Sunday, December 21, 2008

PERL: Making Ctrl+C ineffective

** Before starting, I am not responsible for the ramifications you face after running the below mentioned scripts...So be contemplative before trying these out!! **

If you have been using PERL for a long time now, you must be cognizant of the fact that, if you see your program behaving in an unexpected/bizarre way, pressing Ctrl+C would help you to stop the program execution. But did you know, you can disable this functionality. By disable, I mean that, even after pressing Ctrl+C, your program won’t stop executing. Sure, this would have kindled your thinking caps!! Let’s see how we can achieve it.

This could be easily accomplished by scripting a single line at the onset of your program.
$SIG{‘INT’} = ‘IGNORE’;
But how do you check it? For checking, try this piece of code:
$SIG{'INT'} = 'IGNORE';
@arr = (0..10);
foreach (@arr) {
print("$_\n");
sleep 1;
}
While the code snippet is getting executed, if you pres Ctrl+C, it would not stop your program.
This worked on Windows XP for me....Cool!! Isn’t it??

Let’s say, instead of ignoring Ctrl+C, you want to achieve something else when Ctrl+C is pressed. Like, say you want the program to print some message or exit. This is how it can be done:
sub INT_handler { #function starts
print("Don't Interrupt!\n");
#exit(0); - similar to print, program can be exited using exit(0)
}
$SIG{'INT'} = 'INT_handler';
@arr = (0..10);
foreach (@arr) {
print("$_\n");
sleep 1;
}
While the program execution happens, pressing Ctrl+C will print “Don’t Interrupt!”
But beware, if again Ctrl+C is pressed, the program execution stops.

This worked on Windows XP for me.

Underlying facts:
Basically Ctrl+C is a signal that is sent to the program. So when Ctrl+C sequence is pressed, a signal called INT is activated. When we say $SIG{‘INT’} = ‘IGNORE’, we basically ignore this signal and hence it doesn’t affect program execution.
Similar to INT, we have many more signals. In order to see these, you can run this code:
foreach (keys %SIG) #%SIG is actually a hash that stores all signals like %ENV that stores environment variables.
{ print " $_ \n"; } #lists all the signals supported by the platform.

You are now free to play around with these....Enjoy!!

2 comments:

Unknown said...

Coool Chetan...
Really good thing to know this.
Also helpful in the critical scripts where we can avoid the accidental hit of Ctrl+c and stopping script from execution.
--Ashok.

Anonymous said...

Thanks Ashok for the good words!! These were encouraging.. :)