Return to Snippet

Revision: 2002
at December 11, 2006 17:55 by CUViper

Initial Code
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

spawn(const char *file, char *const argv[])
    pid_t pid;
    int forkpipe[2];
    int fd_flags, err, ret;

    // set up a pipe for communication between forks
    ret = pipe(forkpipe);
    if (ret == -1)
        return -1;

    pid = fork();
    if (pid == -1) {
        err = errno;

        // close the write pipe

        goto parent_exit;

    if (pid == 0) {
        // forked child

        // close the read pipe
        ret = close(forkpipe[0]);
        if (ret == -1)
            goto child_err;

        // make the write end close-on-exec
        ret = fcntl(forkpipe[1], F_GETFD);
        if (ret == -1)
            goto child_err;
        fd_flags = ret | FD_CLOEXEC;
        ret = fcntl(forkpipe[1], F_SETFD, fd_flags);
        if (ret == -1)
            goto child_err;

        // try to run the app
        execvp(file, argv);
        // if we continue executing here, an error occurred

        // send the error code through the write pipe
        err = errno;
        write(forkpipe[1], &err, sizeof(err));


    // parent

    // close the write pipe

    // get the error code from the read pipe
    ret = read(forkpipe[0], &err, sizeof(err));
    if (ret == -1) {
        err = errno;
        pid = -1;
    } else if (ret == sizeof(err))
        pid = -1;
        err = 0;

    // close the read pipe

    if (err)
        errno = err;

    return pid;

Initial URL

Initial Description
With the typical fork+exec method of spawning an application, you are left in the dark about failures in the exec.  Once the fork occurs, the "main" process doesn't have any communication channel except waitpid, so it's hard to tell what happened.

With this function, a pipe is opened for the forked child to communicate errors.  If the exec succeeds, then the pipe is automatically closed, and the main process reports success.  Otherwise, the errno from exec is communicated through the pipe.

Initial Title
Safe application spawning with fork+exec

Initial Tags
unix, c, linux

Initial Language