proxygen
FileUtil.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #pragma once
18 
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 
22 #include <cassert>
23 #include <limits>
24 
25 #include <folly/Portability.h>
26 #include <folly/Range.h>
27 #include <folly/ScopeGuard.h>
32 
33 namespace folly {
34 
41 int openNoInt(const char* name, int flags, mode_t mode = 0666);
42 // Two overloads, as we may be closing either a file or a socket.
43 int closeNoInt(int fd);
44 int closeNoInt(NetworkSocket fd);
45 int dupNoInt(int fd);
46 int dup2NoInt(int oldfd, int newfd);
47 int fsyncNoInt(int fd);
48 int fdatasyncNoInt(int fd);
49 int ftruncateNoInt(int fd, off_t len);
50 int truncateNoInt(const char* path, off_t len);
51 int flockNoInt(int fd, int operation);
52 int shutdownNoInt(NetworkSocket fd, int how);
53 inline int shutdownNoInt(int fd, int how) {
54  return shutdownNoInt(NetworkSocket::fromFd(fd), how);
55 }
56 
57 ssize_t readNoInt(int fd, void* buf, size_t n);
58 ssize_t preadNoInt(int fd, void* buf, size_t n, off_t offset);
59 ssize_t readvNoInt(int fd, const iovec* iov, int count);
60 
61 ssize_t writeNoInt(int fd, const void* buf, size_t n);
62 ssize_t pwriteNoInt(int fd, const void* buf, size_t n, off_t offset);
63 ssize_t writevNoInt(int fd, const iovec* iov, int count);
64 
87 FOLLY_NODISCARD ssize_t readFull(int fd, void* buf, size_t n);
88 FOLLY_NODISCARD ssize_t preadFull(int fd, void* buf, size_t n, off_t offset);
89 FOLLY_NODISCARD ssize_t readvFull(int fd, iovec* iov, int count);
90 FOLLY_NODISCARD ssize_t preadvFull(int fd, iovec* iov, int count, off_t offset);
91 
109 ssize_t writeFull(int fd, const void* buf, size_t n);
110 ssize_t pwriteFull(int fd, const void* buf, size_t n, off_t offset);
111 ssize_t writevFull(int fd, iovec* iov, int count);
112 ssize_t pwritevFull(int fd, iovec* iov, int count, off_t offset);
113 
124 template <class Container>
125 bool readFile(
126  int fd,
127  Container& out,
128  size_t num_bytes = std::numeric_limits<size_t>::max()) {
129  static_assert(
130  sizeof(out[0]) == 1,
131  "readFile: only containers with byte-sized elements accepted");
132 
133  size_t soFar = 0; // amount of bytes successfully read
134  SCOPE_EXIT {
135  DCHECK(out.size() >= soFar); // resize better doesn't throw
136  out.resize(soFar);
137  };
138 
139  // Obtain file size:
140  struct stat buf;
141  if (fstat(fd, &buf) == -1) {
142  return false;
143  }
144  // Some files (notably under /proc and /sys on Linux) lie about
145  // their size, so treat the size advertised by fstat under advise
146  // but don't rely on it. In particular, if the size is zero, we
147  // should attempt to read stuff. If not zero, we'll attempt to read
148  // one extra byte.
149  constexpr size_t initialAlloc = 1024 * 4;
150  out.resize(std::min(
151  buf.st_size > 0 ? (size_t(buf.st_size) + 1) : initialAlloc, num_bytes));
152 
153  while (soFar < out.size()) {
154  const auto actual = readFull(fd, &out[soFar], out.size() - soFar);
155  if (actual == -1) {
156  return false;
157  }
158  soFar += actual;
159  if (soFar < out.size()) {
160  // File exhausted
161  break;
162  }
163  // Ew, allocate more memory. Use exponential growth to avoid
164  // quadratic behavior. Cap size to num_bytes.
165  out.resize(std::min(out.size() * 3 / 2, num_bytes));
166  }
167 
168  return true;
169 }
170 
174 template <class Container>
175 bool readFile(
176  const char* file_name,
177  Container& out,
178  size_t num_bytes = std::numeric_limits<size_t>::max()) {
179  DCHECK(file_name);
180 
181  const auto fd = openNoInt(file_name, O_RDONLY | O_CLOEXEC);
182  if (fd == -1) {
183  return false;
184  }
185 
186  SCOPE_EXIT {
187  // Ignore errors when closing the file
188  closeNoInt(fd);
189  };
190 
191  return readFile(fd, out, num_bytes);
192 }
193 
210 template <class Container>
212  const Container& data,
213  const char* filename,
214  int flags = O_WRONLY | O_CREAT | O_TRUNC,
215  mode_t mode = 0666) {
216  static_assert(
217  sizeof(data[0]) == 1, "writeFile works with element size equal to 1");
218  int fd = open(filename, flags, mode);
219  if (fd == -1) {
220  return false;
221  }
222  bool ok = data.empty() ||
223  writeFull(fd, &data[0], data.size()) == static_cast<ssize_t>(data.size());
224  return closeNoInt(fd) == 0 && ok;
225 }
226 
238 void writeFileAtomic(
239  StringPiece filename,
240  iovec* iov,
241  int count,
242  mode_t permissions = 0644);
243 void writeFileAtomic(
244  StringPiece filename,
245  ByteRange data,
246  mode_t permissions = 0644);
247 void writeFileAtomic(
248  StringPiece filename,
249  StringPiece data,
250  mode_t permissions = 0644);
251 
259  StringPiece filename,
260  iovec* iov,
261  int count,
262  mode_t permissions = 0644);
263 
264 } // namespace folly
bool readFile(int fd, Container &out, size_t num_bytes=std::numeric_limits< size_t >::max())
Definition: FileUtil.h:125
flags
Definition: http_parser.h:127
ssize_t readvFull(int fd, iovec *iov, int count)
Definition: FileUtil.cpp:142
int shutdownNoInt(NetworkSocket fd, int how)
Definition: FileUtil.cpp:98
int writeFileAtomicNoThrow(StringPiece filename, iovec *iov, int count, mode_t permissions)
Definition: FileUtil.cpp:158
LogLevel max
Definition: LogLevel.cpp:31
ssize_t preadNoInt(int fd, void *buf, size_t count, off_t offset)
Definition: FileUtil.cpp:106
ssize_t pwriteFull(int fd, const void *buf, size_t count, off_t offset)
Definition: FileUtil.cpp:138
int closeNoInt(int fd)
Definition: FileUtil.cpp:56
#define FOLLY_NODISCARD
Definition: Portability.h:64
int fdatasyncNoInt(int fd)
Definition: FileUtil.cpp:76
ssize_t readNoInt(int fd, void *buf, size_t count)
Definition: FileUtil.cpp:102
ssize_t readFull(int fd, void *buf, size_t count)
Definition: FileUtil.cpp:126
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
int truncateNoInt(const char *path, off_t len)
Definition: FileUtil.cpp:90
ssize_t writevFull(int fd, iovec *iov, int count)
Definition: FileUtil.cpp:150
folly::Optional< PskKeyExchangeMode > mode
ssize_t writevNoInt(int fd, const iovec *iov, int count)
Definition: FileUtil.cpp:122
const char * name
Definition: http_parser.c:437
int fsyncNoInt(int fd)
Definition: FileUtil.cpp:64
LogLevel min
Definition: LogLevel.cpp:30
ssize_t preadFull(int fd, void *buf, size_t count, off_t offset)
Definition: FileUtil.cpp:130
ssize_t readvNoInt(int fd, const iovec *iov, int count)
Definition: FileUtil.cpp:110
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
ssize_t writeNoInt(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:114
int dupNoInt(int fd)
Definition: FileUtil.cpp:68
ssize_t writeFull(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:134
int flockNoInt(int fd, int operation)
Definition: FileUtil.cpp:94
void writeFileAtomic(StringPiece filename, iovec *iov, int count, mode_t permissions)
Definition: FileUtil.cpp:224
int * count
int openNoInt(const char *name, int flags, mode_t mode)
Definition: FileUtil.cpp:36
ssize_t pwriteNoInt(int fd, const void *buf, size_t count, off_t offset)
Definition: FileUtil.cpp:118
bool writeFile(const Container &data, const char *filename, int flags=O_WRONLY|O_CREAT|O_TRUNC, mode_t mode=0666)
Definition: FileUtil.h:211
int dup2NoInt(int oldfd, int newfd)
Definition: FileUtil.cpp:72
int ftruncateNoInt(int fd, off_t len)
Definition: FileUtil.cpp:86
ssize_t pwritevFull(int fd, iovec *iov, int count, off_t offset)
Definition: FileUtil.cpp:154
static NetworkSocket fromFd(int fd)
Definition: NetworkSocket.h:44
ssize_t preadvFull(int fd, iovec *iov, int count, off_t offset)
Definition: FileUtil.cpp:146