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