LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-25-2011, 07:10 AM   #1
CollieJim
Member
 
Registered: Mar 2005
Distribution: Gentoo, Kubuntu
Posts: 582

Rep: Reputation: 28
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.
Old 01-25-2011, 08:49 AM   #2
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
I would use the getchar() function, if that's what you are talking about.
 
Old 01-25-2011, 09:04 AM   #3
truboy
Member
 
Registered: Oct 2010
Location: Switzerland
Posts: 84

Rep: Reputation: 9
Quote:
Originally Posted by CollieJim View Post
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.
 
1 members found this post helpful.
Old 01-25-2011, 09:39 AM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Non-blocking keyboard input can be accomplished with the ncurses function getch().
--- rod.
 
1 members found this post helpful.
Old 01-25-2011, 10:25 AM   #5
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
I thought getch() is the same as getchar()?
 
Old 01-25-2011, 10:50 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.
 
1 members found this post helpful.
Old 01-25-2011, 10:56 AM   #7
truboy
Member
 
Registered: Oct 2010
Location: Switzerland
Posts: 84

Rep: Reputation: 9
Quote:
Originally Posted by theNbomr View Post
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 ?
 
Old 01-25-2011, 11:17 AM   #8
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
Quote:
Originally Posted by theNbomr View Post
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.
Got ya, thanks.
 
Old 01-25-2011, 01:09 PM   #9
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
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.
 
1 members found this post helpful.
Old 01-25-2011, 01:22 PM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by truboy View Post
But how can getch() spot an input if it has already returned ?
It can't. It is polled periodically. I believe this is the model the OP is trying to achieve.

--- rod.
 
Old 01-25-2011, 07:32 PM   #11
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by theNbomr View Post
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.
 
2 members found this post helpful.
Old 01-26-2011, 05:52 AM   #12
CollieJim
Member
 
Registered: Mar 2005
Distribution: Gentoo, Kubuntu
Posts: 582

Original Poster
Rep: Reputation: 28
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.
 
Old 01-26-2011, 12:19 PM   #13
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
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

Last edited by Nominal Animal; 03-21-2011 at 07:31 AM.
 
Old 01-26-2011, 04:46 PM   #14
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by dwhitney67 View Post
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.

--- rod.
 
Old 01-26-2011, 04:52 PM   #15
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by Nominal Animal View Post
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.

--- rod.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
timeout waiting for input during Draining Input HammerHed Linux - Newbie 1 11-01-2008 05:35 AM
Repeated "input: AT Translated Set 2 keyboard as /class/input/input" messages AcerKev Mandriva 2 09-16-2007 08:35 AM
My browser, all day today: 'waiting for linuxquestions.org...' ..waiting.. waiting .. GrapefruiTgirl LQ Suggestions & Feedback 18 05-25-2007 05:35 AM
stat=timeout waiting for input during message collect Wimpie22 Linux - Software 0 03-18-2005 02:45 PM
Sendmail: timeout waiting for input from local during Draining Input andrewstr Linux - Software 0 07-14-2004 01:43 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:38 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration