До стандартизации было ioctl(
... FIONBIO
... )
и fcntl(
... O_NDELAY
... )
, но они вели себя непоследовательно между системами и даже внутри та же система. Например, FIONBIO
обычно работает с сокетами, а O_NDELAY
- с ttys, что приводит к большим несоответствиям для таких вещей, как трубы, fifos и устройства. И если вы не знаете, какой у вас дескриптор файла, вам придется установить оба, чтобы быть уверенным. Но кроме того, неблокирующее чтение без доступных данных также было указано непоследовательно; в зависимости от ОС и типа дескриптора файла, чтение может вернуть 0, или -1 с ошибкой EAGAIN, или -1 с ошибкой EWOULDBLOCK. Даже сегодня установка FIONBIO
или O_NDELAY
в Solaris приводит к тому, что чтение без данных возвращает 0 для tty или канала или -1 с ошибкой EAGAIN для сокета. Однако 0 является неоднозначным, поскольку он также возвращается для EOF.
POSIX решил эту проблему с введением O_NONBLOCK
, который имеет стандартизированное поведение в разных системах и типах файловых дескрипторов. Поскольку существующие системы обычно хотят избежать любых изменений в поведении, которые могут нарушить обратную совместимость, POSIX определил новый флаг, а не предписывал конкретное поведение для одного из других. Некоторые системы, такие как Linux, обрабатывают все 3 одинаково, а также определяют EAGAIN и EWOULDBLOCK для одного и того же значения, но системы, желающие поддерживать некоторое другое устаревшее поведение для обратной совместимости, могут делать это при использовании более старых механизмов.
Новые программы должны использовать fcntl(
... O_NONBLOCK
... )
, как стандартизировано POSIX.