Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is POSIX::SigSet is needed here?

!/usr/bin/env perl
use POSIX;

my $sig_set = POSIX::SigSet->new(POSIX::SIGINT);
my $sig_act = POSIX::SigAction->new(sub { print "called\n"; exit 0 },$sig_set);

POSIX::sigaction(SIGINT,$sig_act);

sleep(15);

Why do I need to use POSIX::SigSet if I already tell POSIX::sigaction that I want SIGINT?

Basically I'm trying to respond with my coderef to each of the signal I add to SigSet, looking at POSIX::sigaction signature, it must accept a singal as the first parametner, which doesnt seems reasonable to be if I already tell POSIX::SigAction about my POSIX::SigSet.

I'm sure I am missing something here.

thanks,

like image 854
snoofkin Avatar asked Aug 21 '13 14:08

snoofkin


1 Answers

The answer to your question

The POSIX::SigSet specifies additional signals to mask off (to ignore) during the execution of your signal handler sub. It corresponds to the sa_mask member of the underlying struct passed to the C version of sigaction.

Now, SIGINT (well, the first argument to sigaction) will be masked off by default, unless you explicitly request otherwise via the SA_NODEFER.

A better approach?

However, if all you want to do it to register a signal handler whose execution won't be interrupted by the signal for which it was registered (e.g., don't allow SIGINT during your SIGINT handler), you can skip the POSIX module entirely:

$SIG{INT} = sub { print "called\n"; exit 0; };  # Won't be interrupted by SIGINT

Where it can, Perl's signal dispatching emulates the traditional UNIX semantics of blocking a signal during its handler execution. (And on Linux, it certainly can. sigprocmask() is called before executing the handler, and then a scope-guard function is registered to re-allow that signal at the end of the user-supplied sub.)

like image 173
pilcrow Avatar answered Sep 26 '22 16:09

pilcrow