Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!samsung!usc!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!mahendo!jplgodo!seila!edison!don From: don@edison.UUCP (Don Kossman) Newsgroups: comp.unix.ultrix Subject: blocking read() Summary: how to make read() block? Keywords: read(), SYSTEM_FIVE, O_NDELAY Message-ID: <295@edison.UUCP> Date: 10 Nov 89 02:31:56 GMT Reply-To: don@seila.UUCP (Don Kossman) Followup-To: comp.unix.ultrix Organization: SEI Information Technology, Whittier, CA Lines: 66 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