Fread: ferror на pty без данных?

У меня есть два процесса, которые общаются через pty, не блокируя. Проблема в том, что fread() на мастере дает сбой, когда нет данных, доступных для обработки.

Как я могу игнорировать случай «нет данных для чтения/данных» при чтении из несвязанного файлового дескриптора на главной стороне? Я подозреваю, что есть какой-то флаг для open() или fcntl(), который я пропустил во время чтения?

// initialization:
int pty_fd = posix_openpt(O_RDWR | O_NOCTTY);
int rc = grantpt(pty_fd);
rc = unlockpt(pty_fd);
fcntl(pty_fd, F_SETFL, O_NONBLOCK);
fd_read = fdopen(pty_fd, "r");

// now, trying to read will fail if no data is present:
char buf[100];
int count = sizeof(buf);
size_t bytesRead = fread(buf, sizeof(char), count, fd_read);
if ((bytesRead == 0) && (ferror(fd_read)) {
    printf("fail...\n");
}

Конечно, я могу игнорировать возвращаемое значение ferror(), но я полагаю, что это неправильный способ использования этой функции.

Ах, одно: я нашел трюк POLLHUP на stackoverflowz. Это работает, но колоритно и, следовательно, не подходит для моего случая...

Привет


person klsdjfhsalkjfhl    schedule 19.01.2016    source источник
comment
Что вы ожидаете / хотите, чтобы fread вернул в таком случае?   -  person n. 1.8e9-where's-my-share m.    schedule 19.01.2016
comment
Ноль, как это бывает. Но я ожидаю, что ferror() не соответствует действительности...   -  person klsdjfhsalkjfhl    schedule 19.01.2016
comment
Запрос нескольких байтов и получение меньшего количества байтов по определению является либо eof, либо ошибкой. Вам нужно изучить errno, чтобы увидеть, что это за ошибка, и решить, как с ней справиться.   -  person n. 1.8e9-where's-my-share m.    schedule 19.01.2016
comment
Вероятно, не рекомендуется использовать stdio с ptys или другими специальными типами fd, которые имеют временные условия EOF или ошибки, когда вы действительно хотите рассматривать эти условия как временные. Есть способы заставить его работать, но работа напрямую с файловыми дескрипторами обычно имеет больше смысла.   -  person R.. GitHub STOP HELPING ICE    schedule 19.01.2016
comment
@н.м. Это ошибка, даже когда я сказал O_NONBLOCK? Как я могу отличить отсутствие байтов (я согласен с этим) и мир в огне (вероятно, следует вызвать выход сейчас...)?   -  person klsdjfhsalkjfhl    schedule 19.01.2016
comment
Я бы предположил, что это ошибка по определению, определение заключается в том, что базовый уровень ввода-вывода POSIX устанавливает errno (вероятно, в данном случае EAGAIN).   -  person n. 1.8e9-where's-my-share m.    schedule 19.01.2016
comment
ха, я как-то не заметил, что errno все равно выставляется, даже fread... глупый я...   -  person klsdjfhsalkjfhl    schedule 20.01.2016