2013-09-12 4 views
1

Я сделал команду history в C, которая хранит и выводит команды в/из файла. Теперь я пытаюсь запустить «голову» над ним по трубопроводам. История | head -3Труба с командой printf

Для этого у меня есть первый dup2() stdout, чтобы написать конец трубы. Затем используется printf для печати истории (которая не будет отображаться на экране). Теперь после этого я перенаправил stdin, чтобы прочитать эту команду и команду execvp(). Он отображает верхние 3 строки правильно. Но он все еще ждет ввода пользователя. Я должен закончить с помощью Ctrl C. Любая идея, почему это происходит. Даже я попытался сбросить все в stdout после отображения истории. Ничто не работает.

pid=fork(); 
if(pid==0){ 
    if(...first time..){ 
     if(dup2(fd[1],1)<0){ 
       printf("Error in Dup!!"); 
     } 
     printHistory(); 
     for(k = 0;k < totalfds; k++){ 
       close(fd[k]); 
     } 
     return; 
    } 
    if(...second time..){ 
     if(dup2(fd[0],0)<0){ 
      printf("Error in Dup!!"); 
      } 
    } 
    ... 
    execvp(subcomm[0],subcomm); 
    ... 
} 
+2

Где код? Почему [tag: shell] указан? – sehe

+0

Его реализация оболочки в C. Вот почему. Я думаю, что код не потребуется, я его отредактирую. – rocker

+0

Это, вероятно, больше связано с тем, как работает 'head', чем что-либо. Как он ожидает завершения своего ввода? – Duck

ответ

1

Обычная проблема с командами, не заканчивающимися на EOF, заключается в том, что вы не закрыли достаточно файловых дескрипторов. Если команда head по-прежнему имеет дескриптор файла записи для открытого канала, то он может попытаться прочитать и повесить, потому что конец записи канала открыт - хотя это процесс head, который имеет его открытым и не будет писать пока чтение не вернется.

Кроме того, ваш ребенок, который делает printHistory(), должен, вероятно, сделать exit(0) (или, может быть, _exit(0)), когда это будет сделано - не возврат. Если он вернется, он, вероятно, вернется в цикл чтения. Вы также должны убедиться, что вы выходите из процесса (с ненулевым статусом), если execvp() терпит неудачу. Никогда не нужно проверять статус возврата execvp() или других членов функций exec*(). Если они вернутся, они потерпят неудачу; если они преуспеют, исходный процесс заменяется новым, и функция никогда не возвращается.

Кроме того, в качестве общего комментария, завершите свои сообщения символом новой строки; это помогает обеспечить их своевременное появление. Также рассмотрите отправку сообщений об ошибках в stderr вместо stdout.

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