2012-05-25 2 views
0

Когда я выполняю эту функцию с ls | head, она зависает во втором дочернем процессе после распечатки файлов и каталогов. Может ли кто-нибудь сказать мне, что я здесь пропущу? Заранее спасибодочерний процесс зависает внутри трубы

int unipipe(char* lhs[], char* rhs[]) 
{ 
    int pfd[2]; 
    int status, cid; 
    pid_t pid; 
    char buf; 
    if((lhs != NULL) && (rhs != NULL)) 
    { 
     if(pipe(pfd) != 0) 
     { 
     perror("pipe"); 
     return -1; 
     } 
    if((pid = fork()) < 0) 
    { 
     perror("fork"); 
     return -1; 
    } 
    else if(pid == 0) 
    { 
     close(1); //close the unused read end 
     dup2(pfd[1], STDOUT_FILENO); 
     //execute the left-hand side command 
     close(pfd[0]); 
     execvp(lhs[0], lhs); 
     _exit(EXIT_SUCCESS); 
    } 

    if(setpgid(pid, 0) < 0) 
    { 
    perror("setpgid"); 
    return -1; 
    }; 

    cid = waitpid(pid, &status, 0); 
    if((pid = fork()) == 0) 
    { 
     close(0); 
     dup2(pfd[0], STDIN_FILENO); 
     close(pfd[1]); //close the unused write end 
     execvp(rhs[0], rhs); 
     _exit(EXIT_SUCCESS); 
    } 
    else 
    { 
      waitpid(pid, &status, 0); 
    } 
} 
+1

где работает функция unipipe в соответствии с вашим примером 'ls | head'? удачи. – shellter

+0

У меня есть парсер функций, который анализирует команду «ls | head» на два массива указателей символов: lhs будет {"ls", null}, а rhs - {"head", null}. Спасибо за ваш ответ! – jctank

ответ

1

Вы ожидаете, что первый процесс завершится до начала второго. Каждая труба имеет буфер, и как только этот буфер заполнен, блок функций ввода/вывода, ожидая, что несколько байтов будут считаны из канала, чтобы большее количество могло «перетекать». Скорее всего, ваш первый процесс блокирует трубу и поэтому никогда не выходит.

Я бы объявил две переменные типа pid_t, по одному для каждого ребенка, и только дождался их обоих, как только они были успешно запущены.

+0

Удивительный! Это так, спасибо! – jctank

0

сделать вашу программу, вы удалите первый:

cid = waitpid(pid, &status, 0); 

на:

else 
{ 
     waitpid(pid, &status, 0); 
} 

заменить его:

wait(); // for the fist child 
wait(); // for the second child 

вашей программа будет запущена.

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