Start a child process on OSX / Unix that does not inherit files / ports

I want to start a child process on OS X so that the child process does not inherit the current open files / ports process.

Any suggestions on how to do this? The shell commands I can call with the system () function will work too - I just don't know of a good shell command that allows this.

Thank!

+2


source to share


4 answers


After some experimentation, I found that the "open" shell command on Mac creates a process that doesn't inherit files / ports from the parents. Calling "open foo.app" as arguments to a system function does the trick. Of course, this is just a poppy. On Unix, one of the other methods suggested here makes a lot of sense.



0


source


You didn't mention what language you are working in, but since you mentioned system()

, I assume you mean C or C ++.

This is usually done with fcntl () to set the close-on-exec flag on those file descriptors that you don't want to inherit:

int fd = open("somefile", O_RDONLY);
fcntl(fd, F_SETFD, FD_CLOEXEC);

      

You can also do this brute-force by iterating through all possible fd's in the child after the fork, but before exec. This is a little more complicated because it requires you to know what the maximum possible fd value is, and it is also less efficient because you end up repeating and “closing” a bunch of unused fd's. Something like that:



pid_t pid = fork();
switch (pid) {
    case 0:
        // In the child process.  Iterate through all possible file descriptors
        // and explicitly close them.

        long maxfd = sysconf(OPEN_MAX);
        for (long i = 0; i < maxfd; ++i) {
            close(i);
        }

        // Now exec the new program, file-handle free.

        execlp("someprogram", "arg1", "arg2");
        break;
    case -1:
        // TODO: handle errors.

        break;
    default:
        // Parent process.

        int status;
        pid_t finished = waitpid(pid, &status, 0);
        break;
}

      

Hope it helps,

Eric Melsky

+10


source


On Mac OS X, you can read the directory /dev/fd/

with opendir()

/ readdir()

to determine the set of open file descriptors. With this information, you can call fcntl(

fd , F_SETFD, FD_CLOEXEC)

on every open file descriptor, or you can call close(

fd )

on every file descriptor after fork.

See Retrieving Highest Allocated File Descriptor for more information, including approaches to other systems.

+1


source


@Eric M: Your answer gave me most of the path, but I found that it still left some file descriptors open. I replaced sysconf(OPEN_MAX)

with your code above getdtablesize()

and it works great. Thanks for the help!

0


source







All Articles