Antes da padronização havia ioctl(
... FIONBIO
... )
e fcntl(
... O_NDELAY
... )
, mas esses se comportavam de maneira inconsistente entre os sistemas e até mesmo dentro do mesmo sistema. Por exemplo, era comum FIONBIO
trabalhar em soquetes e O_NDELAY
trabalhar em ttys, com muita inconsistência para coisas como tubos, fifos e dispositivos. E se você não sabia que tipo de descritor de arquivo você tinha, você teria que definir ambos para ter certeza. Mas, além disso, uma leitura sem bloqueio e sem dados disponíveis também foi indicada de forma inconsistente; dependendo do sistema operacional e do tipo de descritor de arquivo, a leitura pode retornar 0, ou -1 com errno EAGAIN, ou -1 com errno EWOULDBLOCK. Ainda hoje, definindo FIONBIO
ouO_NDELAY
no Solaris faz com que uma leitura sem dados retorne 0 em um tty ou pipe, ou -1 com errno EAGAIN em um soquete. No entanto, 0 é ambíguo, pois também é retornado para EOF.
POSIX abordou isso com a introdução de O_NONBLOCK
, que padronizou o comportamento em diferentes sistemas e tipos de descritores de arquivo. Como os sistemas existentes geralmente desejam evitar quaisquer mudanças no comportamento que possam quebrar a compatibilidade com versões anteriores, POSIX definiu um novo sinalizador em vez de obrigar um comportamento específico para um dos outros. Alguns sistemas como Linux tratam todos os 3 da mesma maneira e também definem EAGAIN e EWOULDBLOCK com o mesmo valor, mas sistemas que desejam manter algum outro comportamento legado para compatibilidade com versões anteriores podem fazê-lo quando os mecanismos mais antigos são usados.
Novos programas devem usar fcntl(
... O_NONBLOCK
... )
, conforme padronizado por POSIX.