2013-05-29 81 views
1

我有一個簡單的c程序,執行'ps'並將其管理爲'grep',基本上'ps | grep x'。ps命令linux vs unix在c程序中的不同行爲

代碼去更多或東西少這樣的:

#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

嘗試閱讀關於'SIGCHLD'。 – icktoofay

+0

謝謝,這實際上很有幫助。我正在搜索'信號17',但沒有得到任何有用的信息。現在已經很晚了,明天我會花一些時間研究它。 – Lex

回答

2

當程序調用fork時,它創建一個父進程和一個子進程。在子進程中,fork返回0,並在父進程中返回1.每當子進程終止時,SIGCHLD信號就會發送給父進程。

現在,在您的情況下,您可以在父進程和子進程中都調用execlp,它將替換正在運行的進程映像,但不會更改關係。這意味着ps是您的父母程序,grep是您的子程序。通常這並不重要,因爲程序默認忽略SIGCHLD,但是ps會捕獲所有未知信號並退出。您可以在source code for ps(或者procps)中看到相關功能。

+0

是的,但這是否發生,因爲grep異常終止提前,或作爲在輸入結束時正常終止grep的結果,並且ps的競爭條件即使已關閉stdout也沒有終止? –

+0

我認爲這是第二次,但我需要熬夜比我願意肯定:) –

+0

這是一個有點不典型的情況 - 通常情況下,如果殼設置這樣的東西了,殼將父母而不是成爲執行的程序之一。因此,讓原始流程分叉兩次,然後等待其中一個孩子可能是一個解決方案。 –