From 8fdaa987e3b92300b6dc033c876ac29870c5d370 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 25 Mar 2026 10:41:10 +0800 Subject: [PATCH] IO: inlines more helper functions --- src/common/impl/io_unix.c | 36 --------- src/common/impl/io_windows.c | 40 +--------- src/common/io.h | 137 ++++++++++++++++++++++++----------- 3 files changed, 98 insertions(+), 115 deletions(-) diff --git a/src/common/impl/io_unix.c b/src/common/impl/io_unix.c index 31fefe91d..12c07d716 100644 --- a/src/common/impl/io_unix.c +++ b/src/common/impl/io_unix.c @@ -97,42 +97,6 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer) return buffer->length > 0; } -ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) -{ - int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC); - if(fd == -1) - return -1; - - return ffReadFDData(fd, dataSize, data); -} - -ssize_t ffReadFileDataRelative(int dfd, const char* fileName, size_t dataSize, void* data) -{ - int FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); - if(fd == -1) - return -1; - - return ffReadFDData(fd, dataSize, data); -} - -bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) -{ - int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC); - if(fd == -1) - return false; - - return ffAppendFDBuffer(fd, buffer); -} - -bool ffAppendFileBufferRelative(int dfd, const char* fileName, FFstrbuf* buffer) -{ - int FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); - if(fd == -1) - return false; - - return ffAppendFDBuffer(fd, buffer); -} - bool ffPathExpandEnv(const char* in, FFstrbuf* out) { bool result = false; diff --git a/src/common/impl/io_windows.c b/src/common/impl/io_windows.c index cf9c67ca0..c8ecda42c 100644 --- a/src/common/impl/io_windows.c +++ b/src/common/impl/io_windows.c @@ -225,24 +225,6 @@ bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer) return buffer->length > 0; } -ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) -{ - HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(handle == INVALID_HANDLE_VALUE) - return -1; - - return ffReadFDData(handle, dataSize, data); -} - -bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) -{ - HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(handle == INVALID_HANDLE_VALUE) - return false; - - return ffAppendFDBuffer(handle, buffer); -} - HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory) { assert(fileNameLen <= 0x7FFF); @@ -269,7 +251,7 @@ HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool d return hFile; } -HANDLE openat(HANDLE dfd, const char* fileName, bool directory) +HANDLE openat(HANDLE dfd, const char* fileName, int oflag) { wchar_t fileNameW[MAX_PATH]; ULONG len; @@ -284,25 +266,7 @@ HANDLE openat(HANDLE dfd, const char* fileName, bool directory) fileNameW[i] = L'\\'; } - return openatW(dfd, fileNameW, (uint16_t)(len - 1), directory); -} - -bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer) -{ - HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false); - if(fd == INVALID_HANDLE_VALUE) - return false; - - return ffAppendFDBuffer(fd, buffer); -} - -ssize_t ffReadFileDataRelative(HANDLE dfd, const char* fileName, size_t dataSize, void* data) -{ - HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false); - if(fd == INVALID_HANDLE_VALUE) - return -1; - - return ffReadFDData(fd, dataSize, data); + return openatW(dfd, fileNameW, (uint16_t)(len - 1), !!(oflag & O_DIRECTORY)); } bool ffPathExpandEnv(const char* in, FFstrbuf* out) diff --git a/src/common/io.h b/src/common/io.h index efbabc37c..2d2851f00 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -16,6 +16,7 @@ #include #include #include + #include typedef int FFNativeFD; #define FF_INVALID_FD (-1) // procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime. @@ -23,6 +24,51 @@ #define PROC_FILE_BUFFSIZ (32 * 1024) #endif +#ifdef _WIN32 + #ifndef O_CLOEXEC + #define O_CLOEXEC 0 + #endif + #ifndef O_RDONLY + #define O_RDONLY 0 + #endif + #ifndef O_DIRECTORY + #define O_DIRECTORY 0200000 + #endif + +// Only O_RDONLY is supported +HANDLE openat(HANDLE dfd, const char* fileName, int oflag); +HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory); +#endif + + +static inline bool ffIsValidNativeFD(FFNativeFD fd) +{ + #ifndef _WIN32 + return fd >= 0; + #else + // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 + return fd != INVALID_HANDLE_VALUE && fd != NULL; + #endif +} + +FF_C_NONNULL(1) +static inline bool wrapClose(FFNativeFD* pfd) +{ + assert(pfd); + + if (!ffIsValidNativeFD(*pfd)) + return false; + + #ifndef _WIN32 + close(*pfd); + #else + NtClose(*pfd); + #endif + + return true; +} +#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose))) + static inline FFNativeFD FFUnixFD2NativeFD(int unixfd) { #ifndef _WIN32 @@ -72,17 +118,60 @@ static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data) #endif } -FF_C_NONNULL(1, 3) -ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data); -FF_C_NONNULL(2, 4) -ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data); - FF_C_NONNULL(2) bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer); + +FF_C_NONNULL(1, 3) +static inline ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) +{ + FFNativeFD FF_AUTO_CLOSE_FD fd = + #ifndef _WIN32 + open(fileName, O_RDONLY | O_CLOEXEC); + #else + CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + #endif + + if (!ffIsValidNativeFD(fd)) + return -1; + + return ffReadFDData(fd, dataSize, data); +} + +FF_C_NONNULL(2, 4) +static inline ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data) +{ + FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); + if (!ffIsValidNativeFD(fd)) + return -1; + + return ffReadFDData(fd, dataSize, data); +} + FF_C_NONNULL(1, 2) -bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer); +static inline bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) +{ + FFNativeFD FF_AUTO_CLOSE_FD fd = + #ifndef _WIN32 + open(fileName, O_RDONLY | O_CLOEXEC); + #else + CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + #endif + + if (!ffIsValidNativeFD(fd)) + return false; + + return ffAppendFDBuffer(fd, buffer); +} + FF_C_NONNULL(2, 3) -bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer); +static inline bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer) +{ + FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC); + if (!ffIsValidNativeFD(fd)) + return false; + + return ffAppendFDBuffer(fd, buffer); +} FF_C_NONNULL(2) static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer) @@ -183,34 +272,6 @@ static inline void ffUnsuppressIO(bool* suppressed) void ffListFilesRecursively(const char* path, bool pretty); -static inline bool ffIsValidNativeFD(FFNativeFD fd) -{ - #ifndef _WIN32 - return fd >= 0; - #else - // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 - return fd != INVALID_HANDLE_VALUE && fd != NULL; - #endif -} - -FF_C_NONNULL(1) -static inline bool wrapClose(FFNativeFD* pfd) -{ - assert(pfd); - - if (!ffIsValidNativeFD(*pfd)) - return false; - - #ifndef _WIN32 - close(*pfd); - #else - NtClose(*pfd); - #endif - - return true; -} -#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose))) - FF_C_NONNULL(1) static inline bool wrapFclose(FILE** pfile) { @@ -262,9 +323,3 @@ static inline bool ffSearchUserConfigFile(const FFlist* configDirs, const char* FFNativeFD ffGetNullFD(void); bool ffRemoveFile(const char* fileName); - -#ifdef _WIN32 -// Only O_RDONLY is supported -HANDLE openat(HANDLE dfd, const char* fileName, bool directory); -HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory); -#endif