|
16 | 16 | #include <sys/stat.h> |
17 | 17 | #include <errno.h> |
18 | 18 | #include <limits.h> |
| 19 | + #include <fcntl.h> |
19 | 20 | typedef int FFNativeFD; |
20 | 21 | #define FF_INVALID_FD (-1) |
21 | 22 | // procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime. |
22 | 23 | // one safe way to read correct data is reading the whole file in a single read syscall |
23 | 24 | #define PROC_FILE_BUFFSIZ (32 * 1024) |
24 | 25 | #endif |
25 | 26 |
|
| 27 | +#ifdef _WIN32 |
| 28 | + #ifndef O_CLOEXEC |
| 29 | + #define O_CLOEXEC 0 |
| 30 | + #endif |
| 31 | + #ifndef O_RDONLY |
| 32 | + #define O_RDONLY 0 |
| 33 | + #endif |
| 34 | + #ifndef O_DIRECTORY |
| 35 | + #define O_DIRECTORY 0200000 |
| 36 | + #endif |
| 37 | + |
| 38 | +// Only O_RDONLY is supported |
| 39 | +HANDLE openat(HANDLE dfd, const char* fileName, int oflag); |
| 40 | +HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory); |
| 41 | +#endif |
| 42 | + |
| 43 | + |
| 44 | +static inline bool ffIsValidNativeFD(FFNativeFD fd) |
| 45 | +{ |
| 46 | + #ifndef _WIN32 |
| 47 | + return fd >= 0; |
| 48 | + #else |
| 49 | + // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 |
| 50 | + return fd != INVALID_HANDLE_VALUE && fd != NULL; |
| 51 | + #endif |
| 52 | +} |
| 53 | + |
| 54 | +FF_C_NONNULL(1) |
| 55 | +static inline bool wrapClose(FFNativeFD* pfd) |
| 56 | +{ |
| 57 | + assert(pfd); |
| 58 | + |
| 59 | + if (!ffIsValidNativeFD(*pfd)) |
| 60 | + return false; |
| 61 | + |
| 62 | + #ifndef _WIN32 |
| 63 | + close(*pfd); |
| 64 | + #else |
| 65 | + NtClose(*pfd); |
| 66 | + #endif |
| 67 | + |
| 68 | + return true; |
| 69 | +} |
| 70 | +#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose))) |
| 71 | + |
26 | 72 | static inline FFNativeFD FFUnixFD2NativeFD(int unixfd) |
27 | 73 | { |
28 | 74 | #ifndef _WIN32 |
@@ -72,17 +118,60 @@ static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data) |
72 | 118 | #endif |
73 | 119 | } |
74 | 120 |
|
| 121 | +FF_C_NONNULL(2) |
| 122 | +bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer); |
| 123 | + |
75 | 124 | FF_C_NONNULL(1, 3) |
76 | | -ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data); |
| 125 | +static inline ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) |
| 126 | +{ |
| 127 | + FFNativeFD FF_AUTO_CLOSE_FD fd = |
| 128 | + #ifndef _WIN32 |
| 129 | + open(fileName, O_RDONLY | O_CLOEXEC); |
| 130 | + #else |
| 131 | + CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
| 132 | + #endif |
| 133 | + |
| 134 | + if (!ffIsValidNativeFD(fd)) |
| 135 | + return -1; |
| 136 | + |
| 137 | + return ffReadFDData(fd, dataSize, data); |
| 138 | +} |
| 139 | + |
77 | 140 | FF_C_NONNULL(2, 4) |
78 | | -ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data); |
| 141 | +static inline ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data) |
| 142 | +{ |
| 143 | + FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); |
| 144 | + if (!ffIsValidNativeFD(fd)) |
| 145 | + return -1; |
| 146 | + |
| 147 | + return ffReadFDData(fd, dataSize, data); |
| 148 | +} |
79 | 149 |
|
80 | | -FF_C_NONNULL(2) |
81 | | -bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer); |
82 | 150 | FF_C_NONNULL(1, 2) |
83 | | -bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer); |
| 151 | +static inline bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) |
| 152 | +{ |
| 153 | + FFNativeFD FF_AUTO_CLOSE_FD fd = |
| 154 | + #ifndef _WIN32 |
| 155 | + open(fileName, O_RDONLY | O_CLOEXEC); |
| 156 | + #else |
| 157 | + CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
| 158 | + #endif |
| 159 | + |
| 160 | + if (!ffIsValidNativeFD(fd)) |
| 161 | + return false; |
| 162 | + |
| 163 | + return ffAppendFDBuffer(fd, buffer); |
| 164 | +} |
| 165 | + |
84 | 166 | FF_C_NONNULL(2, 3) |
85 | | -bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer); |
| 167 | +static inline bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer) |
| 168 | +{ |
| 169 | + FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); |
| 170 | + if (!ffIsValidNativeFD(fd)) |
| 171 | + return false; |
| 172 | + |
| 173 | + return ffAppendFDBuffer(fd, buffer); |
| 174 | +} |
86 | 175 |
|
87 | 176 | FF_C_NONNULL(2) |
88 | 177 | static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer) |
@@ -183,34 +272,6 @@ static inline void ffUnsuppressIO(bool* suppressed) |
183 | 272 |
|
184 | 273 | void ffListFilesRecursively(const char* path, bool pretty); |
185 | 274 |
|
186 | | -static inline bool ffIsValidNativeFD(FFNativeFD fd) |
187 | | -{ |
188 | | - #ifndef _WIN32 |
189 | | - return fd >= 0; |
190 | | - #else |
191 | | - // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 |
192 | | - return fd != INVALID_HANDLE_VALUE && fd != NULL; |
193 | | - #endif |
194 | | -} |
195 | | - |
196 | | -FF_C_NONNULL(1) |
197 | | -static inline bool wrapClose(FFNativeFD* pfd) |
198 | | -{ |
199 | | - assert(pfd); |
200 | | - |
201 | | - if (!ffIsValidNativeFD(*pfd)) |
202 | | - return false; |
203 | | - |
204 | | - #ifndef _WIN32 |
205 | | - close(*pfd); |
206 | | - #else |
207 | | - NtClose(*pfd); |
208 | | - #endif |
209 | | - |
210 | | - return true; |
211 | | -} |
212 | | -#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose))) |
213 | | - |
214 | 275 | FF_C_NONNULL(1) |
215 | 276 | static inline bool wrapFclose(FILE** pfile) |
216 | 277 | { |
@@ -262,9 +323,3 @@ static inline bool ffSearchUserConfigFile(const FFlist* configDirs, const char* |
262 | 323 |
|
263 | 324 | FFNativeFD ffGetNullFD(void); |
264 | 325 | bool ffRemoveFile(const char* fileName); |
265 | | - |
266 | | -#ifdef _WIN32 |
267 | | -// Only O_RDONLY is supported |
268 | | -HANDLE openat(HANDLE dfd, const char* fileName, bool directory); |
269 | | -HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory); |
270 | | -#endif |
|
0 commit comments