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 de Fatal . Je sais déjà. Intimement.
Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top