Querying tty input with ioctl

Bob Lenk rml at hpfcdc.HP.COM
Thu Jul 21 04:54:40 AEST 1988


> Or in SysV land-
> 
> #include <fcntl.h>
> 
> int fcntl_flags = fcntl(0, F_GETFL, 0);		/* get fcntl flags */
                             ^^^^^^^
                             O_GETFL
> fcntl(0, F_SETFL, fcntl_flags | O_NDELAY);	/* set "no delay" */
           ^^^^^^^
           O_SETFL
> if (read(0, &ch, 1) > 0)			/* there's a char queued */
>     do_something();
> fcntl(0, F_SETFL, fcntl_flags);			/* unset "no delay" */
           ^^^^^^^
           O_GETFL
> 
> Read in O_NDELAY mode will return -1 of the read would block (i.e. there
                                    ^^
                                     0
> are no chars waiting in the tty queue). This allows you to check for
> pending input without causing the program to "block" waiting for input.

Note that the 0 return from read() cannot be distinguished from an
end-of-file condition.

This same code should work on a BSD system, but there are two differences
(not necessarily relevant as the code is written).  First, the return
value for no data is -1 (with errno EWOULDBLOCK) rather than 0.  Second,
on System V "no delay" mode is a property of the file descriptor (including
copies shared across fork, dup, or equivalent), while on BSD it is a
property of the terminal.

Because of this, code using the fcntl() O_NDELAY model will be more generally
portable than code using select().  The POSIX standard uses this model, but
renames O_NDELAY to O_NONBLOCK so that both flavors of system can conform
without hurting backward compatibility.

		Bob Lenk
		{ihnp4, hplabs}!hpfcla!rml
		rml%hpfcla at hplabs.hp.com



More information about the Comp.unix.questions mailing list