How can I read keyboard without stopping
der Mouse
mouse at mcgill-vision.UUCP
Mon Aug 15 18:09:47 AEST 1988
In article <813 at ms3.UUCP>, isns02 at ms3.UUCP (Harris Reavin) writes:
> I would like to know if it is possible to get input data from the
> keyboard while my program is constantly looping and displaying output
> to the screen. The input comes from a call to "popen()".
Now wait a minute! If you used popen(), your input is coming from
another program, and only indirectly (if at all) from the keyboard.
> I am using C, curses, and BSD4.2 on a VAX-780. I have only been able
> to enter input if the display stops for "getch()". This is not
> acceptable because I want the display to be continuous unless I am
> going to change one of the parameters.
It sounds as though you really want to read from the keyboard, so I'll
ignore the bit about popen().
I know of at least four ways to do this (read without jamming the whole
process), of varying degrees of portability and functionality.
1) Signals. Set up an alarm signal (eg, with alarm()) before doing the
read and disable it afterwards. Have the signal handler either
longjmp out or, depending on how signals interact with read on the
system in question, simply do nothing.
Good: - works nearly everywhere.
Bad: - program blocks for a while.
- if alarm() is used (as it must for portability), the
granularity of this timeout is one second.
2) Non-blocking I/O. BSD systems, and I believe recent SV systems,
support the notion of "non-blocking" reads. What this amounts to is
you make a call to turn this mode on, and then any read for which no
characters are available will return an error indication instead of
blocking.
Good: - no temporary blockage.
- reasonably widely available (I think).
Bad: - may not interact well with curses. Many programs
(and library packages) are not prepared to handle
"would block" errors.
- specifics vary from system to system.
- generally, non-blocking mode *must* be turned off or
the shell will die - so you must trap SIGBUS,
SIGSEGV, SIGINT, etc.
- requires constant polling.
3) FIONREAD. BSD systems have an ioctl you can apply to a terminal
line to get the number of characters queued available for a read().
SV may have something similar; I don't know.
Good: - no temporary blockage.
- indicates not only *whether* input is available but
also *how much* input is available.
Bad: - BSD only (as far as I know).
- requires constant polling.
4) select(). BSD systems, and some "SV with BSD extensions" systems (I
know of at least one) have the select() syscall. This allows you to
block until something is available from any one of several sources
you specify, or a timeout expires. (It is possible to wait for
other conditions as well, but I'm not trying to write a manpage for
the thing.) This is the most flexible method of the four.
Good: - full control over blockage, from a zero timeout
(polling) to infinite (blocking).
Bad: - BSD-specific, though your system may have it even if
it's primarily SV.
Pick the one you think best suits your needs. Since you're on a BSD
system, all four are available. If you aren't interested in porting to
non-BSD systems, I recommend select(). (Actually, I recommend that you
use select(), with preprocessor #if lines to select some other method
if you have to compile somewhere select() is unavailable.)
der Mouse
old: mcgill-vision!mouse
new: mouse at larry.mcrcim.mcgill.edu
More information about the Comp.unix.wizards
mailing list