Close all File Handles when Calling posix_spawn

Asked
Active3 hr before
Viewed126 times

5 Answers

90%

If file_actions is a null pointer, then file descriptors open in the calling process shall remain open in the child process, except for those whose close-on- exec flag FD_CLOEXEC is set (see fcntl() ). ,Open file descriptor handling over fork() and exec*() in a multithreaded application using file leases and/or fcntl() locks (record locks) is dicey.,Note that it is much faster to simply try setting the flag on all possible descriptors, than to try and find out which descriptors are actually open. (The latter is possible in Linux via e.g. /proc/self/fd/.),Second, I prefer to use a helper function to create a control pipe to the child process, move the file descriptors to their proper places (which is not always trivial), and fork the child process. The signature is usually similar to

Because of all of the above, I personally prefer to open files with O_CLOEXEC and/or use fcntl(fd,F_SETFD,FD_CLOEXEC) so that all descriptors are close-on-exec by default. Something like

#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;

    /* Resource limit? */
#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
    /* POSIX: 8 message queues, 20 files, 8 streams */
    rlim.rlim_max = 36;
#endif

    /* Configured limit? */
#if defined(_SC_OPEN_MAX)
    max = sysconf(_SC_OPEN_MAX);
#else
    max = 36L;
#endif

    /* Use the bigger of the two. */
    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);
}
load more v
88%

For details of in-depth Linux/UNIX system programming training courses that I teach, look here.

POSIX_SPAWN(3) Linux Programmer 's Manual         POSIX_SPAWN(3)
load more v
72%

Regarding 2. above, note that the spawn open file action provides to posix_spawn() and posix_spawnp() the same capability that the shell redirection operators provide to system(), only without the intervening execution of a shell; for example:,It shall not be considered an error for the fildes argument passed to these functions to specify a file descriptor for which the specified operation could not be performed at the time of the call. Any such error will be detected when the associated file actions object is later used during a posix_spawn() or posix_spawnp() operation.,The posix_spawn_file_actions_addclose() function shall add a close action to the object referenced by file_actions that shall cause the file descriptor fildes to be closed (as if close(fildes) had been called) when a new process is spawned using this file actions object.,A spawn file actions object is of type posix_spawn_file_actions_t (defined in <spawn.h>) and is used to specify a series of actions to be performed by a posix_spawn() or posix_spawnp() operation in order to arrive at the set of open file descriptors for the child process given the set of open file descriptors of the parent. POSIX.1-2017 does not define comparison or assignment operators for the type posix_spawn_file_actions_t.

Regarding 2. above, note that the spawn open file action provides to posix_spawn() and posix_spawnp() the same capability that the shell redirection operators provide to system(), only without the intervening execution of a shell; for example:

system("myprog <file1 3<file2");
65%

If file_actions is NULL, then the file descriptors that are open in the calling process remain open in the child process, except for those whose close-on-exec flag, FD_CLOEXEC, is set. For those file descriptors that remain open, all attributes of the corresponding open file descriptions, including file locks, remain unchanged. For more information about FD_CLOEXEC and file locks, see fcntl().,The set of open file descriptors for the child process is initially the same set as is open for the calling process. All attributes of the corresponding open file descriptions, including file locks, remain unchanged.,The child process is started on the same node that the calling process is running on. , that's used to define an environment variable. If the value of envp is NULL, then the child process inherits the environment of the parent process.

NULL
variable = value
75%

The set of open file descriptors for the child process is initially the same set as is open for the calling process. All attributes of the corresponding open file descriptions, including file locks, remain unchanged.,If file_actions is a null pointer, file descriptors that are open in the calling process remain open in the child process, except for those whose FD_CLOEXEC flag is set. For those file descriptors that remain open, all attributes of the corresponding open file descriptions, including file locks, remain unchanged. ,If this error occurs after the calling process successfully returns from the posix_spawn or posix_spawnp function, the child process might exit with exit status 127. ,The signal mask, signal default actions, and the effective user and group IDs for the child process are changed as specified in the attributes object referenced by attrp.

Syntax

int posix_spawn(pid_t * restrict pid,
   const char * restrict path,
      const posix_spawn_file_actions_t * file_actions,
         const posix_spawnattr_t * restrict attrp,
            char *
            const argv[restrict], char *
               const envp[restrict]);
int posix_spawnp(pid_t * restrict pid,
   const char * restrict file,
      const posix_spawn_file_actions_t * file_actions,
         const posix_spawnattr_t * restrict attrp,
            char *
            const argv[restrict], char *
               const envp[restrict]);
load more v

Other "undefined-undefined" queries related to "Close all File Handles when Calling posix_spawn"