fread() чтение из дескриптора на основе ошибки набора каналов, а не EOF, где нет данных

Мне нужно прочитать с помощью fread() материал с конца канала для чтения.

Но хотя я ожидаю, что fread() установит EOF, когда в канале ничего нет, вместо этого он устанавливает индикатор ошибки. Я проверил стандарты posix и C и не нашел там никакой подсказки. Наверное, я делаю что-то непреднамеренное (читай, глупое), да :)

Вот отрывок:

#include <stdio.h>
#include <fcntl.h>

int main()
{
   char buf[128];
   FILE *f;
   int pipe_fd[2], n;

   pipe(pipe_fd);
   fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK);

   f=fdopen(pipe_fd[0], "r");
   n=fread(buf, 1, 1, f);
   printf("read: %d, Error: %d, EOF: %d\n", n, ferror(f), feof(f));

   return 0;
}

person Community    schedule 07.12.2010    source источник


Ответы (1)


Поскольку вы используете неблокирующий канал, я считаю, что вы получите:

  • errno==EAGAIN когда просто нечего читать (сейчас это ничего не значит, но может быть что-то позже - попробуйте (е) еще раз позже).
  • EOF, когда сторона записи канала закрыта (что означает, что данные больше не поступают).

См. man-страницу для read() о том, как read() ведет себя, когда установлен режим O_NONBLOCK. fread() поведение должно соответствовать read().

person Bert F    schedule 07.12.2010
comment
Спасибо, Берт! Похоже на то. Таким образом, EAGAIN просто распространяется до уровня потоков и приводит к набору ошибок. Так что мой подход не сработает. Просто пытаюсь справиться с lex стандартным способом :) Поищем дальше... - person ; 07.12.2010
comment
Да, подумайте об этом, если он вернет EOF, когда канал временно заблокирован, то получатель не сможет сказать, все ли данные уже поступили. Вы не могли бы написать какие-либо программы, которые выполняют какую-либо реальную работу (с конвейерами), если бы они работали так, если бы у вас не было каких-то протоколов для повторного подключения для получения остальных данных. - person Steven Lu; 04.07.2013