Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the meaning of sigfillset? Do I really needed it in my implementation?

I have the following configuration:

static const signal_information signals_table [] =
{
    // ignored signals.

    { SIGTSTP , true , SA_RESTART , NULL },
    { SIGQUIT , true , SA_RESTART , NULL },
    { SIGINT  , true , SA_RESTART , NULL },
    { SIGTTOU , true , SA_RESTART , NULL },
    { SIGTTIN , true , SA_RESTART , NULL },
    { SIGHUP  , true , SA_RESTART , NULL },

    // non-ignored signals.

    { SIGTERM , false , SA_RESTART , signal_term_handler },
    { SIGCHLD , false , SA_RESTART | SA_NOCLDSTOP , signal_child_handler }
};

Based on this structure:

// signal information type definition.
typedef struct
{
    // the signal identifier.
    int signal;

    // flag indicating if the signal should be ignored.
    bool ignore;

    // signal action flags that will be used for the signal.
    int flags;

    // the handler of the signal.
    void (*handler) (void);
} signal_information;

And the following function which gets the configuration and installs the appropriate signals:

const bool
setup_signals_support (void)
{
    struct sigaction signal_action;

    memset (&signal_action, 0, sizeof (signal_action));

    if (sigfillset (&signal_action.sa_mask) < 0)
    {
        log_error (failed_to_initialize_signal_set_message);
        return false;
    }

    for (int i = 0; i < (sizeof (signals_table) / sizeof (signals_table[0])); i++)
    {
        signal_action.sa_flags = signals_table[i].flags;

        signal_action.sa_handler = signals_table[i].ignore ? SIG_IGN : signal_dispatcher;

        if (sigaction (signals_table[i].signal, &signal_action, NULL) < 0)
        {
            log_error ("%s '%s'.", failed_to_change_signal_action_message, strsignal (signals_table[i].signal));
            return false;
        }
    }

    return true;
}

Question 1:

What I really want to know is if the following fraction of code from the function is really necessary:

if (sigfillset (&signal_action.sa_mask) < 0)
{
    log_error (failed_to_initialize_signal_set_message);
    return false;
}

Also, I cannot understand what is the meaning of sigfillset.

Question 2:

Can I reuse the same sigaction (signal_action) for all signals or I have to create a new one for each signal configuration record inside the function? What I really want to avoid is sharing common configuration while installing signals. Each signal configuration should not affect others. Can I reuse the sigaction in such way?

Thanks.

like image 990
Efstathios Chatzikyriakidis Avatar asked Jun 24 '14 18:06

Efstathios Chatzikyriakidis


1 Answers

Question 1

'sigfillset' initializes a signal set to contain all signals. The signal set sa_mask is the set of signals that are blocked when the signal handler is being executed. So, in your case, when you are executing a signal handler all signals are blocked and you don't have to worry for another signal interrupting your signal handler. Of course, on the signals that you ignore sa_mask don't do anything.

Question 2

Yes, you can reuse the struct (changing what you want to change). The system reads all information that it needs and forgets about it so in fact you can even destroy the struct without problems (and that is what happens when you go out of scope, as it's an automatic variable).

like image 186
Mabus Avatar answered Oct 19 '22 07:10

Mabus