Reputation: 11
I modified the the default action associated with the SIGINT signal by using the signal function. When I send SIGINT (type ctrl+c from keyboard) to the program for the first time,the signal handler function “handler2” works properly.But when I send SIGINT for the second time,the program exit and the signal handler function didn't work! I thought the signal handler function works again,and the program willnot exit.Why my linux signal handler run only once?
Thank you for your help!
#include "csapp.h"
void handler2(int sig)
{
int olderrno = errno;
Sio_puts("Handler in ");
Sio_putl(getpid());
Sio_puts("\n");
errno = olderrno;
}
int main()
{
if (signal(SIGINT, handler2) == SIG_ERR)
unix_error("signal error");
while (1)
{
printf("Parent %d\n", (int)getpid());
Sleep(5);
}
return 0;
}
Upvotes: 1
Views: 96
Reputation: 7345
WARNING:
the behavior of signal() varies across UNIX versions, and has also varied historically across different versions of Linux. Avoid its use: use sigaction(2) instead
In the original UNIX systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal. This is equivalent to calling sigaction(2) with the following flags:
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
System V also provides these semantics for signal().
By default, in glibc 2 and later, the signal() wrapper function does not invoke the kernel system call. Instead, it calls sigaction(2) using flags that supply BSD semantics. This default behavior is provided as long as a suitable feature test macro is defined: _BSD_SOURCE on glibc 2.19 and earlier or _DEFAULT_SOURCE in glibc 2.19 and later. (By default, these macros are defined; see feature_test_macros(7) for details.) If such a feature test macro is not defined, then signal() provides System V semantics.
In short, the behaviour of signal()
varies across UNIX systems. The only portable use is to set the disposition of a signal to SIG_DFL
or SIG_IGN
. Use sigaction(2)
instead.
And your code simply invokes undefined behaviour if it calls any async-signal-unsafe function.
A signal handler should only be setting a flag of type volatile sig_atomic_t
, unless you really know what you are doing.
Upvotes: 1