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

Hi there folks,

I am a complete programming newbie - and am wondering if someone here can help me with this question.

I'm writing a basic ping scanner using Net::Ping, but would like to be able to increment / decrement the timeout threshold for sending out the ICMP requests, while the program is running.
my $ping = Net::Ping->new("icmp"); if ($ping->ping($host, $threshold)) {
I have found documentation on using sigtrap to catch the signals listed from a `kill -l` and execute a code block based on that..., but how do i know which key sequences are bound to which signals at an OS level?? Or how can i define my own key-sequence traps within my shell / perl program to send signals which will be 'caught' and modify a variable?

And I guess finally, is this actually possible?? :))

I hope i've managed to explain myself properly.... heh - any help would be much appreciated. Thanks,
-jonny

Replies are listed 'Best First'.
Re: Using traps to autoincrement / decrement variables
by Fletch (Bishop) on Oct 08, 2001 at 05:21 UTC

    If you haven't already, read perldoc perlipc for information of setting up signal handlers using %SIG. The HUP, USR1, and USR2 signals are good candiates. The usual idiom is to have the handler set a flag, and then you check that flag in your main loop.

    my $reload_config = 0; $SIG{USR1} = sub { $reload_config = 1 }; ... while( $yadda_yadda_yadda ) { check_something( $something ); poll_for_widgets( $mywidgets ); if( $reload_config ) { reload_my_config( $config ); $reload_config = 0; } }

    As for sending interrupts from the keyboard, you're pretty much limited to INT, QUIT, and TSTP as far as what you can send from the keyboard with a plain tty driver. Usually stty -a will give a list of what keys will send what particular signal. For example here's what I get on Linux (YDL 2.0 PPC):

    speed 38400 baud; rows 30; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = + ^W; ...

    Ctrl-c will send SIGINT, Ctrl-\ will send SIGQUIT, and Ctrl-z sends SIGTSTP. You can't really send other signals (USR1, HUP, et al) easily from the keyboard, but you can always have your program write out its PID to a file and then use backticks in your shell to do kill -HUP `cat /var/run/myprog.pid`.

    You may also want to look into Event or POE, both of which provide ways of triggering events in your program when signals are received.

Re: Using traps to autoincrement / decrement variables
by pjf (Curate) on Oct 08, 2001 at 09:42 UTC
    Fletch's answer above already covers signals quite well, so I won't mention them here. Instead I'll present a small alternative.

    If your program is always going to be attached to a terminal of some sort (ie, it won't run in the background or as a daemon), you can use Term::ReadKey to check for individual keystrokes. For example:

    use Term::ReadKey; ReadMode 3; # cbreak mode while ($stuff) { # Ping hosts and whatnot. if (defined($key = ReadKey(-1))) { # nonblocking read $key eq 'q' && exit 0 or $key eq '+' && $foo++ or $key eq '-' && $foo--; } }
    The above code keys checks for eachstrokes and either increments or decrements $foo, or exits the program if 'q' is pressed. This is a much more user-friendly and useful way of running should you have someone seated at the keyboard.

    Cheers,
    Paul