1

我有一个简单的 c 程序,它执行 'ps' 并将其通过管道传递给 'grep',基本上是 'ps | grep x'。

代码或多或少是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int pid;

    pipe(pipefd);
    pid=fork();

    if (pid == 0){
        close(pipefd[1]);
        dup2(pipefd[0], 0);
        close(pipefd[0]);
        execlp("grep", "grep", "b", (char *) 0);
    }
    else{
        close(pipefd[0]);
        dup2(pipefd[1], 1);
        close(pipefd[1]);
        execlp("ps", "ps", (char *) 0);
    }
    exit(0);
}

我遇到的问题是,当我在 unix (Solaris) 上运行它时效果很好,但是当我在 (Debian) 上运行它时,它可以正常执行,但会给我一条错误消息。

错误信息:

Signal 17 (CHLD) caught by ps (procps-ng version 3.3.3).
ps:display.c:59: please report this bug

我尝试过运行不同命令(如“ls”和“grep”)的同一个程序,在任何一个操作系统上都没有问题。是什么让“ps”与众不同?

编辑:
将包含的库添加到代码中。

4

1 回答 1

2

When your program calls fork, it creates a parent process and a child process. In the child process fork returns 0 and in the parent it returns 1. Whenever a child process terminates, a SIGCHLD signal is sent to the parent process.

Now, in your case you call execlp in both the parent and child process, which replaces the running process image but does not change the relationship. This means that ps is your parent process and grep is your child process. Normally this would not matter, as programs ignore SIGCHLD by default, but ps catches all unknown signals and quits with the message you see there. You can see the relevant function in the source code for ps (or rather procps).

于 2013-05-29T04:31:14.820 回答