Beispiel #1
0
/* Calls fork() and on success returns its return value.  On failure, logs an
 * error and exits unsuccessfully.
 *
 * Post-fork, but before returning, this function calls a few other functions
 * that are generally useful if the child isn't planning to exec a new
 * process. */
static pid_t
fork_and_clean_up(void)
{
    pid_t pid = xfork();
    if (pid > 0) {
        /* Running in parent process. */
        fatal_signal_fork();
    } else if (!pid) {
        /* Running in child process. */
        lockfile_postfork();
    }
    return pid;
}
Beispiel #2
0
static pid_t
fork_and_wait_for_startup(int *fdp)
{
    int fds[2];
    pid_t pid;

    if (pipe(fds) < 0) {
        ovs_fatal(errno, "pipe failed");
    }

    pid = fork();
    if (pid > 0) {
        /* Running in parent process. */
        char c;

        close(fds[1]);
        fatal_signal_fork();
        if (read(fds[0], &c, 1) != 1) {
            int retval;
            int status;

            do {
                retval = waitpid(pid, &status, 0);
            } while (retval == -1 && errno == EINTR);

            if (retval == pid
                && WIFEXITED(status)
                && WEXITSTATUS(status)) {
                /* Child exited with an error.  Convey the same error to
                 * our parent process as a courtesy. */
                exit(WEXITSTATUS(status));
            }

            ovs_fatal(errno, "fork child failed to signal startup");
        }
        close(fds[0]);
        *fdp = -1;
    } else if (!pid) {
        /* Running in child process. */
        close(fds[0]);
        time_postfork();
        lockfile_postfork();
        *fdp = fds[1];
    } else {
        ovs_fatal(errno, "could not fork");
    }

    return pid;
}
Beispiel #3
0
static pid_t
fork_and_wait_for_startup(int *fdp)
{
    int fds[2];
    pid_t pid;

    xpipe(fds);

    pid = fork();
    if (pid > 0) {
        /* Running in parent process. */
        size_t bytes_read;
        char c;

        close(fds[1]);
        fatal_signal_fork();
        if (read_fully(fds[0], &c, 1, &bytes_read) != 0) {
            int retval;
            int status;

            do {
                retval = waitpid(pid, &status, 0);
            } while (retval == -1 && errno == EINTR);

            if (retval == pid
                && WIFEXITED(status)
                && WEXITSTATUS(status)) {
                /* Child exited with an error.  Convey the same error to
                 * our parent process as a courtesy. */
                exit(WEXITSTATUS(status));
            }

            VLOG_FATAL("fork child failed to signal startup (%s)",
                       strerror(errno));
        }
        close(fds[0]);
        *fdp = -1;
    } else if (!pid) {
        /* Running in child process. */
        close(fds[0]);
        time_postfork();
        lockfile_postfork();
        *fdp = fds[1];
    } else {
        VLOG_FATAL("fork failed (%s)", strerror(errno));
    }

    return pid;
}
Beispiel #4
0
static enum { PARENT, CHILD }
do_fork(void)
{
    switch (fork()) {
    case 0:
        lockfile_postfork();
        return CHILD;

    default:
        return PARENT;

    case -1:
        /* Error. */
        ovs_fatal(errno, "fork failed");
    }
}
/* Calls fork() and on success returns its return value.  On failure, logs an
 * error and exits unsuccessfully.
 *
 * Post-fork, but before returning, this function calls a few other functions
 * that are generally useful if the child isn't planning to exec a new
 * process. */
pid_t
fork_and_clean_up(void)
{
    pid_t pid;

    pid = fork();
    if (pid > 0) {
        /* Running in parent process. */
        fatal_signal_fork();
    } else if (!pid) {
        /* Running in child process. */
        time_postfork();
        lockfile_postfork();
    } else {
        VLOG_FATAL("fork failed (%s)", strerror(errno));
    }

    return pid;
}