2010-02-09 7 views
0

Les descripteurs de fichiers sont-ils pris en charge sous Windows? Pourquoi les choses "semblent-elles fonctionner" dans Perl avec fds?Comment les descripteurs de fichiers Perl fonctionnent-ils sous Windows?

Des choses comme "fileno", "dup" et "dup2" fonctionnaient, mais aléatoirement dans un autre environnement, ont cessé de fonctionner. Il est difficile de donner des détails, la plupart du temps ce que je cherche, ce sont des réponses de programmeurs Windows expérimentés et comment les descripteurs de fichiers fonctionnent/ne fonctionnent pas sous Windows.

Je suppose que c'est la couche PerlIO qui joue à des jeux et donne l'impression que les descripteurs de fichiers fonctionnent, mais ce n'est qu'une supposition.

Exemple de ce qui se passe:

open($saveout, ">&STDOUT") or die(); 
... 
open(STDOUT, ">&=".fileno($saveout)) or die(); 

La deuxième matrice de ligne() s, mais seulement dans certaines situations (que je n'ai pas encore clouer).

+1

Pourriez-vous donner * quelques * informations sur ce que vous faites qui ne fonctionne pas? Un exemple minimal, indiquant où les choses vont mal, rendrait beaucoup plus facile de fournir des commentaires. – jamessan

Répondre

1

Windows utilise les descripteurs de fichiers de manière native. Voir Low-Level I/O sur MSDN. Ils signalent tous des erreurs via la variable C errno, ce qui signifie qu'ils apparaissent dans le $! de Perl.

Notez que vous pouvez vous épargner un peu de taper:

open(STDOUT, ">&=", $saveout) or ...; 

Cela fonctionne parce que le documentation for open in perlfunc fournit:

Si vous utilisez le formulaire 3-arg vous pouvez passer un nombre , le nom d'un descripteur de fichier ou la « référence à un glob. » normal

Enfin, toujours inclure des diagnostics significatifs lorsque vous appelez die! Le programme ci-dessous s'identifie ($0), indique ce qu'il essayait de faire (open), et pourquoi il a échoué ($!). En outre, comme le message ne se termine pas par un saut de ligne, die ajoute le nom du fichier et le numéro de ligne où il a été appelé.

my $fakefd = 12345; 
open(STDOUT, ">&=", $fakefd) or die("$0: open: $!"); 

Ce produit

prog.pl: open: Bad file descriptor at foo.pl line 2.

Selon le documentation for _fdopen (parce que vous avez utilisé >&= et non >&), il dispose de deux modes de défaillance:

Si l'exécution est autorisée à continuer, errno est défini sur EBADF, indiquant un mauvais descripteur de fichier, ou EINVAL, indiquant que le mode était un pointeur nul.

Le second serait un bug dans perl et très peu probable parce que je ne vois nulle part dans perlio.c qui implique un mode calculé: ils sont toutes les chaînes statiques. Un problème semble avoir mal tourné avec $saveout. Est-ce que $saveout a été fermé avant que vous essayiez de le restaurer? De votre exemple, il n'est pas clair si vous avez activé le pragma strict. Si ce n'est pas lexical (déclaré avec my), appelez-vous une fonction qui singe aussi avec $saveout?

Questions connexes