I'm using select
to do non-blocking reads from a socket and STDIN. In pseudo-code:
loop
readable = select(socket, STDIN)
foreach input in readable
if input == STDIN
handle_keyboard_input(read(STDIN))
else
handle_socket_input(read(socket))
The above works great. But now I'd like to start using libncurses to build a more sophisticated text-based UI. (I'll probably have two windows: A large log window and a smaller one for the prompt.)
Presumably, the socket handling will remain the same. But I'm unclear on how libncurses abstracts away STDIN. What is the correct idiom for doing non-blocking reads in a libncurses window?
In truth this is in Ruby, but I'm just using thin wrappers around the C APIs, so I felt this was more appropriately tagged as a C problem.
Basically, ncurses
only reads from its input stream when you call an input function such as getch
. So to that extent, ncurses
doesn't abstract away anything; all it does is to associates two file descriptors, one for input and one for output, with each SCREEN
. See man newterm
for details.
If you call nodelay
or use timeout/wtimeout
to set a timeout of 0, then getch
will immediately return an error if there is no pending input for the corresponding window. That's basically all you need to write asynchronous input handling (as far as ncurses
is concerned.) If you want to use a select
loop, you'll need to deal with the mechanics of scheduling background tasks, etc. ncurses
has rudimentary support for multi-threaded applications if you want to go that route.