in reply to getting data to a signal handler

We're stuck with globals for that. The only argument a handler gets is the name of the signal that fired it.

Since we don't know where in the code a handler will fire, only global variables can be relied on to be visible to the handler. It's best if they are not file-level lexicals. That produces a closure with the handlers which use them, occasionally producing hard-to-debug "features".

Added: The first section of your local perlipc is on signal handling, and is full of great tips and tricks.

After Compline,
Zaxo

Replies are listed 'Best First'.
Re^2: getting data to a signal handler
by pileofrogs (Priest) on Nov 19, 2005 at 02:52 UTC

    I figured out something that doesn't SEEM to use globals, but it probably does something much worse...

    Run this and hit CTRL-C, it will print how many seconds it thinks it's been running

    #! /usr/bin/perl -w -T use strict; my $var; ($var,$SIG{INT}) = voodoo(); sub voodoo { my $thing ; my $sub = sub { my $blob = \$thing; print $$blob."\n"; exit; }; return (\$thing,$sub); } for (my $i=0; $i<60 ;$i++) { $$var = $i; sleep 1; }

    Let me know what sort of terrible thing I've done...

      You're forming a closure on $thing, as well as returning a reference to it. voodoo() indeed!

      One nice way to pretend you don't have a global variable when you do (I've talked about this one before):

      { my $foo; sub foo () :lvalue { $foo } } foo = 'bar'; print foo, $/;
      No sigil, that makes some people happy ;-)

      After Compline,
      Zaxo

      In general, lexical closures are a handy and useful technique, but I'm not entirely sure what interesting edge cases will emerge if you combine them with signal handlers. I wouldn't care to speculate on that without understanding the nittier and grittier details of how signal handlers are handled.

      What I would do is name the global in a fashion that prevents it from ever having a namespace collision and then just leave it global. For instance, I might call it something like $SIGINT_HANDLER_GLOBAL_ONE_FOR_NET_SERVER_POP3 (if it were the first global variable for the interrupt signal handler for Net::Server::POP3; as it happens that module doesn't have any such thing, but you get the idea).