Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Strange SIGNAL HANDLER behavior...

by Clownburner (Monk)
on Oct 24, 2001 at 23:00 UTC ( [id://121225]=perlquestion: print w/replies, xml ) Need Help??

Clownburner has asked for the wisdom of the Perl Monks concerning the following question:

I've been doing this for a while but I'm just starting on daemon code and I thought signal handlers sounded like a good idea (it lets me close sockets and database handles, etc.) So I tried it, and got stuck right here... I've read everything I can find on signal handlers, and this looks right to me:
sub GotSignal($) { my $sig = shift; print "Got a $sig signal, exiting\n"; exit(0); } # Install signal handlers local $SIG{HUP} = 'IGNORE'; local $SIG{QUIT} = \&GotSignal('quit'); while (1) { # do stuff }
..But it doesn't work. As soon as the code hits the line where I assign a handler to $SIG{QUIT}, it runs that subroutine and exits. But if I do this:
# Install signal handlers local $SIG{HUP} = 'IGNORE'; local $SIG{QUIT} = sub { my $sig = shift; print "Got a $sig sign +al, exiting\n"; exit(0); }; while (1) { # do stuff }
The second example works as expected. This is on Linux (RH 6.2) runing perl5 (5.0 patchlevel 5 subversion 3). Anyone have any ideas? All help appreciated.
"Non sequitur. Your facts are un-coordinated." - Nomad

Replies are listed 'Best First'.
(tye)Re: Strange SIGNAL HANDLER behavior...
by tye (Sage) on Oct 24, 2001 at 23:32 UTC

    Note that Perl already passes in the name of the signal to the signal handler so simply: $SIG{QUIT}= \&GotSignal; would produce the message Got a QUIT signal, exiting so if the case of the name bothers you, another alternative would be:

    sub GotSignal { my $sig= ucfirst lc shift; print "Got a $sig signal, exiting\n"; exit(0); }

            - tye (but my friends call me "Tye")
Re: Strange SIGNAL HANDLER behavior...
by dws (Chancellor) on Oct 24, 2001 at 23:07 UTC
    The problem you're running into is that you're actually invoking your signal handler when you're setting it up. The line   local $SIG{QUIT} = \&GotSignal('quit'); is creating a reference to the result of invoking GotSignal, and assign the reference to $SIG{QUIT}. Not what you intended, but Perl is just following orders.

    One alternative to your second, working code fragment is   local $SIG{QUIT} = sub { GotSignal('quit') };

      That makes perfect sense, and is kinda what I was thinking.. But: 1) why do the Camel, Llama, and Goat all show examples like this, then? Perl Cookbook, pg 587:
      $SIG{INT} = \&got_int;
      ..and 2) Why doesn't the hard anonymous subroutine reference also execute the subroutine immediately? Doesn't this say set $SIG{QUIT} to the value returned by sub{ GotSignal('quit'} }; ??
      local $SIG{QUIT} = sub { GotSignal('quit') };
      I'm just trying to make sense of Perl's internal logic here.. Maybe that's my first mistake... ;-)
      "Non sequitur. Your facts are un-coordinated." - Nomad

        The difference is that you have parens following the sub name, which parses as a subroutine call. You can't create a reference to a sub invocation with particular arguments, you can only create a reference to a sub. If you need to set values in the sub, you'll need closures.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-03-28 20:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found