2010-09-28 14 views
12

Pour comparer avec diff enregistrements adjacents d'un fichier, j'ai créé deux FIFOs, les enfants en forme de fourche pour fournir leurs extrémités d'écriture et de capturer la sortie deEn Perl, comment créer en toute sécurité un FIFO temporaire?

diff -ub $previous $current 

où les valeurs scalaires contiennent les de FIFOs chemins nature de la façon dont bash process substitution travaux.

Ce n'est pas un programme qui doit être à l'épreuve des balles, mais si c'était le cas, comment créer des FIFO temporaires afin d'éviter race conditions et d'autres vulnérabilités? Imaginez File::Temp a un cousin File::Temp::FIFO: quelle serait la mise en œuvre de ce dernier?

+0

Avec la substitution de processus bash, chaque processus dans la conduite est terminée avant la 'diff'-à-dire,' diff <(ls first_directory de $) <(ls second_directory de $) 'chaque' ls 'est complet au total avant que' diff 'soit exécuté sur leurs sorties. Vous essayez de faire le même enregistrement par enregistrement ... – dawg

Répondre

3

En supposant que toutes les extrémités du processus sont connectées aux FIFO que vous avez créées, ne pouvez-vous pas simplement les supprimer du système de fichiers? Les handles de fichiers ouverts empêcheront la FIFO d'être supprimée, mais aucun nouveau handle ne pourra y être attaché, et une fois que les handles de fichiers existants seront fermés, le FIFO lui-même disparaîtra.

+0

Sur Unix, ça devrait aller - je ne peux pas répondre pour Windows. L'autre problème que je vois est-ce que 'mkfifo' suit des liens symboliques incomplets? Sur MacOS X, la commande shell et l'appel système échouent avec EEXISTS. Choisir des noms aléatoires pour les FIFO devrait aussi aider. –

+0

Ma question est centrée sur la création des FIFO, mais cette réponse semble les considérer comme données. Qu'est-ce que je rate? –

+0

Eh bien, vous avez mentionné dans votre question que "j'ai créé deux FIFO"? De toute façon, vous pouvez les créer avec les commandes système 'mkfifo' ou' mknod'. – zigdon

6

Que diriez-vous de créer un répertoire temporaire (a la mkdtemp()) pour éviter les conditions de course, et y mettre vos FIFO?

Par exemple:

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

Pourquoi deux répertoires? Au moins deux fois plus de nettoyage nécessaire. Un répertoire est suffisant. –

+0

Hmmm ... J'étais trop intelligent pour mon propre bien. Vous avez raison, un seul répertoire temporaire est nécessaire. –

+1

N'oubliez pas de vérifier que 'tempdir' a réussi. –

Questions connexes