Unix系统函数实现的困惑

标签 c unix

<分区>

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

Figure 8.22 The system function, without signal handling

#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);
}

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

最佳答案

除了子进程结束之外,waitpid 函数如果被信号中断也可以提前返回。如果发生这种情况,将不会进入 if block ,并且将再次尝试 waitpid

如果没有循环,如果 waitpid 被中断,您最终将处于父进程不等待子进程的状态,并且当子进程退出时您将进入僵尸进程。在父进程退出之前,该僵尸不会被清理,此时 init 进程成为父进程并自动等待僵尸。

关于Unix系统函数实现的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55233149/

相关文章:

c - 在 C 中丢弃数十和数百列的 int

c++ - 使用什么格式说明符在 C 中打印 "unsigned long long"并在控制台上获取截断值?

c - 如何在 C 中移植打印 int64_t 类型

linux - 无限递归别名 `cd`

linux - 如何在使用curl时阻止密码在ps上可见

c - 使用recv从套接字接收数据不起作用

linux - 如何使用shell脚本按字母顺序将一行插入到文件中

c - 使用进程通过管道运行命令

c - sdcc 内联 asm() 不工作

linux - 根据字典替换文本