X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FFileUtil.cpp;h=d31e8ff945f78b0883b841277e70243f5804ac6e;hb=5b8add09a804f52169f96db1ee73e33acf8a56ae;hp=8a07bf768e262d17c66e84f7c432c3bf411d9666;hpb=d1028d196481191a6e3adf1b081f736b89c52cfa;p=folly.git diff --git a/folly/FileUtil.cpp b/folly/FileUtil.cpp index 8a07bf76..d31e8ff9 100644 --- a/folly/FileUtil.cpp +++ b/folly/FileUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,23 @@ * limitations under the License. */ -#include "folly/FileUtil.h" +#include #include +#include +#include +#include +#include + namespace folly { +using namespace fileutil_detail; + +int openNoInt(const char* name, int flags, mode_t mode) { + return wrapNoInt(open, name, flags, mode); +} + int closeNoInt(int fd) { int r = close(fd); // Ignore EINTR. On Linux, close() may only return EINTR after the file @@ -30,26 +41,50 @@ int closeNoInt(int fd) { // Interestingly enough, the Single Unix Specification says that the state // of the file descriptor is unspecified if close returns EINTR. In that // case, the safe thing to do is also not to retry close() -- leaking a file - // descriptor is probably better than closing the wrong file. + // descriptor is definitely better than closing the wrong file. if (r == -1 && errno == EINTR) { r = 0; } return r; } -namespace { +int fsyncNoInt(int fd) { + return wrapNoInt(fsync, fd); +} -// Wrap call to f(args) in loop to retry on EINTR -template -ssize_t wrapNoInt(F f, Args... args) { - ssize_t r; - do { - r = f(args...); - } while (r == -1 && errno == EINTR); - return r; +int dupNoInt(int fd) { + return wrapNoInt(dup, fd); +} + +int dup2NoInt(int oldfd, int newfd) { + return wrapNoInt(dup2, oldfd, newfd); +} + +int fdatasyncNoInt(int fd) { +#if defined(__APPLE__) + return wrapNoInt(fcntl, fd, F_FULLFSYNC); +#elif defined(__FreeBSD__) || defined(_MSC_VER) + return wrapNoInt(fsync, fd); +#else + return wrapNoInt(fdatasync, fd); +#endif } -} // namespace +int ftruncateNoInt(int fd, off_t len) { + return wrapNoInt(ftruncate, fd, len); +} + +int truncateNoInt(const char* path, off_t len) { + return wrapNoInt(truncate, path, len); +} + +int flockNoInt(int fd, int operation) { + return wrapNoInt(flock, fd, operation); +} + +int shutdownNoInt(int fd, int how) { + return wrapNoInt(portability::sockets::shutdown, fd, how); +} ssize_t readNoInt(int fd, void* buf, size_t count) { return wrapNoInt(read, fd, buf, count); @@ -59,8 +94,8 @@ ssize_t preadNoInt(int fd, void* buf, size_t count, off_t offset) { return wrapNoInt(pread, fd, buf, count, offset); } -ssize_t readvNoInt(int fd, const struct iovec* iov, int count) { - return wrapNoInt(writev, fd, iov, count); +ssize_t readvNoInt(int fd, const iovec* iov, int count) { + return wrapNoInt(readv, fd, iov, count); } ssize_t writeNoInt(int fd, const void* buf, size_t count) { @@ -71,95 +106,40 @@ ssize_t pwriteNoInt(int fd, const void* buf, size_t count, off_t offset) { return wrapNoInt(pwrite, fd, buf, count, offset); } -ssize_t writevNoInt(int fd, const struct iovec* iov, int count) { +ssize_t writevNoInt(int fd, const iovec* iov, int count) { return wrapNoInt(writev, fd, iov, count); } ssize_t readFull(int fd, void* buf, size_t count) { - char* b = static_cast(buf); - ssize_t totalBytes = 0; - ssize_t r; - do { - r = read(fd, b, count); - if (r == -1) { - if (errno == EINTR) { - continue; - } - return r; - } - - totalBytes += r; - b += r; - count -= r; - } while (r != 0 && count); // 0 means EOF - - return totalBytes; + return wrapFull(read, fd, buf, count); } ssize_t preadFull(int fd, void* buf, size_t count, off_t offset) { - char* b = static_cast(buf); - ssize_t totalBytes = 0; - ssize_t r; - do { - r = pread(fd, b, count, offset); - if (r == -1) { - if (errno == EINTR) { - continue; - } - return r; - } - - totalBytes += r; - b += r; - offset += r; - count -= r; - } while (r != 0 && count); // 0 means EOF - - return totalBytes; + return wrapFull(pread, fd, buf, count, offset); } ssize_t writeFull(int fd, const void* buf, size_t count) { - const char* b = static_cast(buf); - ssize_t totalBytes = 0; - ssize_t r; - do { - r = write(fd, b, count); - if (r == -1) { - if (errno == EINTR) { - continue; - } - return r; - } - - totalBytes += r; - b += r; - count -= r; - } while (r != 0 && count); // 0 means EOF - - return totalBytes; + return wrapFull(write, fd, const_cast(buf), count); } ssize_t pwriteFull(int fd, const void* buf, size_t count, off_t offset) { - const char* b = static_cast(buf); - ssize_t totalBytes = 0; - ssize_t r; - do { - r = pwrite(fd, b, count, offset); - if (r == -1) { - if (errno == EINTR) { - continue; - } - return r; - } - - totalBytes += r; - b += r; - offset += r; - count -= r; - } while (r != 0 && count); // 0 means EOF - - return totalBytes; + return wrapFull(pwrite, fd, const_cast(buf), count, offset); } -} // namespaces +ssize_t readvFull(int fd, iovec* iov, int count) { + return wrapvFull(readv, fd, iov, count); +} +ssize_t preadvFull(int fd, iovec* iov, int count, off_t offset) { + return wrapvFull(preadv, fd, iov, count, offset); +} + +ssize_t writevFull(int fd, iovec* iov, int count) { + return wrapvFull(writev, fd, iov, count); +} + +ssize_t pwritevFull(int fd, iovec* iov, int count, off_t offset) { + return wrapvFull(pwritev, fd, iov, count, offset); +} + +} // namespaces