%SIG
contiene las rutinas de manipulación de las señales.
Las claves del hash son los nombres de las señales. Así, $SIG{INT}$
contendrá el nombre de la subrutina que se ejecuta cuando se produce una interrupción
de teclado (el usuario pulsó CTRL-C
).
Supongamos que tenemos un programa que crea ciertos ficheros temporales
durante su ejecución, los cuales son borrados al final de la misma.
Si el usuario pulsa CTRL-C
, nuestro programa será interrumpido y los ficheros
temporales quedarán como restos de la ejecución inacabada. El problema se
resuelve usando un manejador de la señal de interrupción:
lhp@nereida:~/Lperl/src$ cat -n signal.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use File::Temp qw{tempdir}; 4 use Time::HiRes qw(usleep); 5 use IO::File; 6 use IO::Tee; 7 use constant W => 0.7e6; 8 9 my $n = shift || 1; 10 my $temp_dir; 11 12 sub clean_files { 13 unlink glob "$temp_dir/*"; 14 rmdir $temp_dir; 15 } 16 17 sub int_handler { 18 &clean_files; 19 die "\nPrograma interrumpido por el usuario\n"; 20 } 21 22 $temp_dir = tempdir('/tmp/pruebaXXXXX'); 23 local $SIG{INT} = \&int_handler; 24 25 my $fn = "$temp_dir/file.txt"; 26 my $F = IO::File->new(">$fn"); 27 $F->autoflush(1); 28 my $tee = IO::Tee->new(\*STDOUT, $F); 29 30 my @files; 31 for(my $i=0; $i<$n; $i++) { 32 print $tee "Printing $i in $fn. size ".(-s $fn)."\n"; 33 usleep(W); # sleep W microseconds 34 } 35 close($F); 36 37 &clean_files;La línea clave aquí es:
local $SIG{INT} = \&int_handlerque establece el manejador.
Veamos un ejemplo de ejecución:
lhp@nereida:~/Lperl/src$ signal.pl 1000 Printing 0 in /tmp/pruebahCKNU/file.txt. size 0 Printing 1 in /tmp/pruebahCKNU/file.txt. size 48 Printing 2 in /tmp/pruebahCKNU/file.txt. size 97 ^C Programa interrumpido por el usuario lhp@nereida:~/Lperl/src$ ls -l /tmp/pruebahCKNU/file.txt ls: /tmp/pruebahCKNU/file.txt: No existe el fichero o el directorio
Casiano Rodríguez León