X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fos_file.c;h=c5970ddb2431b058334dd6b97b0b142e2bb724ff;hb=04ed3522c9093472461cad78380d5d66ac8a2519;hp=756164c3dfef670f2693cc63c8c70a7d3a4b3aae;hpb=955c63d3643f30d7db0c5d16e06a5eda4f62f889;p=mesa.git diff --git a/src/util/os_file.c b/src/util/os_file.c index 756164c3dfe..c5970ddb243 100644 --- a/src/util/os_file.c +++ b/src/util/os_file.c @@ -4,16 +4,91 @@ */ #include "os_file.h" +#include "detect_os.h" #include +#include #include +#include + +#if DETECT_OS_WINDOWS +#include +#define open _open +#define fdopen _fdopen +#define O_CREAT _O_CREAT +#define O_EXCL _O_EXCL +#define O_WRONLY _O_WRONLY +#else +#include +#ifndef F_DUPFD_CLOEXEC +#define F_DUPFD_CLOEXEC 1030 +#endif +#endif + + +FILE * +os_file_create_unique(const char *filename, int filemode) +{ + int fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, filemode); + if (fd == -1) + return NULL; + return fdopen(fd, "w"); +} + + +#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 defined(__linux__) + 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 #include +#include #include +/* copied from */ +#define KCMP_FILE 0 static ssize_t readN(int fd, char *buf, size_t len) @@ -41,7 +116,7 @@ readN(int fd, char *buf, size_t len) } char * -os_read_file(const char *filename) +os_read_file(const char *filename, size_t *size) { /* Note that this also serves as a slight margin to avoid a 2x grow when * the file is just a few bytes larger when we read it than when we @@ -97,7 +172,6 @@ os_read_file(const char *filename) char *newbuf = realloc(buf, len); if (!newbuf) { free(buf); - close(fd); errno = -ENOMEM; return NULL; } @@ -105,16 +179,44 @@ os_read_file(const char *filename) buf[offset] = '\0'; + if (size) + *size = offset; + return buf; } +int +os_same_file_description(int fd1, int fd2) +{ + pid_t pid = getpid(); + + /* Same file descriptor trivially implies same file description */ + if (fd1 == fd2) + return 0; + + return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2); +} + #else +#include "u_debug.h" + char * -os_read_file(const char *filename) +os_read_file(const char *filename, size_t *size) { errno = -ENOSYS; return NULL; } +int +os_same_file_description(int fd1, int fd2) +{ + /* Same file descriptor trivially implies same file description */ + if (fd1 == fd2) + return 0; + + /* Otherwise we can't tell */ + return -1; +} + #endif