in reply to Re: keyboard input during runtime...
in thread keyboard input during runtime...

That is a bad idea for many reasons.

update: i'm on winblows 9x here, in case you was wonderin';)
Also, exit from a sigint handler is also a bad idea, just as bad as a die, or a warn, or anything, which doesn't actually terminate the program like a kill.

First, that is not the proper way to exit a program after capturing sigint, you gotta kill youself (i found out the hard way), like:

$SIG{INT} = \&zap; sub zap { print "You zapped me!\n"; # do some stuff # you can't die; # kill 6 which is ABRT doesn't work (crash) # under strict in indigoperl for some reason kill 15, $$; # TERM = 15, forgot where you import it from } sleep 1 while 1;
Second, because of the funky stuff that happens when you capture signals in perl, you can do a few things before killing yourself, but you can't go back into an infinite loop, cause things get pretty messed up. I was gonna suggest something like (code recycled from my personal tests):
#!/usr/bin/perl -w use strict; use sigtrap 'handler' => \&CLEANUP, 'INT'; # $SIG{INT}=\&CLEANUP; =head1 modulus (%) explained =pod Binary ``%'' computes the modulus of two numbers. Given integer opera +nds $a and $b: If $b is positive, then $a % $b is $a minus the largest multiple of $b that is not greater than $a. If $b is negative, then $a % $b is $a minus the smallest multiple of $b that is not less than $a (i.e. the result will be less than or equal to zero). =cut $|++; # i like a free flow of ideas &theloopy; sub theloopy { my($a,$b)=(0,0); while(11) { $a = '|' if(($b % 4) == 1); #| $a = '/' if(($b % 4) == 2); #/ $a = '-' if(($b % 4) == 3); #- $a = '\\' if(($b % 4) == 0); #\ print "\r $a$a$a infinite loop"; select(undef,undef,undef,0.25); # sleep $b++; } } sub CLEANUP { print "\n caught \$SIG{INT}",@_,"\n"; my $shallwedie = <STDIN>; print "shall we die (666)\n"; $shallwedie = <STDIN>; chomp $shallwedie; # $SIG{'ABRT'} = DEFAULT; # just make sure # do your cleanup stuff # and then kill yourself #kill 'ABRT', $$; # ABRT = 6 if($shallwedie eq '666') { print "the dying\n"; kill 'TERM', $$; # TERM = 15 kill 6, $$; } else { print "the loopy\n"; &theloopy(); } #exit; }
But as you can see if you run it, it does some weird things (or things i just don't understand, which might be the reason my example/strategy failed, in which case explanation is welcome ;)

update: indeed having a label, and using a goto will not work, and it will crash perl. But what's this you say about about the handler returning someplace?

Ok, it has been my experience that it returns to what your script was doing before, but another sigint will just kill the script, and i that is not desired behaviour.

So there must be some kind of sigint counter?

 
___crazyinsomniac_______________________________________
Disclaimer: Don't blame. It came from inside the void

perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Replies are listed 'Best First'.
Re: (crazyinsomniac) Re: Re: keyboard input during runtime...
by dragonchild (Archbishop) on Aug 06, 2001 at 19:00 UTC
    *laughs* If you just comment out the else-section where you call theloopy(), then you run just fine. :)

    I suspect the problem you had is that you were calling theloopy() from within the SIG{INT} handler. I tried doing a goto out, but something still keeps track that you're within the handling of a SIG{INT}, thus (I suspect) preventing the handling of another SIG{INT}. (Of course, that's pure speculation.)

    The reason why if you just let the SIG{INT} handler end if you don't want to do anything works just fine is that the handler will return back to where it was invoked from if nothing is done. I've used that to good use in other applications.

    ------
    /me wants to be the brightest bulb in the chandelier!

Re: (crazyinsomniac) Re: Re: keyboard input during runtime...
by particle (Vicar) on Feb 19, 2002 at 14:37 UTC
    i woke up this morning and had a moment of clarity. (thanks for /msging me the link here.) you need to reload the signal handler for it to work again. try this:

    #!/usr/local/bin/perl -w use strict; $|++; { # global count, closure my $count=0; # initialize count sub inc_count { ++$count } # increment count sub get_count { $count } # get count } $SIG{INT} = \&_SIGINT_; # set signal handler (CTRL-C) sub _SIGINT_ { # handle CTRL-C inc_count(); # increment global count $SIG{INT} = \&_SIGINT_; # reset signal handler (CTRL-C) }; while(1) { # infinite loop my $count = get_count(); # get the count of CTRL-C's $count % 2 # branch (just to do something) ? printf "\b\b\b\b\b\b\b\byes %2d",$count : printf "\b\b\b\b\b\b\b\b no %2d",$count; sleep 1; # take a cat nap $count >= 10 and last; # break loop (not so infinite) } print "\ndone!\n"; # et voila!
    </code> oh, and by the way, if you're running your code on windows, note that kill won't work as you think. specifically, kill will *always* abort the program, and force the exit code to the number you send. it will not send a signal to the program, like it does on unix.

    ~Particle