[SOLVED] How do I watch for keyboard input without waiting in C?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How do I watch for keyboard input without waiting in C?
I have a C program that may finish in seconds or weeks depending on the data. For the longer jobs I want to be able to press a key and get an intermediate result printed.
How can I look at stdin without waiting if nothing is there?
TIA
Jim
Click here to see the post LQ members have rated as the most helpful post in this thread.
How can I look at stdin without waiting if nothing is there?
You can go multi-threads, one reading stdin while the other is doing the job. The main one could store the state of the processing in an int that the other would refer to, to print when a key is pressed.
As far as I know, getchar() will block until either a character is available, EOF happens, or an error happens. getch() will always return immediately, with either valid data or the value ERR.
--- rod.
As far as I know, getchar() will block until either a character is available, EOF happens, or an error happens. getch() will always return immediately, with either valid data or the value ERR.
--- rod.
But how can getch() spot an input if it has already returned ?
As far as I know, getchar() will block until either a character is available, EOF happens, or an error happens. getch() will always return immediately, with either valid data or the value ERR.
--- rod.
Many programs install a signal handler (typically USR1), which causes the program to save its working state or progress. Even dd does this. If you catch INT, the user can just press Ctrl+C, or use the kill command or function, to send the INT signal to the program.
If you use signals, note that you shouldn't do the output in the signal handler itself, just set a flag (a variable of type volatile sig_atomic_t). In your main loop(s), you need to periodically check the flag, and if set, clear the flag and do the output.
Nominal Animal
Last edited by Nominal Animal; 03-21-2011 at 07:32 AM.
Non-blocking keyboard input can be accomplished with the ncurses function getch().
--- rod.
It can also be achieved by manipulating the terminal attributes using a combination of tcgetattr() and tcsetattr(). ncurses probably does something similar.
Personally, I would go with the multi-thread approach, where one thread processes the data, and another (maybe even the main thread) waits for input from standard-in. The thread that waits for user input would not even have to deal with non-blocking input because when it is in a wait-state, the other thread would continue processing data.
Thanks for all the replies.
I tried getchar() and it blocked.
I will try getch() and see what happens.
I'm currently using signal. I wasn't aware of the output restriction. I will change the code and use a flag as recommended.
I like the idea of threads. It's something new for me, and probably the most efficient solution.
It can also be achieved by manipulating the terminal attributes using a combination of tcgetattr() and tcsetattr(). ncurses probably does something similar.
Undoubtedly. It is likely to know how to do it in a wide range of terminal types, and related circumstances, as well. Why not take advantage of what it does well, rather than re-invent same?
Quote:
Personally, I would go with the multi-thread approach, where one thread processes the data, and another (maybe even the main thread) waits for input from standard-in. The thread that waits for user input would not even have to deal with non-blocking input because when it is in a wait-state, the other thread would continue processing data.
How is that better than polling with a non-blocking call? (not saying it isn't; just asking). In both cases it requires a main loop to periodically poll something. In one case it will be a call to getch(), and in the other, it would have to inspect a flag of some sort (and then potentially correctly synchronize with the other thread to coordinate re-setting of the flag). Please explain.
Strictly speaking, you can do I/O from a signal handler, but only if you use the low-level unistd.h interface, not stdio.h.
The man 7 signal manpage has the list of safe library functions you can use in a signal handler, under the Async-signal-safe functions heading.
Nominal Animal
Strictly speaking, all of what you say is true. However, the OP asked how to accomplish his requirement by reading stdin. He didn't specify, but my guess is that he would like to use various different keystrokes to determine what action to take on receipt.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.