2012-05-04 6 views
6

Estoy tratando de descifrar algo que veo en la documentación perlipc.Error en la documentación perlipc?

Si está escribiendo en una tubería, también debe atrapar SIGPIPE. De lo contrario, piense en lo que ocurre cuando inicia una tubería con un comando que no existe: la apertura() tendrá éxito con toda probabilidad (solo refleja el éxito del fork()), pero luego su salida falla - espectacularmente. Perl no puede saber si el comando funcionó porque su comando realmente se está ejecutando en un proceso separado cuyo exec() podría haber fallado. Por lo tanto, mientras que los lectores de los comandos falsos devuelven solo un final rápido de archivo, los escritores con un comando falso activarán una señal que es mejor que estén preparados para manejar. Considere lo siguiente:

open(FH, "|bogus") or die "can't fork: $!"; 
    print FH "bang\n" or die "can't write: $!"; 
    close FH   or die "can't close: $!"; 

Eso no va a volar hasta el cierre, y que va a explotar con un SIGPIPE . Para atraparlo, se puede usar esto:

$SIG{PIPE} = 'IGNORE'; 
    open(FH, "|bogus") or die "can't fork: $!"; 
    print FH "bang\n" or die "can't write: $!"; 
    close FH   or die "can't close: status=$?"; 

Si estoy leyendo correctamente que, se dice que la primera versión será probablemente no morirá hasta el cierre final.

Sin embargo, eso no está sucediendo en mi caja de OS X (versiones de Perl 5.8.9 a 5.15.9). Explota en el open con un "can not fork: No such such file or directory" independientemente de si tengo o no la línea $ SIG {PIPE} allí.

¿Qué es lo que no entiendo?

+0

Creo que 'open' se modificó para informar mejor ese caso y' perlipc' no se actualizó; aún puede obtener el comportamiento documentado, pero necesita usar el mecanismo 'open (..., '| -')' más detallado. – geekosaur

+0

geekosaur: cambiar a 'abrir mi $ fh, '| -', '' falso 'o morir' da el mismo error. – Ovid

+0

Erm. Quise decir el * realmente * largo camino, donde no se especifica un comando en absoluto pero en cambio el script en sí mismo 'fork's y ejecuta' exec' en el niño. – geekosaur

Respuesta

0

misma salida en mi Perl, v5.14.2, Ubuntu 12.04:

$ perl 
    open(FH, "|bogus") or die "can't fork: $!"; 
    print FH "bang\n" or die "can't write: $!"; 
    close FH   or die "can't close: $!"; 
can't fork: No such file or directory at - line 1. 

Y ese error es extraña, ya que no tiene nada que ver con la bifurcación - deben haber añadido algo de búsqueda hacia delante de adivinar para ver si pudiera ejecutar bogus. (Lo que sería una condición carrera en el mejor, pero una probable proporcionar significativamente mejor manejo en el caso común de error;. Y sólo ser tan incómodo ya que el comportamiento de edad cuando se pierde la carrera)

+0

No necesariamente adivinando; dado que Perl ya intenta usar una búsqueda interna de 'PATH' y' exec' si no están involucrados metacaracteres de shell, ya está detectando "no encontrado" de antemano. – geekosaur

+0

@geekosaur: pero el 'falso' puede estar en el' PATH' _y ejecutable_ cuando la llamada 'execve()' eventualmente llegue. Sí, está a solo milisegundos de distancia, pero [las condiciones de carrera rara vez son tan benignas] (http://en.wikipedia.org/wiki/Time_of_check_to_time_of_use). :) – sarnold

+0

Creo que solo cuenta como una condición de carrera si estás escribiendo ese código con la expectativa específica de que fallará. – geekosaur

Cuestiones relacionadas