/* Open a file with the specified flags (wrapper to open() function). The file descriptor is created non-inheritable. */ int _Py_open(const char *pathname, int flags) { int fd; #ifdef MS_WINDOWS fd = open(pathname, flags | O_NOINHERIT); if (fd < 0) return fd; #else int *atomic_flag_works; #ifdef O_CLOEXEC atomic_flag_works = &_Py_open_cloexec_works; flags |= O_CLOEXEC; #else atomic_flag_works = NULL; #endif fd = open(pathname, flags); if (fd < 0) return fd; if (set_inheritable(fd, 0, 0, atomic_flag_works) < 0) { close(fd); return -1; } #endif /* !MS_WINDOWS */ return fd; }
/* Make the file descriptor non-inheritable. Return 0 on success, set errno and return -1 on error. */ static int make_non_inheritable(int fd) { return set_inheritable(fd, 0, 0, NULL); }
/* Set the inheritable flag of the specified file descriptor. On success: return 0, on error: raise an exception if raise is nonzero and return -1. If atomic_flag_works is not NULL: * if *atomic_flag_works==-1, check if the inheritable is set on the file descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and set the inheritable flag * if *atomic_flag_works==1: do nothing * if *atomic_flag_works==0: set inheritable flag to False Set atomic_flag_works to NULL if no atomic flag was used to create the file descriptor. atomic_flag_works can only be used to make a file descriptor non-inheritable: atomic_flag_works must be NULL if inheritable=1. */ int _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works) { return set_inheritable(fd, inheritable, 1, atomic_flag_works); }
/* Same as _Py_set_inheritable() but on error, set errno and don't raise an exception. This function is async-signal-safe. */ int _Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works) { return set_inheritable(fd, inheritable, 0, atomic_flag_works); }