File.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #pragma once
  17. #include <fcntl.h>
  18. #include <sys/stat.h>
  19. #include <sys/types.h>
  20. #include <string>
  21. #include <system_error>
  22. #include <folly/ExceptionWrapper.h>
  23. #include <folly/Expected.h>
  24. #include <folly/Portability.h>
  25. #include <folly/Range.h>
  26. #include <folly/portability/Unistd.h>
  27. namespace folly {
  28. /**
  29. * A File represents an open file.
  30. */
  31. class File {
  32. public:
  33. /**
  34. * Creates an empty File object, for late initialization.
  35. */
  36. File() noexcept;
  37. /**
  38. * Create a File object from an existing file descriptor.
  39. * Takes ownership of the file descriptor if ownsFd is true.
  40. */
  41. explicit File(int fd, bool ownsFd = false) noexcept;
  42. /**
  43. * Open and create a file object. Throws on error.
  44. * Owns the file descriptor implicitly.
  45. */
  46. explicit File(const char* name, int flags = O_RDONLY, mode_t mode = 0666);
  47. explicit File(
  48. const std::string& name,
  49. int flags = O_RDONLY,
  50. mode_t mode = 0666);
  51. explicit File(StringPiece name, int flags = O_RDONLY, mode_t mode = 0666);
  52. /**
  53. * All the constructors that are not noexcept can throw std::system_error.
  54. * This is a helper method to use folly::Expected to chain a file open event
  55. * to something else you want to do with the open fd.
  56. */
  57. template <typename... Args>
  58. static Expected<File, exception_wrapper> makeFile(Args&&... args) noexcept {
  59. try {
  60. return File(std::forward<Args>(args)...);
  61. } catch (const std::system_error& se) {
  62. return makeUnexpected(exception_wrapper(std::current_exception(), se));
  63. }
  64. }
  65. ~File();
  66. /**
  67. * Create and return a temporary, owned file (uses tmpfile()).
  68. */
  69. static File temporary();
  70. /**
  71. * Return the file descriptor, or -1 if the file was closed.
  72. */
  73. int fd() const {
  74. return fd_;
  75. }
  76. /**
  77. * Returns 'true' iff the file was successfully opened.
  78. */
  79. explicit operator bool() const {
  80. return fd_ != -1;
  81. }
  82. /**
  83. * Duplicate file descriptor and return File that owns it.
  84. */
  85. File dup() const;
  86. /**
  87. * If we own the file descriptor, close the file and throw on error.
  88. * Otherwise, do nothing.
  89. */
  90. void close();
  91. /**
  92. * Closes the file (if owned). Returns true on success, false (and sets
  93. * errno) on error.
  94. */
  95. bool closeNoThrow();
  96. /**
  97. * Returns and releases the file descriptor; no longer owned by this File.
  98. * Returns -1 if the File object didn't wrap a file.
  99. */
  100. int release() noexcept;
  101. /**
  102. * Swap this File with another.
  103. */
  104. void swap(File& other) noexcept;
  105. // movable
  106. File(File&&) noexcept;
  107. File& operator=(File&&);
  108. // FLOCK (INTERPROCESS) LOCKS
  109. //
  110. // NOTE THAT THESE LOCKS ARE flock() LOCKS. That is, they may only be used
  111. // for inter-process synchronization -- an attempt to acquire a second lock
  112. // on the same file descriptor from the same process may succeed. Attempting
  113. // to acquire a second lock on a different file descriptor for the same file
  114. // should fail, but some systems might implement flock() using fcntl() locks,
  115. // in which case it will succeed.
  116. void lock();
  117. bool try_lock();
  118. void unlock();
  119. void lock_shared();
  120. bool try_lock_shared();
  121. void unlock_shared();
  122. private:
  123. void doLock(int op);
  124. bool doTryLock(int op);
  125. // unique
  126. File(const File&) = delete;
  127. File& operator=(const File&) = delete;
  128. int fd_;
  129. bool ownsFd_;
  130. };
  131. void swap(File& a, File& b) noexcept;
  132. } // namespace folly