util: introduce os_dupfd_cloexec() helper

Adapted from wayland's wl_os_dupfd_cloexec().

Suggested-by: Kristian H. Kristensen <hoegsberg@google.com>
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5369>
This commit is contained in:
Eric Engestrom
2020-06-05 01:08:33 +02:00
committed by Marge Bot
parent b00e1d9ea7
commit 0e5ea7a363
2 changed files with 55 additions and 0 deletions

View File

@@ -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>

View File

@@ -24,6 +24,12 @@ extern "C" {
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.