X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fos_file.c;h=c5970ddb2431b058334dd6b97b0b142e2bb724ff;hb=HEAD;hp=a700f3aada3088b6f1164fbc78a7e6f9dc886ac2;hpb=93349d71183d4a50ef5ad90b32cb96b9f84d3eec;p=mesa.git diff --git a/src/util/os_file.c b/src/util/os_file.c index a700f3aada3..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 (newfd < 0) + return -1; -#if defined(__linux__) + 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 @@ -92,18 +167,56 @@ os_read_file(const char *filename) if (actually_read > 0) offset += actually_read; + /* Final resize to actual size */ + len = offset + 1; + char *newbuf = realloc(buf, len); + if (!newbuf) { + free(buf); + errno = -ENOMEM; + return NULL; + } + buf = newbuf; + 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