From: melennec@stna.dgac.fr (Ronan Melennec STNA 7C p8240 BD22)
Newsgroups: comp.unix.programmer
Subject: Re: non-blocking input
Date: 13 Aug 92 12:17:58 GMT
Organization: STNA 95 rue Henri Rochefort 91025 Evry Cedex 33(1)60.79.80.00

In article <93345@bu.edu>, tasos@cs.bu.edu (Anastasios Kotsikonas) writes:
> In article <1992Aug11.092112.8339@cenaath.cena.dgac.fr> melennec@stna.dgac.fr (Ronan Melennec STNA 7C p8240 BD22) writes:
> >In article <9208066999@umunk.GUN.de>, udo@umunk.GUN.de (Udo Munk) writes:
> >> zg03+@andrew.cmu.edu (Zafrir E. Gan) writes:
> >> : 
> >> : 	I'm writing an interactive server that needs to check for input from
> >> : sockets as well as keyboard commands.  The socket part is already done
> >> : so what I need is a way to check for input on the keyboard, read it if
> >> : it's there but continue with the cycle if it isn't.  Any suggestions?
> >> 
> >> Use fcntl(0, F_SETFL, O_NDELAY). A read from stdin now returns with 0
> >> bytes readed, if there is no input and you can continue the cycle.
> >
> >Using O_NDELAY leads to the following inconvenient : you can't
> >distinguish an IDLE input (no byte available) from a CLOSED input
> >(such as peer socket closed by peer process, or user hangup).
> >Both return 0.
> >
> 
> I would disagree. The following code works fine for me:
>
> [example of non blocking read on a socket fd deleted] 

My apologies: I should have written `you can't IN GENERAL distinguish...'

While it is true that O_NDELAY will put a socket file descriptor
in non blocking mode, it is in general not true for other kinds of file
descriptors.

Quote from SunOS 4.1.1 man(2V) man page:

     When attempting to read from a descriptor associated with an
     empty pipe, socket, FIFO, or stream:

     +  If the object the descriptor is associated with is marked
        for  4.2BSD-style  non-blocking  I/O  (with  the  FIONBIO
        ioctl() request or a call to fcntl(2V) using the  FNDELAY
        flag   from   <sys/file.h>  or  the  O_NDELAY  flag  from
        <fcntl.h> in  the  4.2BSD  environment),  the  read  will
        return -1 and errno will be set to EWOULDBLOCK.

     +  If the descriptor is marked for POSIX-style  non-blocking
        I/O   (using   fcntl()  with  the  O_NONBLOCK  flag  from
        <fcntl.h>) and refers to a stream, the read  will  return
        -1 and errno will be set to EAGAIN.

[according to my experience O_NONBLOCK works for any kind of file
 descriptor, not only streams. - RM ]

     +  If the descriptor  is  marked  for  System  V-style  non-
        blocking  I/O  (using  fcntl()  with  the FNBIO flag from
        <sys/file.h> or the O_NDELAY flag from <fcntl.h>  in  the
        System  V  environment),  and does not refer to a stream,
        the read will return 0.
	Note: this is  indistinguishable from EOF.
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

(In SunOS 5.0, O_NDELAY and O_NONBLOCK cause the same behavior
when applied to a socket fd  : both cause read(2) to set errno to EAGAIN
when no byte can be transferred. In SunOS 5.0 sockets are implemented
on top of streams.)

My opinion is that you should use O_NONBLOCK (if your system supports it)
in the interest of portability and perennity and functionality (it
work the same with pipes, sockets, ttys and pseudo-ttys).
Also it is a POSIX thing :-)

Regards,
-- 
Ronan Melennec              | Service Technique de la Navigation Aerienne
+33 1 60 79 82 40           | Departement 7
melennec@stna7.stna.dgac.fr | 95, rue Henri Rochefort, 91025 EVRY CEDEX, FRANCE