/* 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; }
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; }
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; }
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; }