Doing homework with signals and fork and have a problem with the signal.
I’ve created the function:
void trata_sinal_int() {
char op[2];
printf("\nTerminate? (y/n)\n");
scanf("%s", op);
if (op[0] == 'y') {
printf("Bye Bye\n");
exit(0);
}
}
And in main I have:
signal(SIGINT, trata_sinal_int);
When I run this, and press CTRL ^C the function void trata_sinal_int() is called and I got the message.
If I press y program ends as expected but if I press n program still ends.
It is not returning to were he was before pressing CTRL ^C.
Is this supposed to happen?
It depends on which standard you are adhering to, but Standard C doesn’t allow you to do much more than modify a variable of type
volatile sig_atomic_tor call_Exit(orabort()orsignal()) from a signal handler. POSIX is a lot more lenient. Your code in your signal handler, replete with user interaction, is pushing beyond the limits of what even POSIX allows. Normally, you want your signal handler function to be small and svelte.Note that the signal handler function should be:
This allows you to compile without casts or compiler warnings about type mismatches.
The
signal()function may reset the signal handler back to default behaviour when it is invoked; classically, it is necessary to reinstate the signal handler inside the signal handler:So far, that’s all pretty generic and semi-trivial.
When you type the Control-C, the system does go back to roughly where it was when the signal was originally received. However, what happens next depends on where it was (one of the reasons you have to be so very careful inside the handler). For example, if it was in the middle of manipulating the free list pointers inside
malloc(), it would return there, but if you’d reinvokedmalloc()inside the handler, all hell might be breaking loose. If you were inside a system call, then your call may be interrupted (return with an error indication anderrno == EINTR), or it may resume where it left off. Otherwise, it should go back to where the calculation was running.Here’s (a fixed up version of) your code built into a test rig. The
pause()function waits for a signal before returning.I should really point out that the
scanf()is not very safe at all; a buffer of size 2 is an open invitation to buffer overflow. I’m also not error checking system calls.I tested on Mac OS X 10.7.5, a BSD derivative. The chance are good that the resetting of
signal()would be unnecessary on this platform, because BSD introduced ‘reliable signals’ a long time ago (pre-POSIX).ISO/IEC 9899:2011 §7.14.1.1 The
signalfunctionThe references to
quick_exit()are new in C2011; they were not present in C1999.POSIX 2008
The section on Signal Concepts goes through what is and is not allowed inside a signal handler under POSIX in considerable detail.