Git fork
1#include "git-compat-util.h"
2
3#ifdef OPEN_RETURNS_EINTR
4#undef open
5int git_open_with_retry(const char *path, int flags, ...)
6{
7 mode_t mode = 0;
8 int ret;
9
10 /*
11 * Also O_TMPFILE would take a mode, but it isn't defined everywhere.
12 * And anyway, we don't use it in our code base.
13 */
14 if (flags & O_CREAT) {
15 va_list ap;
16 va_start(ap, flags);
17 mode = va_arg(ap, int);
18 va_end(ap);
19 }
20
21 do {
22 ret = open(path, flags, mode);
23 } while (ret < 0 && errno == EINTR);
24
25 return ret;
26}
27#endif
28
29int git_open_cloexec(const char *name, int flags)
30{
31 int fd;
32 static int o_cloexec = O_CLOEXEC;
33
34 fd = open(name, flags | o_cloexec);
35 if ((o_cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
36 /* Try again w/o O_CLOEXEC: the kernel might not support it */
37 o_cloexec &= ~O_CLOEXEC;
38 fd = open(name, flags | o_cloexec);
39 }
40
41#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
42 {
43 static int fd_cloexec = FD_CLOEXEC;
44
45 if (!o_cloexec && 0 <= fd && fd_cloexec) {
46 /* Opened w/o O_CLOEXEC? try with fcntl(2) to add it */
47 int flags = fcntl(fd, F_GETFD);
48 if (fcntl(fd, F_SETFD, flags | fd_cloexec))
49 fd_cloexec = 0;
50 }
51 }
52#endif
53 return fd;
54}