Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^2: How to pass CTRL-C to child script only

by ohmysea (Novice)
on Aug 23, 2010 at 14:13 UTC ( [id://856712] : note . print w/replies, xml ) Need Help??


in reply to Re: How to pass CTRL-C to child script only
in thread How to pass CTRL-C to child script only

Yes, I've tried that:

Script A:
$SIG{'INT'} = 'IGNORE';

Script B:
$SIG{'INT'} = sub { exit(0); };

With this, CTRL-C has no effect on either script.
Using die instead of exit has the same result.

Also, script B is called from script A as follows:
my $login = new CQLogin(); $login->autoLogon();
autoLogon is a subroutine in script B (CQLogin)

Thanks.

Replies are listed 'Best First'.
Re^3: How to pass CTRL-C to child script only
by lidden (Curate) on Aug 23, 2010 at 14:43 UTC
    In script A do:
    $SIG{INT} = sub { kill 2, $pid_of_scriptB;};

    Should work, not tested.

Re^3: How to pass CTRL-C to child script only
by gvenkat (Novice) on Aug 23, 2010 at 14:48 UTC

    This is still unclear, reason is, do you  fork in CQLogin? If you don't you're just  useing the module invoking a method on the instantiated object within the same process and the whole process will just terminate on Ctrl-C

      I'm just use ing the CQLogin module in script A, so in this case I cannot use kill as there is no separate PID for script B, is that correct?

      The thing is, in script B, CTRL-C will only ever be invoked during STDIN of subroutine autoLogon, so I tried to end script B during STDIN as follows:

      handler:
      my $stop = 0; $SIG{'INT'} = sub { $stop = 1 };
      during STDIN:
      print "->CQ username: "; while (<STDIN>){ if ($stop == 1){ return(0); } last; } chomp ($username = <STDIN>);
      the current problem with this is that, after pressing CTRL-C, the user will have to press the enter key again to exit script B. and if the user actually wants to pass in input, the input will need to be entered twice, but I guess I will have to work around this way for this problem.

      Thanks!
        I'm just use ing the CQLogin module in script A, so in this case I cannot use kill as there is no separate PID for script B, is that correct?
        Yes, that is correct. In the situation you have described there is no child script.

        Suggestion 1:
        Set interrupt to die, then use eval to trap the die in the code. This modification could be in either the primary module or the CQLogin module, depending on if you want to change the calling contract of the CQLogin.

        Suggestion 2:
        Use a parsing module that has already anticipated and fixed these issues.

        #!/usr/bin/perl use strict; use warnings; my $INTERRUPT_MESSAGE = "caught sig int user interrupt"; $SIG{'INT'} = sub { die $INTERRUPT_MESSAGE }; my $login = new CQLogin(); my $username = eval { $login->autoLogon() }; if ( !defined $username && $@ ) { print STDERR "wow, we got a signal\n\n"; #just for demo purpose die $@ unless $@ eq $INTERRUPT_MESSAGE; } print "Success, our username is [$username]\n\n"; #note, username will be undef if the user interrupted. package CQLogin; sub new { my $class = shift; return bless {}, $class; } sub autoLogon { my $self = shift; chomp( my $username = <STDIN> ); return $username; }
        Why don't you simply have a prompt at log-on, saying "Enter username (Q to quit)" and then test for "Q" and do what you need to do in that case?

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James