EWOULDBLOCK equivalent errno sous Windows Perl
-
02-07-2019 - |
Question
G'day Stackoverflowers,
Je suis l'auteur du autodie pragma de Perl, qui modifie les paramètres intégrés de Perl en jeter des exceptions en cas d'échec. Il est similaire à Fatal , mais avec une portée lexicale, un modèle d'exception extensible, un contrôle de retour plus intelligent, et beaucoup, beaucoup plus gentils messages d'erreur. Il remplacera le module Fatal
dans les prochaines versions de Perl (provisoirement à la version 5.10.1+), mais peut actuellement être téléchargé à partir du réseau CPAN pour Perl 5.8.0 et les versions ultérieures.
La prochaine version de autodie
ajoutera une gestion spéciale des appels à flock
avec l'option LOCK_NB
(non bloquant). Alors qu'un appel flock
ayant échoué entraînerait normalement une exception sous autodie
, un appel ayant échoué à flock
à l'aide de LOCK_NB
renvoie simplement false si le code d'erreur renvoyé ( $!
) est EWOULDBLOCK
.
La raison en est que les gens peuvent continuer à écrire du code tel que:
use Fcntl qw(:flock);
use autodie; # All perl built-ins now succeed or die.
open(my $fh, '<', 'some_file.txt');
my $lock = flock($fh, LOCK_EX | LOCK_NB); # Lock the file if we can.
if ($lock) {
# Opportuntistically do something with the locked file.
}
Dans le code ci-dessus, un verrou qui échoue parce que le fichier est déjà verrouillé par une autre personne ( EWOULDBLOCK
) n'est pas considéré comme une erreur irréversible. Par conséquent, le code automatique flock
renvoie une fausse valeur. Dans le cas où nous travaillons avec un système de fichiers qui ne prend pas en charge les verrous de fichiers, ou un système de fichiers réseau et le réseau vient de disparaître, le code automatique flock
génère une exception appropriée lorsqu'il constate que notre code d'erreur n'est pas EWOULDBLOCK
.
Cela fonctionne très bien dans ma version de développement sur les systèmes Unix, mais il échoue horriblement sous Windows. Il semble que si Perl sous Windows prend en charge l'option LOCK_NB
, il ne définit pas EWOULDBLOCK
. Au lieu de cela, le code d'erreur renvoyé est 33 ("Erreur de domaine") lors du blocage.
Évidemment, je peux coder ceci en tant que constante dans autodie
, mais ce n'est pas ce que je veux faire ici, car cela signifie que je suis foutu si l'errno change un jour (ou a changé ). J'aimerais bien le comparer à l'équivalent Windows de POSIX :: EWOULDBLOCK
, mais je ne peux pas pour la vie de moi trouver où une telle chose serait définie. Si vous pouvez aider, faites le moi savoir.
Réponses que je ne veux surtout pas:
- Il est suggéré de le coder en tant que constante (ou pire, laissez un nombre magique en suspens).
- Ne prend pas en charge la fonctionnalité
LOCK_NB
sous Windows. - En supposant que tout échec d'un appel
LOCK_NB
àflock
ne renvoie que faux. - Suggestions que je pose sur p5p ou perlmonks . Je sais déjà à leur sujet.
- Explication du fonctionnement de
flock
, des exceptions ou deFatal
. Je sais déjà. Intimement.
La solution
Sous Win32 " native " Perl, notez que $ ^ E est plus descriptif en 33, "Le processus ne peut pas accéder au fichier car un autre processus a verrouillé une partie du fichier". qui est ERROR_LOCK_VIOLATION
(disponible à partir de Win32 :: WinError . ).
Autres conseils
Pour le code d'erreur spécifique à Windows, vous souhaitez utiliser $ ^ E
. Dans ce cas, il s’agit du 33: "Le processus ne peut pas accéder au fichier car un autre processus a verrouillé une partie du fichier". ( ERROR_LOCK_VIOLATION
dans winerror.h
).
Malheureusement, je ne pense pas que Win32 :: WinError soit au cœur . Par contre, si Microsoft renumérotait jamais les codes d’erreur Windows, pratiquement tous les programmes Windows jamais écrits cesseraient de fonctionner. Je ne pense donc pas que le codage en dur posera problème.