2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/Conv.h>
20 #include <folly/Portability.h>
21 #include <folly/ScopeGuard.h>
22 #include <folly/portability/Fcntl.h>
23 #include <folly/portability/SysUio.h>
24 #include <folly/portability/Unistd.h>
29 #include <sys/types.h>
34 * Convenience wrappers around some commonly used system calls. The *NoInt
35 * wrappers retry on EINTR. The *Full wrappers retry on EINTR and also loop
36 * until all data is written. Note that *Full wrappers weaken the thread
37 * semantics of underlying system calls.
39 int openNoInt(const char* name, int flags, mode_t mode = 0666);
40 int closeNoInt(int fd);
42 int dup2NoInt(int oldfd, int newfd);
43 int fsyncNoInt(int fd);
44 int fdatasyncNoInt(int fd);
45 int ftruncateNoInt(int fd, off_t len);
46 int truncateNoInt(const char* path, off_t len);
47 int flockNoInt(int fd, int operation);
48 int shutdownNoInt(int fd, int how);
50 ssize_t readNoInt(int fd, void* buf, size_t n);
51 ssize_t preadNoInt(int fd, void* buf, size_t n, off_t offset);
52 ssize_t readvNoInt(int fd, const iovec* iov, int count);
54 ssize_t writeNoInt(int fd, const void* buf, size_t n);
55 ssize_t pwriteNoInt(int fd, const void* buf, size_t n, off_t offset);
56 ssize_t writevNoInt(int fd, const iovec* iov, int count);
59 * Wrapper around read() (and pread()) that, in addition to retrying on
60 * EINTR, will loop until all data is read.
62 * This wrapper is only useful for blocking file descriptors (for non-blocking
63 * file descriptors, you have to be prepared to deal with incomplete reads
64 * anyway), and only exists because POSIX allows read() to return an incomplete
65 * read if interrupted by a signal (instead of returning -1 and setting errno
68 * Note that this wrapper weakens the thread safety of read(): the file pointer
69 * is shared between threads, but the system call is atomic. If multiple
70 * threads are reading from a file at the same time, you don't know where your
71 * data came from in the file, but you do know that the returned bytes were
72 * contiguous. You can no longer make this assumption if using readFull().
73 * You should probably use pread() when reading from the same file descriptor
74 * from multiple threads simultaneously, anyway.
76 * Note that readvFull and preadvFull require iov to be non-const, unlike
77 * readv and preadv. The contents of iov after these functions return
80 ssize_t readFull(int fd, void* buf, size_t n);
81 ssize_t preadFull(int fd, void* buf, size_t n, off_t offset);
82 ssize_t readvFull(int fd, iovec* iov, int count);
83 ssize_t preadvFull(int fd, iovec* iov, int count, off_t offset);
86 * Similar to readFull and preadFull above, wrappers around write() and
87 * pwrite() that loop until all data is written.
89 * Generally, the write() / pwrite() system call may always write fewer bytes
90 * than requested, just like read(). In certain cases (such as when writing to
91 * a pipe), POSIX provides stronger guarantees, but not in the general case.
92 * For example, Linux (even on a 64-bit platform) won't write more than 2GB in
93 * one write() system call.
95 * Note that writevFull and pwritevFull require iov to be non-const, unlike
96 * writev and pwritev. The contents of iov after these functions return
99 * These functions return -1 on error, or the total number of bytes written
100 * (which is always the same as the number of requested bytes) on success.
102 ssize_t writeFull(int fd, const void* buf, size_t n);
103 ssize_t pwriteFull(int fd, const void* buf, size_t n, off_t offset);
104 ssize_t writevFull(int fd, iovec* iov, int count);
105 ssize_t pwritevFull(int fd, iovec* iov, int count, off_t offset);
108 * Read entire file (if num_bytes is defaulted) or no more than
109 * num_bytes (otherwise) into container *out. The container is assumed
110 * to be contiguous, with element size equal to 1, and offer size(),
111 * reserve(), and random access (e.g. std::vector<char>, std::string,
114 * Returns: true on success or false on failure. In the latter case
115 * errno will be set appropriately by the failing system primitive.
117 template <class Container>
121 size_t num_bytes = std::numeric_limits<size_t>::max()) {
122 static_assert(sizeof(out[0]) == 1,
123 "readFile: only containers with byte-sized elements accepted");
125 size_t soFar = 0; // amount of bytes successfully read
127 DCHECK(out.size() >= soFar); // resize better doesn't throw
133 if (fstat(fd, &buf) == -1) return false;
134 // Some files (notably under /proc and /sys on Linux) lie about
135 // their size, so treat the size advertised by fstat under advise
136 // but don't rely on it. In particular, if the size is zero, we
137 // should attempt to read stuff. If not zero, we'll attempt to read
139 constexpr size_t initialAlloc = 1024 * 4;
142 buf.st_size > 0 ? folly::to<size_t>(buf.st_size + 1) : initialAlloc,
145 while (soFar < out.size()) {
146 const auto actual = readFull(fd, &out[soFar], out.size() - soFar);
151 if (soFar < out.size()) {
155 // Ew, allocate more memory. Use exponential growth to avoid
156 // quadratic behavior. Cap size to num_bytes.
157 out.resize(std::min(out.size() * 3 / 2, num_bytes));
164 * Same as above, but takes in a file name instead of fd
166 template <class Container>
168 const char* file_name,
170 size_t num_bytes = std::numeric_limits<size_t>::max()) {
173 const auto fd = openNoInt(file_name, O_RDONLY);
179 // Ignore errors when closing the file
183 return readFile(fd, out, num_bytes);
187 * Writes container to file. The container is assumed to be
188 * contiguous, with element size equal to 1, and offering STL-like
189 * methods empty(), size(), and indexed access
190 * (e.g. std::vector<char>, std::string, fbstring, StringPiece).
192 * "flags" dictates the open flags to use. Default is to create file
193 * if it doesn't exist and truncate it.
195 * Returns: true on success or false on failure. In the latter case
196 * errno will be set appropriately by the failing system primitive.
198 * Note that this function may leave the file in a partially written state on
199 * failure. Use writeFileAtomic() if you want to ensure that the existing file
200 * state will be unchanged on error.
202 template <class Container>
203 bool writeFile(const Container& data, const char* filename,
204 int flags = O_WRONLY | O_CREAT | O_TRUNC) {
205 static_assert(sizeof(data[0]) == 1,
206 "writeFile works with element size equal to 1");
207 int fd = open(filename, flags, 0666);
211 bool ok = data.empty() ||
212 writeFull(fd, &data[0], data.size()) == static_cast<ssize_t>(data.size());
213 return closeNoInt(fd) == 0 && ok;
217 * Write file contents "atomically".
219 * This writes the data to a temporary file in the destination directory, and
220 * then renames it to the specified path. This guarantees that the specified
221 * file will be replaced the the specified contents on success, or will not be
222 * modified on failure.
224 * Note that on platforms that do not provide atomic filesystem rename
225 * functionality (e.g., Windows) this behavior may not be truly atomic.
227 void writeFileAtomic(
228 StringPiece filename,
231 mode_t permissions = 0644);
232 void writeFileAtomic(
233 StringPiece filename,
235 mode_t permissions = 0644);
236 void writeFileAtomic(
237 StringPiece filename,
239 mode_t permissions = 0644);
242 * A version of writeFileAtomic() that returns an errno value instead of
245 * Returns 0 on success or an errno value on error.
247 int writeFileAtomicNoThrow(
248 StringPiece filename,
251 mode_t permissions = 0644);