Reputation: 165
I'm writing a program where the SIGINT signal is handled the first time it is sent, but set to default after that. So, for example, I have this:
static volatile int stop_terminating = 1;
void handler(int dummy) {
stop_terminating = 0;
}
int main(){
signal(SIGINT, handler);
char input[256];
while(1){
if(stop_terminating == 0){
// reset the action of the signal to default
signal(SIGINT, SIG_DFL);
printf("Message sent.\n");
// increment counter so it doesn't enter this condition again
stop_terminating++;
}
printf("User input:\n");
fgets(input, sizeof(input), stdin);
// In this stage, I wanna press CTRL+C and print a message, stopping the fgets
// but what happens is: I press CTRL+C, the signal is catched, but fgets
// is still asking for an input, and after I send something, the my message is printed
// because it looped through the while(1) again.
}
}
How can I stop fgets from asking for an input and just print the message and then ask again for an input?
Upvotes: 2
Views: 2559
Reputation: 683
If you close stdin fgets will return immediately, then you can try to open stdin again. This is weird but can work as a workaround
Upvotes: 1
Reputation: 283614
The Linux manual page for signals says that
Interruption of system calls and library functions by signal handlers
If a signal handler is invoked while a system call or library function call is blocked, then either:
the call is automatically restarted after the signal handler returns; or
the call fails with the error
EINTR
.Which of these two behaviors occurs depends on the interface and whether or not the signal handler was established using the
SA_RESTART
flag (seesigaction
(2)).
You may use either the siginterrupt()
function together with signal()
, or use sigaction()
instead of signal()
for registering your signal handler, in order to disable restarting a read()
system call after a signal.
Note however that fgets()
from the C library might call read()
multiple times until a newline character is found, therefore you may also need to switch to using the lower-level functions instead of stdio.h
APIs.
Upvotes: 3
Reputation: 798
You get a NULL from fgets when it reaches EOF. From the keyboard, that's usually signalled with CTRL-D (Linux/Unix/MacOS X) or CTRL-Z (DOS/Windows and I think MacOS before X)
Upvotes: 0