Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^3: When to use sigtrap, when to assign to %SIG?

by Marshall (Canon)
on Jan 04, 2012 at 05:45 UTC ( [id://946196]=note: print w/replies, xml ) Need Help??


in reply to Re^2: When to use sigtrap, when to assign to %SIG?
in thread When to use sigtrap, when to assign to %SIG?

Easy enough to locally override $SIG{INT}, to catch Ctrl+C and rather than exiting immediately, set an $interrupt_caught variable, and then when it is safe, check $interrupt_caught and exit.

This is not the right way because you are replicating OS functionality.

The right way is to set the sigprocmask. You can use this to temporarily disable handling of a particular signal or all of them. If a signal occurs while it is blocked, that status is saved by the OS and when handling is re-enabled, it will be processed. This is called a "pending signal".

I give you some C code for a routine that I called right before exiting (while updating a critical structure). The code below didn't save the current mask for later restore, but this is the idea.

There are Perl equivalents to this. But since I haven't tested the exact code, and I might make a mistake, I will leave to the reader to research some more.

Update: see sigproc mask for the Perl way.

The basic idea is not to change "what happens" but rather to delay "what happens". This enables you to right there, in the code that does a critical action, surround it by "block" then "unblock" signal code - no other changes required.

void block_all_signals(void) /* Block 'em Danno! */ { sigset_t all; Sigfillset(&all); Sigprocmask(SIG_BLOCK, &all, NULL); return; }
Note: the capital letter forms, like Sigprocmask() instead of sigprocmask() are re-defined versions that do error processing. Handling these extremely rare, but yet important errors is important and it is too easy to forget to check the error return every time so, this technique does that.
void Sigprocmask(int how, const sigset_t *mask, sigset_t *old) { if (sigprocmask(how, mask, old) < 0) { perror("sigprocmask"); exit(1); } }
Oh, the "block 'em Danno!" comment is a nod to the Hawaii-five-O TV series. At the end to the show, the main cop always says: "Book 'em Danno" when the bad guys get arrested. I don't consider a bit of small humor in a comment to be an error - so I left it there. In this case it was the "final act" before exit.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://946196]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-25 20:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found