2 * Copyright 2019 Intel Corporation
3 * SPDX-License-Identifier: MIT
17 #define fdopen _fdopen
18 #define O_CREAT _O_CREAT
19 #define O_EXCL _O_EXCL
20 #define O_WRONLY _O_WRONLY
23 #ifndef F_DUPFD_CLOEXEC
24 #define F_DUPFD_CLOEXEC 1030
30 os_file_create_unique(const char *filename
, int filemode
)
32 int fd
= open(filename
, O_CREAT
| O_EXCL
| O_WRONLY
, filemode
);
35 return fdopen(fd
, "w");
41 os_dupfd_cloexec(int fd
)
44 * On Windows child processes don't inherit handles by default:
45 * https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873
51 os_dupfd_cloexec(int fd
)
54 int newfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, minfd
);
62 newfd
= fcntl(fd
, F_DUPFD
, minfd
);
67 long flags
= fcntl(newfd
, F_GETFD
);
73 if (fcntl(newfd
, F_SETFD
, flags
| FD_CLOEXEC
) == -1) {
87 #include <sys/syscall.h>
90 /* copied from <linux/kcmp.h> */
94 readN(int fd
, char *buf
, size_t len
)
99 ssize_t ret
= read(fd
, buf
+ total
, len
- total
);
104 if (ret
== -EINTR
|| ret
== -EAGAIN
)
113 } while (total
!= len
);
115 return total
? (ssize_t
)total
: err
;
119 os_read_file(const char *filename
, size_t *size
)
121 /* Note that this also serves as a slight margin to avoid a 2x grow when
122 * the file is just a few bytes larger when we read it than when we
124 * The string's NULL terminator is also included in here.
128 int fd
= open(filename
, O_RDONLY
);
130 /* errno set by open() */
134 /* Pre-allocate a buffer at least the size of the file if we can read
138 if (fstat(fd
, &stat
) == 0)
141 char *buf
= malloc(len
);
148 ssize_t actually_read
;
149 size_t offset
= 0, remaining
= len
- 1;
150 while ((actually_read
= readN(fd
, buf
+ offset
, remaining
)) == (ssize_t
)remaining
) {
151 char *newbuf
= realloc(buf
, 2 * len
);
161 offset
+= actually_read
;
162 remaining
= len
- offset
- 1;
167 if (actually_read
> 0)
168 offset
+= actually_read
;
170 /* Final resize to actual size */
172 char *newbuf
= realloc(buf
, len
);
189 os_same_file_description(int fd1
, int fd2
)
191 pid_t pid
= getpid();
193 /* Same file descriptor trivially implies same file description */
197 return syscall(SYS_kcmp
, pid
, pid
, KCMP_FILE
, fd1
, fd2
);
205 os_read_file(const char *filename
, size_t *size
)
212 os_same_file_description(int fd1
, int fd2
)
214 /* Same file descriptor trivially implies same file description */
218 /* Otherwise we can't tell */