выберите сбой с помощью программы C, но не оболочки - PullRequest
3 голосов
/ 03 мая 2010

У меня есть родительский и дочерний процессы, и родитель может читать выходные данные дочернего элемента и отправлять их на вход дочернего элемента. Пока что все отлично работает со скриптами оболочки, тестирующими команды, которые вводят и выводят данные. Я только что протестировал с простой программой на C и не смог заставить ее работать. Вот программа на C:

#include <stdio.h>

int main( void ) {
  char stuff[80];
  printf("Enter some stuff:\n");
  scanf("%s", stuff);

  return 0;
}

Проблема с программой на C состоит в том, что мой выбор не может прочитать от дочернего fd и, следовательно, программа не может завершиться. Вот бит, который делает выбор ..

//wait till child is ready
fd_set set;
struct timeval timeout;

FD_ZERO( &set ); // initialize fd set
FD_SET( PARENT_READ, &set ); // add child in to set
timeout.tv_sec = 3;
timeout.tv_usec = 0;

int r = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
if( r < 1 ) { // we didn't get any input
    exit(1);
}

Кто-нибудь знает, почему это происходит с программой на C, а не с оболочкой?

Редактировать: я должен указать, что дочерний процесс вызывает exec для аргумента, поэтому у меня нет доступа к нему после этой точки.

Ответы [ 2 ]

2 голосов
/ 03 мая 2010

Проблема в том, что дочерний процесс полностью буферизует вывод, потому что он пишет в канал, а не в терминал. Используйте setvbuf для принудительной буферизации строк или небуферизованного режима, или добавьте явный fflush к дочернему элементу после printf, или используйте программу unbuffer , которая поставляется с Expect, чтобы обмануть libc дочернего процесса в думая, что программа работает в интерактивном режиме.

1 голос
/ 03 мая 2010

Очистите свой стандартный вывод перед блокировкой ввода в программе C.

fflush(stdout);

В оболочке это часто неявно.

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

setvbuf(stdout, NULL, _IONBF, 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...