2010-09-28 9 views
12

Para comparar con diff registros adyacentes de un archivo, creé dos FIFOs, niños bifurcadas para abastecer a sus extremos de escritura, y capturó la salida deEn Perl, ¿cómo creo de manera segura una FIFO temporal?

diff -ub $previous $current 

donde los escalares contienen rutas especie de cómo bash process substitution los FIFO trabajos.

Este no es un programa que debe ser a prueba de balas, pero si lo fuera, ¿cómo crearía FIFO temporales para evitar race conditions y otras vulnerabilidades? Imagine File::Temp tiene un primo File::Temp::FIFO: ¿cuál sería la implementación de este último?

+0

Con sustitución proceso bash, cada proceso en la tubería es completa antes de que el 'diff' es decir,' diff <(ls $ first_directory) <(ls $ second_directory) '' cada ls 'está completo en total antes de que' diff' se ejecute en sus salidas. Está intentando hacer el mismo registro por registro ... – dawg

Respuesta

3

Suponiendo que todos los extremos del proceso están conectados a los FIFO que ha creado, ¿no puede simplemente eliminarlos del sistema de archivos? Los manejadores de archivos abiertos evitarán que se elimine el FIFO, pero no se podrán asociar nuevos identificadores, y una vez que se cierren los manejadores de archivos, el FIFO desaparecerá.

+0

En Unix, debería estar bien, no puedo responder para Windows. El otro problema que veo es 'mkfifo' seguir enlaces simbólicos incompletos? En MacOS X, tanto el comando de shell como la llamada al sistema fallan con EEXISTS. Elegir nombres aleatorios para las FIFO también debería ser de ayuda. –

+0

Mi pregunta se centra en crear los FIFO, pero esta respuesta parece asumirlos como dados. ¿Qué me estoy perdiendo? –

+0

Bueno, ¿mencionó en su pregunta que "Creé dos FIFOs"? De cualquier manera, puede crearlos con los comandos del sistema 'mkfifo' o' mknod'. – zigdon

6

¿Qué tal crear un directorio temporal (a la mkdtemp()) para evitar condiciones de carrera, y luego poner sus FIFO allí?

Por ejemplo:

use File::Temp qw(tempdir); 
use File::Spec::Functions qw(catfile); 
use POSIX qw(mkfifo); 

my $dir = tempdir(CLEANUP=>1); 
my $fifo0 = catfile($dir, "fifo0"); 
mkfifo($fifo0, 0700) or die "mkfifo($fifo0) failed: $!"; 
my $fifo1 = catfile($dir, "fifo1"); 
mkfifo($fifo1, 0700) or die "mkfifo($fifo1) failed: $!"; 

print "FIFO #0: $fifo0\n"; 
print "FIFO #1: $fifo1\n"; 
+0

¿Por qué dos directorios? Se necesita al menos el doble de limpieza. Un directorio es suficiente. –

+0

Hmmm ... Estaba siendo demasiado inteligente por mi propio bien. Tienes razón, solo es necesario un directorio temporal. –

+1

No olvide comprobar que 'tempdir' fue exitoso. –

Cuestiones relacionadas