lib/process.c
/* Starts a subprocess with the arguments in the null-terminated argv[] array.
 * argv[0] is used as the name of the process.  Searches the PATH environment
 * variable to find the program to execute.
 *
 * This function may not be called after creating any additional threads.
 *
 * All file descriptors are closed before executing the subprocess, except for
 * fds 0, 1, and 2.
 *
 * Returns 0 if successful, otherwise a positive errno value indicating the
 * error.  If successful, '*pp' is assigned a new struct process that may be
 * used to query the process's status.  On failure, '*pp' is set to NULL. */
Starts a subprocess with the arguments in the null-terminated argv[] array.
argv[0] is used as the name of the process.  Searches the PATH environment
variable to find the program to execute.

This function may not be called after creating any additional threads.

All file descriptors are closed before executing the subprocess, except for
fds 0, 1, and 2.

Returns 0 if successful, otherwise a positive errno value indicating the
error.  If successful, '*pp' is assigned a new struct process that may be
used to query the process's status.  On failure, '*pp' is set to NULL.
Starts a subprocess with the arguments in the null - terminated argv [] array . argv [ 0 ] is used as the name of the process . Searches the PATH environment variable to find the program to execute . This function may not be called after creating any additional threads . All file descriptors are closed before executing the subprocess except for fds 0 1 and 2 . Returns 0 if successful otherwise a positive errno value indicating the error . If successful ' * pp ' is assigned a new struct process that may be used to query the process ' s status . On failure ' * pp ' is set to NULL .
int
process_start(char **argv, struct process **pp)
{
#ifndef _WIN32
    pid_t pid;
    int error;
    sigset_t prev_mask;
    assert_single_threaded();
    *pp = NULL;
    COVERAGE_INC(process_start);
    error = process_prestart(argv);
    if (error) {
        return error;
    }
    fatal_signal_block(&prev_mask);
    pid = fork();
    if (pid < 0) {
        VLOG_WARN("fork failed: %s", ovs_strerror(errno));
        error = errno;
    } else if (pid) {
        *pp = process_register(argv[0], pid);
        error = 0;
    } else {
        int fd_max = get_max_fds();
        int fd;
        fatal_signal_fork();
        for (fd = 3; fd < fd_max; fd++) {
            close(fd);
        }
        xpthread_sigmask(SIG_SETMASK, &prev_mask, NULL);
        execvp(argv[0], argv);
        fprintf(stderr, "execvp(\"%s\") failed: %s\n",
                argv[0], ovs_strerror(errno));
        _exit(1);
    }
    xpthread_sigmask(SIG_SETMASK, &prev_mask, NULL);
    return error;
#else
    *pp = NULL;
    return ENOSYS;
#endif
}
int process_start ( char * * argv , struct process * * pp ) { #ifndef _WIN32 pid_t pid ; int error ; sigset_t prev_mask ; assert_single_threaded ( ) ; * pp = NULL ; COVERAGE_INC ( process_start ) ; error = process_prestart ( argv ) ; if ( error ) { return error ; } fatal_signal_block ( & prev_mask ) ; pid = fork ( ) ; if ( pid < 0 ) { VLOG_WARN ( " " , ovs_strerror ( errno ) ) ; error = errno ; } else if ( pid ) { * pp = process_register ( argv [ 0 ] , pid ) ; error = 0 ; } else { int fd_max = get_max_fds ( ) ; int fd ; fatal_signal_fork ( ) ; for ( fd = 3 ; fd < fd_max ; fd ++ ) { close ( fd ) ; } xpthread_sigmask ( SIG_SETMASK , & prev_mask , NULL ) ; execvp ( argv [ 0 ] , argv ) ; fprintf ( stderr , " \" \" \n " , argv [ 0 ] , ovs_strerror ( errno ) ) ; _exit ( 1 ) ; } xpthread_sigmask ( SIG_SETMASK , & prev_mask , NULL ) ; return error ; #else * pp = NULL ; return ENOSYS ; #endif }
Starts a subprocess with the arguments in the null-terminated argv[] array.
Starts a subprocess with the arguments in the null - terminated argv [] array .
/* Running in parent process. */ /* Running in child process. */