c читать () с трубой бездействует - PullRequest
0 голосов
/ 28 марта 2012

Я написал этот фрагмент кода, который должен перенаправить что-то, записанное в STDOUT, функцией в STDIN, чтобы это могло быть прочитано другой функцией. Я не могу получить доступ к этим функциям, так что это единственный способ, которым я могу их использовать. mpz_fput(stdout, c) является одной из этих функций. Он просто печатает на STDOUT что-то, содержащееся в структуре данных c.

Теперь все работало нормально при отладке, как и в следующем коде: printf();, за которым следует fflush(stdout); (необходим для печати отладочных сообщений). Теперь, когда я удалил эти две строки, я заметил (используя gdb), что этот код бездействует в функции read() (последняя строка этого фрагмента кода)

char buffer[BUFSIZ] = "";
int out_pipe[2];
int in_pipe[2];
int saved_stdout;
int saved_stdin;
int errno;

// REDIRECT STDIN
saved_stdin = dup(STDIN_FILENO);    /* save stdin for later */
if(errno= pipe(in_pipe) != 0 ) {          /* make a pipe */
  printf("\n%s",strerror(errno));
  exit(1);
}
close(STDIN_FILENO);
dup2(in_pipe[0], STDIN_FILENO);     /* redirect pipe to stdin */

// REDIRECT STDOUT
saved_stdout = dup(STDOUT_FILENO);  /* save stdout for display later */
if(errno= pipe(out_pipe) != 0 ) {          /* make a pipe */
  printf("\n%s",strerror(errno));
  exit(1);
}
dup2(out_pipe[1], STDOUT_FILENO);   /* redirect stdout to the pipe */
close(out_pipe[1]);

mpz_fput(stdout,c);         // put c on stdout
read(out_pipe[0], buffer, BUFSIZ);  // read c from stdout pipe into buffer

есть идеи, почему это так?

1 Ответ

0 голосов
/ 28 марта 2012

Кажется, вы использовали тип блокировки.В этом случае out_pipe [0] является дескриптором блокировки.Так что read () заблокирован и ждет чего-либо из out_pipe [0].

Кроме того, я думаю, что есть что-то, что связано с fflush ():

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

В вашем случае вы перенаправили канал в STDOUT, затем вызвали fflush (), чтобы очистить все содержимое в STDOUT и переместить их в буфер read ().Затем вы вызвали read (), чтобы прочитать их.Если вы не вызываете fflush (), а буфер read () будет пустым.Поскольку это дескриптор блокировки, используемый read (), вы ничего не можете прочитать из буфера, поэтому он будет заблокирован.

Это краткая теория, я предлагаю вам прочитать справочную страницу Linux для более подробной информации.

...