Handling signals in different ways
Can anyone help me to understand what are the differences between the following three ways of handling a signal? I'm operating in a client/server in C.
Edit: I've understood that the 1st example is wrong, now I'd like to know which is better/possible, the 2nd one ore the third one? I've also read around the web that someone does a mix between them, using the "struct sigaction sig" in "sigemptyset" and "sigaddset", without any sigprocmask. Is this better than both my solutions?
Handler:
void closeSig(){
close(socketAccept);
close(socket);
exit(1);
}
1st example:
signal(SIGINT, closeSig);
2nd example:
sigset_t set;
struct sigaction sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sig.sa_mask = set;
sigaction(SIGINT, &sig, NULL);
sigprocmask(SIG_UNBLOCK, &set, NULL);
3rd example:
struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &sig, NULL);
According to POSIX sigaction()
, the function closeSig()
is not strictly a suitable callback for signals. It should be:
void closeSig(int signum);
for a regular callback, but as you're using SA_SIGINFO
, it needs to be:
void closeSig(int signum, siginfo_t *info, void *context);
You also need to look at the POSIX specification for sigprocmask()
.
Let's look at the second example:
sigset_t set;
struct sigaction sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sig.sa_mask = set;
sigaction(SIGINT, &sig, NULL);
sigprocmask(SIG_UNBLOCK, &set, NULL);
The &
on &closeSig
is unnecessary, but harmless. However, the type of closeSig()
shown in the question is wrong. The sigset_t
says that SIGINT
(only) will be blocked when the interrupt handler is called, but that would happen anyway since the flags don't include SA_NODEFER
. So, the code handling set
is superfluous to sigaction()
.
The call to sigprocmask()
unblocks interrupts ( SIGINT
). It is not clear why this is called; there would have to be some previous call to sigprocmask()
that blocked interrupts for it to make a difference. However, after this, if an interrupt is sent to the process, the closeSig()
function will be called with arguments that it does not expect.
The third example is:
struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &sig, NULL);
This is fairly close to the minimal operations described in dissecting and simplifying the second example. The main problem is that sig.sa_mask
is set to an indeterminate value. The code should be:
struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigemptyset(&sig.sa_mask);
sigaction(SIGINT, &sig, NULL);
This is now equivalent to the second example.
链接地址: http://www.djcxy.com/p/80300.html下一篇: 以不同的方式处理信号