Pregunta

G'day Stackoverflowers,

Soy el autor del pragma autodie de Perl, que cambia las funciones integradas de Perl a lanzar excepciones en caso de fallo. Es similar a Fatal , pero con alcance léxico, un modelo de excepción extensible, verificación de retorno más inteligente, y muchos, mucho mejores mensajes de error. Reemplazará el módulo Fatal en futuras versiones de Perl (provisionalmente 5.10.1+), pero actualmente se puede descargar desde el CPAN para Perl 5.8.0 y superior.

La próxima versión de autodie agregará un manejo especial para las llamadas a flock con la opción LOCK_NB (sin bloqueo). Mientras que una llamada fallida de flock normalmente resultaría en una excepción en autodie , una llamada fallida a flock usando LOCK_NB simplemente devuelve false si el error devuelto ( $! ) es EWOULDBLOCK .

La razón de esto es para que las personas puedan seguir escribiendo código como:

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.
}

En el código anterior, un bloqueo que falla porque alguien más ya tiene el archivo bloqueado ( EWOULDBLOCK ) no se considera un error grave, por lo que la autodecisión de flock simplemente devuelve un valor falso. En la situación en la que estamos trabajando con un sistema de archivos que no admite bloqueos de archivos, o un sistema de archivos de red y la red acaba de morir, la autodeterminación de flock genera una excepción apropiada cuando ve que nuestro error no es EWOULDBLOCK .

Esto funciona bien en mi versión dev en sistemas con sabor Unix, pero falla horriblemente en Windows. Parece que mientras Perl bajo Windows admite la opción LOCK_NB , no define EWOULDBLOCK . En cambio, el error devuelto es 33 (" Error de dominio ") cuando se produce el bloqueo.

Obviamente, puedo codificar esto como una constante en autodie , pero eso no es lo que quiero hacer aquí, porque significa que estoy jodido si el error nunca cambia (o ha cambiado) ). Me encantaría compararlo con el equivalente de Windows de POSIX :: EWOULDBLOCK , pero por mi vida no puedo encontrar dónde se definiría tal cosa. Si puedes ayudar, házmelo saber.

Respuestas que específicamente no quiero:

  • Sugerencias para codificarlo como una constante (o, lo que es peor, dejar flotando un número mágico).
  • No es compatible con la funcionalidad LOCK_NB en Windows.
  • Suponiendo que cualquier error de una llamada LOCK_NB a rebaño debería devolver simplemente falso.
  • Sugerencias que pido en p5p o perlmonks . Ya los conozco.
  • Una explicación de cómo funciona flock , o excepciones, o Fatal . Ya lo se. Intimamente.
¿Fue útil?

Solución

Bajo Win32 " nativo " Perl, tenga en cuenta que $ ^ E es más descriptivo en 33, " El proceso no puede acceder al archivo porque otro proceso bloqueó una parte del archivo " que es ERROR_LOCK_VIOLATION (disponible en Win32 :: WinError ).

Otros consejos

Para el código de error específico de Windows, desea utilizar $ ^ E . En este caso, es 33: " El proceso no puede acceder al archivo porque otro proceso ha bloqueado una parte del archivo " ( ERROR_LOCK_VIOLATION en winerror.h ).

Desafortunadamente, no creo que Win32 :: WinError está en el núcleo . Por otro lado, si Microsoft vuelve a numerar los códigos de error de Windows, casi todos los programas de Windows que se hayan escrito dejarán de funcionar, por lo que no creo que haya un problema con la codificación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top