diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/util/os_file.c | 49 | ||||
-rw-r--r-- | src/util/os_file.h | 6 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/util/os_file.c b/src/util/os_file.c index f02d74afd2c..c5970ddb243 100644 --- a/src/util/os_file.c +++ b/src/util/os_file.c @@ -18,6 +18,11 @@ #define O_CREAT _O_CREAT #define O_EXCL _O_EXCL #define O_WRONLY _O_WRONLY +#else +#include <unistd.h> +#ifndef F_DUPFD_CLOEXEC +#define F_DUPFD_CLOEXEC 1030 +#endif #endif @@ -31,6 +36,50 @@ os_file_create_unique(const char *filename, int filemode) } +#if DETECT_OS_WINDOWS +int +os_dupfd_cloexec(int fd) +{ + /* + * On Windows child processes don't inherit handles by default: + * https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873 + */ + return dup(fd); +} +#else +int +os_dupfd_cloexec(int fd) +{ + int minfd = 3; + int newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd); + + if (newfd >= 0) + return newfd; + + if (errno != EINVAL) + return -1; + + newfd = fcntl(fd, F_DUPFD, minfd); + + if (newfd < 0) + return -1; + + long flags = fcntl(newfd, F_GETFD); + if (flags == -1) { + close(newfd); + return -1; + } + + if (fcntl(newfd, F_SETFD, flags | FD_CLOEXEC) == -1) { + close(newfd); + return -1; + } + + return newfd; +} +#endif + + #if DETECT_OS_LINUX #include <fcntl.h> diff --git a/src/util/os_file.h b/src/util/os_file.h index 36f367ea358..cf0dc207595 100644 --- a/src/util/os_file.h +++ b/src/util/os_file.h @@ -25,6 +25,12 @@ FILE * os_file_create_unique(const char *filename, int filemode); /* + * Duplicate a file descriptor, making sure not to keep it open after an exec*() + */ +int +os_dupfd_cloexec(int fd); + +/* * Read a file. * Returns a char* that the caller must free(), or NULL and sets errno. * If size is not null and no error occured it's set to the size of the |