关于在Unix中实现系统功能的困惑

时间:2019-03-19 03:19:54

标签: c unix

来自 APUE 的Unix system函数的实现:

  

图8.22 system函数,不进行信号处理

#include    <sys/wait.h>
#include    <errno.h>
#include    <unistd.h>

int
system(const char *cmdstring)   /* version without signal handling */
{
    pid_t   pid;
    int     status;

    if (cmdstring == NULL)
        return(1);      /* always a command processor with UNIX */

    if ((pid = fork()) < 0) {
        status = -1;    /* probably out of processes */
    } else if (pid == 0) {              /* child */
        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127);     /* execl error */
    } else {                            /* parent */
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1; /* error other than EINTR from waitpid() */
                break;
            }
        }

        // if(waitpid(pid, &status, 0) < 0){
        //     if(errno != EINTR){
        //         status = -1;
        //     }
        // } 
    }

    return(status);
}

为什么它对while使用waitpid循环而不是我在注释中添加的if语句?我尝试过if,但到目前为止没有出错。

1 个答案:

答案 0 :(得分:6)

除了子进程结束之外,waitpid函数如果被信号中断,可能会更早返回。如果真是这样,将不会输入if块,而将再次尝试waitpid

在没有循环的情况下,如果waitpid被打断,您最终将处于父进程不等待孩子的状态,而当孩子退出时,您将陷入僵尸进程。直到父进程退出,僵尸才会被清理,这时init进程成为父进程并自动等待僵尸。