2012-07-23 16 views
5

Quiero especificar un manejador de señal en Perl, pero usando el número, no el nombre. ¿Es esto posible de una manera sucinta? La falta de simetría con la muerte sobresale particularmente. Por ejemplo, en lugar deEspecifique el manejador de señal Perl usando el número, no el nombre

$SIG{USR2} = \&myhandler; 

me gustaría decir

$SIG{12} = \&myhandler; 

lo mejor que tengo en este momento es "utilizar Config" y hurgar en Config $ {} sig_name, con base en el código en perlc perlipc. Esto es detallado y parece innecesariamente complicado.

Justificación: Lo he querido en dos casos recientemente.

1: Me está iniciando un proceso padre con errores que incorrectamente establece las señales que me importa ignorar, y quiero simplemente restablecer todo a la predeterminada. por ejemplo http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679630 El objetivo sería algo simple y la fuerza bruta como:

foreach my $i (1..32) { $SIG{$i} = 'DEFAULT'; } 

2: Estoy escribiendo un guión envoltorio delgado como invisible-como-posible. Si el programa que estoy envolviendo sale con una señal, quiero salir con la misma señal. Sin embargo, capturo algunas señales, así que tengo que borrar mi propio manejador de señal para asegurarme de que realmente salgo en lugar de ingresar a mi manejador de señal. Mi objetivo es escribir algo breve como éste:

$ret = system("./other-program"); 
$SIG{$ret & 127} = 'DEFAULT'; 
kill $ret & 127, $$; 

Respuesta

2

Primera pregunta: ¿

use Config qw(%Config); 

my @sig_name_by_num; 
@sig_name_by_num[ split(' ', $Config{sig_num}) ] = split(' ', $Config{sig_name}); 

$SIG{$sig_name_by_num[12]} = \&handler; 

Segunda pregunta:

use Config qw(%Config); 

$SIG{$_} = 'DEFAULT' for split ' ', $Config{sig_name}; 

-o-

$SIG{$_} = 'DEFAULT' for keys %SIG; 

-o-

$_ = 'DEFAULT' for values %SIG; 

Tercera pregunta

use Config qw(%Config); 

my @sig_name_by_num; 
@sig_name_by_num[ split(' ', $Config{sig_num}) ] = split(' ', $Config{sig_name}); 

my $sig_num = $? & 0x7F; 
$SIG{$sig_name_by_num[$sig_num]} = 'DEFAULT'; 
kill($sig_num => $$); 
2

Si lo que desea es establecer todas las señales a la vez, no es necesario conocer sus números:

$SIG{$_} = 'DEFAULT' for keys %SIG; 

Usando $Config{sig_name}/$Config{sig_num} es el único manera portátil para asignar números de señal a los nombres, pero de una manera rápida y sucia que funciona en muchos sistemas Unix y es

$sig_name = qx(kill -l $sig_num); 

($sig_name tendrán entonces un salto de línea final, por lo que en pra ctice que querría hacer algo así

chomp($sig_name = qx(kill -l $sig_num)); 
($sig_name) = qx(kill -l $sig_num) =~ /(\S+)/; 

)

Eso no es necesariamente más concisa que el uso de %Config, sin embargo, a menos que la convirtió en una función.

sub sig_no { chomp(my ($sig_no = qx(kill -l $_[0])); $sig_no } 

$SIG{ sig_no($ret & 127) } = 'DEFAULT'; 
... 
+0

estoy dudoso de la técnica de "teclas% SIG". Un Perl razonablemente reciente (5.12.4) recomienda ir a $ Config {sig_name}, y creo que es porque históricamente no se podía contar con Perl para poblar% SIG con señales que no había establecido personalmente. En la práctica, parece que 5.12.4 en Linux llena las claves, pero no está claro que eso sea portable en sistemas o versiones de Perl. –

Cuestiones relacionadas