don@edison.UUCP (Don Kossman) (11/10/89)
environment: ultrix 3.0, microvaxII, SYSTEM_FIVE environment (cc -Y ...)
problem: read() returns 0 bytes, even though the O_NDELAY flag is NOT set.
according to the SVID spec, read() should BLOCK under these circumstances,
and return -1 or the number of bytes read. however, it seems to
return 0 if there is nothing in the read buffer. which forces my
application to poll. which is silly, and expensive on the cpu.
according to the ultrix man page:
When you use the System V environment, note the following:
+ If your program is compiled in this environment, a read
and readv system call returns 0 if the file has been
set up for non-blocking I/O and the read would block.
which i read to mean that if i'm set up for blocking I/O, it should
NOT return 0!.
is there something i don't understand here or is ultrix broken in
this respect?
i've checked the actual state of the flags with an fcntl() call,
and the O_NDELAY flag is indeed clear.
other relevant info: modem control is turned on, but carrier IS
present. the driver is in RAW mode (i'm reading/writing binary data).
i want loss of carrier to generate a hangup signal. and i want to
hangup the line on close. i have a SIGALRM handler which sets
sig_state and returns. code (much abridged) is something like:
if((tty_in = open(device,O_RDWR|O_FSYNC)) < 0)
...
if(ioctl(tty_in,TIOCGETP,&sg) == ERROR)
...
sg.sg_flags = 00000040; /* RAW mode */
if(ioctl(tty_in,TIOCSETP,&sg) == ERROR)
...
if(ioctl(tty_in,TIOCLBIC,000400) == ERROR)
...
if(ioctl(tty_in,TIOCHPCL,0) == ERROR)
...
alarm(5);
cc=read(tty_in,buf,count);
alarm(0);
switch(cc)
{
case ERROR:
if (errno == EINTR && sig_state == SIGALRM)
[handle timeout]
case 0:
[? i handle this by re-trying, but why?...]
case count:
[success- handle input]
default:
[?]
}
ok folks, what am i doing wrong??
--
------
don kossman, sei information technology, los angeles
...sun.com!suntzu!seila!don
...uunet!mahendo.jpl.nasa.gov!jplgodo!seila!don