ps命令linux vs unix在c程序中的不同行为

时间:2013-05-29 04:01:09

标签: c linux unix

我有一个简单的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'与众不同?

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

1 个答案:

答案 0 :(得分:2)

当程序调用fork时,它会创建父进程和子进程。在子进程中,fork返回0并在父进程中返回1.每当子进程终止时,SIGCHLD信号就会发送到父进程。

现在,在您的情况下,您在父进程和子进程中调用execlp,这将替换正在运行的进程映像,但不会更改关系。这意味着ps是您的父流程,grep是您的子流程。通常情况下这没关系,因为程序默认忽略SIGCHLD,但ps捕获所有未知信号并退出,并显示您在那里看到的消息。您可以在source code for ps(或更确切地说procps)中看到相关功能。