2013-05-29 3 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»?

EDIT:
добавлены библиотеки, включенные в код.

+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

Это несколько атипичный случай - обычно, если оболочка устанавливает что-то вроде этого, оболочка будет родительской для обоих, вместо того, чтобы стать одной из исполняемых программ. Таким образом, наличие оригинального процесса fork два раза, а затем ждать одного из детей может быть решением. –

Смежные вопросы