[SOLVED] send signal every time input comes in on stdin
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.
Problem solved, I ont only find the answer, but learn much else.
Hi guys.
how to inform OS to send a signal like SIGIO every time input comes in on stdin, I tried to use ioctl and fcntl, but both failed, so can anyone help me figure it out, thanks!
I want to write a program which sends a signal like SIGIO every time input comes in on stdin, I tried to use ioctl and fcntl, but both failed, so can anyone help me figure it out, thanks!
So long as you know how to read from stdin, all you need to complete the Astounding Chain Of Glory is kill() - see the man page in section 2, or http://linux.die.net/man/2/kill.
So long as you know how to read from stdin, all you need to complete the Astounding Chain Of Glory is kill() - see the man page in section 2, or http://linux.die.net/man/2/kill.
John G
Sorry, I wrote my question wrongly, what I mean is how to inform OS to send me a signal every time there's a input on stdion
Sorry, I wrote my question wrongly, what I mean is how to inform OS to send me a signal every time there's a input on stdion
I don't know of a way to do this, except to read standard input using getchar() or scanf() and send the signal yourself with kill().
Note that (i) scanf() is unsafe, as it pays no attention to how large a buffer you've assigned it, so if you try and read a string and the user enters a string that's too long, your data will get stomped on, and (ii) input from stdin is buffered - maybe there's a ways you can make it unbuffered, but unless you do that, you'll only get told about things on stdin when the user presses the return key.
(i) scanf() is unsafe, as it pays no attention to how large a buffer you've assigned it, so if you try and read a string and the user enters a string that's too long, your data will get stomped on
So what do you generally use to input a string? through command line argument?
Quote:
Originally Posted by JohnGraham
(ii) input from stdin is buffered - maybe there's a ways you can make it unbuffered, but unless you do that, you'll only get told about things on stdin when the user presses the return key.
Actually, command "stty raw" can disable those line-editing characters like backspace, if you have a "getchar()", then after you press a key, it will immediately be accepted as input without pressing enter. (But if you want to input a string, you still need to press enter).
how to inform OS to send a signal like SIGIO every time input comes in on stdin, I tried to use ioctl and fcntl, but both failed, so can anyone help me figure it out, thanks!
You tried fcntl with F_SETOWN, yes? That should work. Can you show a simple test program that fails?
I think the normal result is that it keeps printing "1", and when you press a key followed by return, it prints "read character ..", and then start printing "1" again.
But actually the result is it prints some "1", and then stop, waiting for you to input a chacacter, and once you input a character, it prints some "1" again, and waiting for you to input again, and this goes on and on until you terminate it by pressing 'q' or Ctrl-C.
First, you should be cautious about the library function calls you make in a signal handler. getchar()? No. exit()? No (although _exit() is ok). printf()? No.
To get a list of functions you can safely use in a signal handler, do this at the shell command prompt:
Code:
man 7 signal
... and then scroll down many, many pages.
Here are three programs which do what you want. The first is the simplest. The second, though more complex, might be more appealing because it shows the main loop's awareness of time passing. The third shows your stream of "1". The problem with that one is that it's difficult to notice the reporting of characters input, because it rapidly scrolls off the screen. You can find that reporting in the verbose "1" stream by running the whole thing within a script command, and examining the output with grep or less or vi or some other editor.
You'll notice that each is a shell script.
But before the three scripts, here is typical output of the first two.
Code:
aread character a
bread character b
cread character c
dread character d
eread character e
qgot quit request
major loop count: 2086205662
signals caught : 12
characters input: 5
Code:
11aread character a
11bread character b
111cread character c
1dread character d
1eread character e
1qgot quit request
major loop count: 32203501
signals caught : 22
characters input: 5
First, you should be cautious about the library function calls you make in a signal handler ... ...
Thanks very much for your greate responce, I learn much from it, they really work as expected. But I still have one problem, I found that the number of signals caught is larger than the number of input characters, and in the 3rd program, the difference is actually huge, and that means even if there's no keypress event, SIGIO will be sent. Then I refered to the manpage of fcntl, from which I learned that using F_SETOWN command means SIGIO will be sent whenever there's an event on the given file descriptor, so except the keypress event, what other things happened on stdin?
using F_SETOWN command means SIGIO will be sent whenever there's an event on the given file descriptor, so except the keypress event, what other things happened on stdin
When you run these scripts without redirecting the output, then stdin, stdout, and stderr are actually the same device. So the other thing that happens is that output is done. After output is done, a new event occurs to show that more output can be done without blocking.
Of course, you can't tell whether the signal is happening because input has arrived or because output is possible without blocking. Distinguishing these is the purpose of the select().
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.