http://qs321.pair.com?node_id=93004

crazyinsomniac has asked for the wisdom of the Perl Monks concerning the following question: (programs and processes)

I've got a commandline script, and I wanted to do some stuff before ending the program if somebody hit Ctrl^C.

I'm using ActivePerl and I've tried:

#!/usr/bin/perl -w use strict; $SIG{INT}=\&myhand; sub myhand { print "\n caught $SIG{INT}",@_,"\n"; } print "program started \n"; while(1){sleep 1;}
I need to hit Ctrl^c twice to kill the program.
If I add exit; or die; at the end of myhand, perl crashes (PERL caused an exception c0000026H in module KERNEL32.DLL at 015f:bff88510.).

How do I fix this?
I've read perlman:lib:sigtrap and I've also tried:

use sigtrap 'handler' => \&myhand, 'INT'; sub myhand { print "\n caught $SIG{INT}",@_,"\n"; } print "program started \n"; while(1){sleep 1;}
which should be the same as my first example, but it also doesn't work (same errors as before).

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I trap $SIG{INT} ( sigint aka Ctrl^c )?
by crazyinsomniac (Prior) on Jul 01, 2001 at 13:18 UTC
    Basically you need to kill yourself (the process).

    #!/usr/bin/perl -w use sigtrap 'handler' => \&myhand, 'INT'; # equivalent to $SIG{INT}=\&myhand; # use strict; # kill 6 doesn't work under strict under IndigoPerl for some reason sub myhand { print "\n caught $SIG{INT}",@_,"\n"; kill 6, $$; # ABRT = 6 # $$ is the pid of the current process } print "program started \n"; while(1) { select(undef,undef,undef,0.25);}

    Also check out perlvar(for $$), perlipc and How do I trap control characters/signals?.
    kill 6 is the equivalent of kill ABRT (thanks Vynce).

Re: How do I trap $SIG{INT} ( sigint aka Ctrl^c )?
by Anonymous Monk on Feb 26, 2003 at 16:00 UTC

    Instead of killing yourself, as suggested by crazyinsomniac, you could also try just exiting. This avoids the shell's response of 'aborted' when the program is killed. I.e.:

    sub myhand
    {
      print "\n caught $SIG{INT}",@_,"\n";
      exit(0);
    }
    

    -Josh O-

Re: How do I trap $SIG{INT} ( sigint aka Ctrl^c )?
by thayer (Sexton) on Jul 15, 2004 at 07:44 UTC
    Well, exit or die would work under unix, so switch to Linux and your life will be much better ;^)

    However, if that's not an option, then any OS will let you do something like:

    $Done = 0; sub myhand { print "Caught SIGINT\n"; $Done = 1; } ... while(1) { sleep(1); $Done && die "Time to go"; } ...
    I'd also like to warn you that if you use system, or sleep you're signal handlers may get reset for INT and ALRM respectively, so what's in the run loop may contribute to your woes... I'm not sure what Windows side-effects to look for...

    /charles

Re: How do I trap $SIG{INT} ( sigint aka Ctrl^c )?
by LH2007 (Initiate) on Oct 25, 2007 at 14:40 UTC
    How to terminate a childprocess by press Ctrl_c: Creat 2 process,P1(parent),P2(child).P1 gets characters from keyboard.If press Ctrl-C,P1 will send a signal to terminate P2.... I think,I can use a subroutine to response to Ctrl-C combination: code$SIG{INT} = \&killproc; sub tsktsk { $SIG{INT} = \&killproc; ............ } /code Please help me.Thanks

    Originally posted as a Categorized Answer.