#include "git-compat-util.h" #ifdef OPEN_RETURNS_EINTR #undef open int git_open_with_retry(const char *path, int flags, ...) { mode_t mode = 0; int ret; /* * Also O_TMPFILE would take a mode, but it isn't defined everywhere. * And anyway, we don't use it in our code base. */ if (flags & O_CREAT) { va_list ap; va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); } do { ret = open(path, flags, mode); } while (ret < 0 && errno == EINTR); return ret; } #endif int git_open_cloexec(const char *name, int flags) { int fd; static int o_cloexec = O_CLOEXEC; fd = open(name, flags | o_cloexec); if ((o_cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) { /* Try again w/o O_CLOEXEC: the kernel might not support it */ o_cloexec &= ~O_CLOEXEC; fd = open(name, flags | o_cloexec); } #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) { static int fd_cloexec = FD_CLOEXEC; if (!o_cloexec && 0 <= fd && fd_cloexec) { /* Opened w/o O_CLOEXEC? try with fcntl(2) to add it */ int flags = fcntl(fd, F_GETFD); if (fcntl(fd, F_SETFD, flags | fd_cloexec)) fd_cloexec = 0; } } #endif return fd; }