Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

quiting program

by Anonymous Monk
on May 31, 2002 at 19:31 UTC ( [id://170812]=perlquestion: print w/replies, xml ) Need Help??

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

I have a part of my scripts where I want it to quit only after I type the <Ctrl> c three times instead of just once. In this part of the script if I type <Ctrl> c once it exits the scripts but I want it to exit after three times of <Ctrl> c . How would I make a global variable to store the number of times <Ctrl> c is used in this part of my script??
Here is my input part:
while (@a = <STDIN>) { print @a; }

Replies are listed 'Best First'.
Re: quiting program
by maverick (Curate) on May 31, 2002 at 19:40 UTC
    You'll need to setup a signal handler to catch the ctrl-c.
    my $num_ctrlc = 0; $SIG{'INT'} = sub { $num_ctrlc++; print "Got $num_ctrlc ctrl-c\n"; exit if $num_ctrlc > 2; }; # rest of program
    The $SIG{'INT'} part creates a signal handler for 'interrupt' (control-c) with your code. In this case, a little sub that increments a global counter, prints a message, and exists if the counter is above a certain number

    BTW, your while loop is only going to run once, since @a will contain ALL of STDIN on the first pass... Perhaps you meant something more like:

    while ($a = <STDIN>) { print $a; }
    HTH

    /\/\averick
    OmG! They killed tilly! You *bleep*!!

      your code is probably better implemented as a closure. then there's no special variable in the same scope as your code.

      { my $num_ctrlc = 0; $SIG{'INT'} = sub { print "Got " . ++$num_ctrlc . " ctrl-c\n"; exit if $num_ctrlc > 2; } }

      ~Particle *accelerates*

Re: quiting program
by vladb (Vicar) on May 31, 2002 at 19:41 UTC
    This should work:
    use strict; my $hit_count = 0; $SIG{INT} = sub { if (++$hit_count > 3) { print "terminated!\n"; exit; } print "Hit!\n"; }; while (1) { sleep(1000); }
    Here, I simply define a subroutine handler for the 'INT' signal. Inside the sub, I keep track of how many times it was initiated (<cntrl>C hit counts) and exit the program on 3rd hit! ;-)

    UPDATE: Owww.. Maverick got here first! ;-)

    UPDATE: Also I should point out that if your intent is to run a similar code on a Win OS, be cautious of the fact that the system is inherently flawed when it comes to signal handling as you know it in Unix, for example. And as crazyinsomniac kindly pointed out (in my private conversations with him :), "you shouldn't 'exit' out of a signal handler, but kill, kill"! (and I've added the exclamation mark ;-).

    _____________________
    $"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+) +-.*)$/; $_=["ps -e -o pid | "," $2 | "," -v "," "];`@$_`?{print"+ $1"}:{print" +- $1"}&&`rm $1`; print$\;}

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-22 05:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found