Совершенно верно: выполнение печати errno
и вызова perror
сразу после чтения приводит к «ресурсу занято» и к ошибке с номером 11, или EAGAIN/EWOULDBLOCK
, как показано в этом коде:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main (void) {
char buf;
fcntl (STDOUT_FILENO, F_SETFL, fcntl (STDOUT_FILENO, F_GETFL, 0) | O_NONBLOCK);
fprintf (stderr, "%5d: ", errno); perror("");
read (STDIN_FILENO, &buf, 1);
fprintf (stderr, "%5d: ", errno); perror("");
}
, который генерирует:
0: Success
11: Resource temporarily unavailable
Причина в том, что файловые дескрипторы имеют два различных типа флагов (см. здесь в разделе, подробно описывающем дублирование файловых дескрипторов):
Вы можете продублировать дескриптор файла или выделить другой дескриптор файла, который ссылается на тот же открытый файл, что и оригинал. Дублирующиеся дескрипторы совместно используют одну позицию файла и один набор флагов состояния файла (см. Флаги состояния файла), но каждый имеет свой собственный набор флагов дескриптора файла (см. Флаги дескриптора).
Первый - это флаги дескриптора файла , и они действительно уникальны для каждого дескриптора файла. Согласно документации, FD_CLOEXEC
(рядом с exec
) является единственным в настоящее время в этом лагере.
Все остальные флаги являются флагами состояния файла и совместно используются дескрипторами файлов, которые были продублированы. К ним относятся режимы ввода-вывода , такие как O_NONBLOCK
.
Итак, что здесь происходит, так это то, что стандартный дескриптор выходного файла был продублирован из стандартного входного (порядок не имеет значения, только тот факт, что один был продублирован из другого), так что установка режима неблокирования для одного влияет на все дубликаты (и это, вероятно, также включало бы стандартный дескриптор файла ошибок, хотя я не подтвердил это).
Обычно не стоит разбираться с режимом блокировки дубликатов файловых дескрипторов или файловыми дескрипторами, которые, вероятно, будут наследоваться подпроцессами - эти подпроцессы не всегда любезны иметь свой стандарт файлы плохо себя ведут (с их точки зрения).
Если вы хотите более детальный контроль над отдельными файловыми дескрипторами, рассмотрите возможность использования select
для проверки дескрипторов перед попыткой чтения.