CodeCumber
CodeCumber

Reputation: 45

Why won't this signal handler catch SIGHUP or SIGQUIT?

I am starting to practice handling signals and wanted to see if I can prevent the use of SIGHUP or SIGQUIT in stopping a process that was executed within the same program as the sigaction structure. But the below function doesn't seem to prevent me from sending either SIGHUP or SIGQUIT through the command line to stop the process. By typing $ kill -HUP PID# or $ kill -QUIT PID# into the command line would shut down the process. I thought by adding the signals that I want to block to the mask, it will prevent those signals from being delivered. Using sigfillset() had the same results as sigaddset(). I am using ubuntu. Thank you for the help.

Upvotes: 1

Views: 1484

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118310

We'll start by re-reading what sa_mask does, which you set with the intent to block the signals in question, however that's not exactly what that does.

From the sigaction(2) manual page:

   sa_mask  specifies  a  mask  of  signals which should be blocked (i.e.,
   added to the signal mask of the thread in which the signal  handler  is
   invoked) during execution of the signal handler.

The only thing you're blocking here are these signals while the signal handler is executing. It does absolutely nothing towards the goal of handling (or blocking) these signals in the normal course of business.

However, this is irrelevant, because:

if(execl(argv[1], argv[1], argv[2], argv[3], NULL) == -1) {

The shown code subsequently execs a new process. From the signal(7) manual page we learn what happens to signal handlers:

A child created via fork(2) inherits a copy of its parent's signal dis- positions. During an execve(2), the dispositions of handled signals are reset to the default; the dispositions of ignored signals are left unchanged.

The shown code installs a signal handler. Therefore signal handling gets restored to the default, which is process termination for SIGQUIT and SIGHUP.

Ignoring signals is not the same thing as blocking them while a signal handler is executing. To learn how to do that we go back to the sigaction(2) manual page:

sa_handler specifies the action to be associated with signum and may be SIG_DFL for the default action, SIG_IGN to ignore this signal, or a pointer to a signal handling function.

Your code chooses door #3, a signal handling function. Your code should've chosen door #2, SIG_IGN.

Upvotes: 2

Related Questions