2014-01-29 5 views
0

Я сравнивал это с предыдущими сообщениями, связанными с трубопроводом, и я не могу найти проблему. Все в родителе кажется закрытым, как должно. Он отлично работает при вводе правильной команды (ex «ls | grep a), но если она не является допустимой командой (ex« ls | grup a), программа перестает отвечать на ввод пользователя (она продолжает работать, но она просто не работает) т сделать что-нибудь, когда вы вводите команду)Проблемы с трубопроводом для базовой программы оболочки

Основная функция:

int main() { 
int i; 
char **args; 

int pipeCheck = 0; 
int argCount = -1; 
int blank = 0; 

while(1) { 
    args = getln(); 

    if (args[0] != NULL){ 
     blank = 1; 
     if (strcmp(args[0],"exit")==0) exit(0); 
    } 
    for(i = 0; args[i] != NULL; i++) { 
    if (strcmp(args[i], "|")==0){ 
      pipeCheck = i; 
     } 
    } 
    if (pipeCheck != 0){ 
      args[pipeCheck] = NULL; 
      directPipe(args, pipeCheck, argCount, ampCheck); 
     } 
} 

} Это функция для трубопроводов в моей программе:

int directPipe(char ** args, int fileNumber, int argCount,int ampCheck){ 
    int fd[2]; 
    int child1,child2; 
    int status; 
    int i; 
    char * piped[10000]; 
    int count = 0; 

    for (i = (fileNumber+1); args[i] != NULL; i++){ 
     piped[count] = args[i]; 
     count++; 
    } 
    piped[count] = NULL; 

    printf("\nPipe attempted...\n"); 

    pipe(fd); 

    child1 = fork(); 
    if (child1==0){ 
     close(1); 
     dup(fd[1]); 
     close(fd[0]); 
     close(fd[1]); 

     execvp(args[0], args); 
     printf("Unknown command, please try again."); 
     exit(0); 
    } 

    child2 = fork(); 

    if (child2 ==0){ 

     close(0); 
     close(fd[1]); 
     dup(fd[0]); 
     close(fd[0]); 

     execvp(piped[0], piped); 
     printf("Unknown command, please try again."); 
     exit(0); 
    } 

    close(fd[1]); 
    close(fd[0]); 

    if (ampCheck == 0){ 
     while (wait(&status) != child1); 
     while (wait(&status) != child2); 
    } 
    else{ 
     printf("\nampCheck = %d",ampCheck); 
     sigset(child2, printer()); 
    } 

    return (0); 
} 
+0

«контроль не возвращается к родительскому» --- расскажите, что вы наблюдаете. –

+0

Непонятно. Каковы функциональные аргументы в точности. Нужно минимальное 'main()' компилировать полную программу и инструкции для воспроизведения проблемы. – grebneke

+0

добавлено основное и исправлено объяснение –

ответ

0

Ваша проблема является пара wait() петель :

while (wait(&status) != child1); 
while (wait(&status) != child2); 

В вашем сценарии второй ребенок умирает до первого, поэтому вы собираете его труп в первом цикле, но игнорируете его. Затем второй цикл переходит в оживленное ожидание, потому что детей больше нет.

Как минимум, вам нужно сделать:

int corpse; 

while ((corpse = wait(&status)) != -1 && corpse != child1 && corpse != child2) 
    ; 
while ((corpse = wait(&status)) != -1 && corpse != child1 && corpse != child2) 
    ; 

Это обрабатывает детей, умирающих в любом порядке - но только двое детей. Для более общего конвейера (три или более процессов) вам приходится работать сложнее - и использовать один цикл. Более общая форма будет что-то вроде:

int corpse; 

while ((corpse = wait(&status)) != -1) 
{ 
    if (record_death_of_child(corpse, status) == -1) 
     break; 
} 

где код создания процесса записывает ИДП из созданных процессов, и record_death_of_child() кода сделок с этим списком СОИДА и возвращает -1, когда нет больше детей подождите в текущем конвейере (и 0 в противном случае). Или вы можете использовать другие эвристики, чтобы определить, когда выйти из цикла. Обратите внимание: если у вас есть длительные рабочие задания в фоновом режиме, любой из них может умереть, и этот труп будет собран в цикле. Функция «записи смерти» также должна была бы обрабатывать такие процессы - их больше нельзя вводить на передний план, и вам нужно сообщить, что они вышли, и т. Д.

Возможно, вы можете использовать waitpid(), так как вы можете организовать для этого не зависание, пока есть фоновый процесс, который все еще работает с использованием WNOHANG.

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