Open the file descriptor handler through fork()and exec*()in a multi-threaded application, using file leases and / or fcntl()locks (write locks) are risky.
O_CLOEXEC/fcntl(fd, F_SETFD, FD_CLOEXEC) , . , , .
, Linux fcntl() fork(); . man 2 fork.
posix_spawn() C, posix_spawn_file_actions_init(), posix_spawn_file_actions_addclose() ; . . , exec*() .
- O_CLOEXEC / fcntl(fd,F_SETFD,FD_CLOEXEC), . -
#define _GNU_SOURCE
#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/resource.h>
void set_all_close_on_exec(void)
{
struct rlimit rlim;
long max;
int fd;
#if defined(RLIMIT_NOFILE)
if (getrlimit(RLIMIT_NOFILE, &rlim) != 0)
rlim.rlim_max = 0;
#elif defined(RLIMIT_OFILE)
if (getrlimit(RLIMIT_OFILE, &rlim) != 0)
rlim.rlim_max = 0;
#else
rlim.rlim_max = 36;
#endif
#if defined(_SC_OPEN_MAX)
max = sysconf(_SC_OPEN_MAX);
#else
max = 36L;
#endif
if ((int)max > (int)rlim.rlim_max)
fd = max;
else
fd = rlim.rlim_max;
while (fd-->0)
if (fd != STDIN_FILENO &&
fd != STDOUT_FILENO &&
fd != STDERR_FILENO)
fcntl(fd, F_SETFD, FD_CLOEXEC);
}
- ( ) close-on-exec; O_CLOEXEC. set_all_close_on_exec() 0.25ms ; 4096 1024 , 4093 .
( , fcntl(fd,F_SETFD,FD_CLOEXEC) errno==EBADF (/) .)
, , , . ( Linux , , /proc/self/fd/.)
-, , ( ) .
int do_exec(pid_t *const childptr,
const char *const cmd,
const char *const args[],
const int stdin_fd,
const int stdout_fd,
const int stderr_fd);
My do_exec() close-on-exec, . ( exec(), errno char . char . , exec : , , , waitpid(), errno. , - exec(), ( ) ).
, , , , Unix ( , ), . , , , Apache mod_cgid FastCGI.