Pergunta

G'day StackOverflowers,

Eu sou o autor do Perl do autodie pragma, que muda built-ins do Perl para lançar exceções em caso de falha. É semelhante a Fatal, mas com escopo léxico, um modelo de exceção extensível, verificação de retorno mais inteligente, e muito, mensagens de erro muito mais agradáveis. Ele vai substituir o módulo Fatal em futuras versões do Perl (provisoriamente 5.10.1+), mas atualmente pode ser descarregado a partir do CPAN para Perl 5.8.0 e acima.

O próximo lançamento do autodie irá adicionar um tratamento especial para as chamadas para flock com o LOCK_NB (non-blocking) opção. Enquanto uma chamada flock falhou normalmente resultar em uma exceção sob autodie, uma chamada não conseguiu flock usando LOCK_NB vai apenas retornar false se o errno retornado ($!) é EWOULDBLOCK.

A razão para isso é que as pessoas possam continuar a escrever 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.
}

No código acima, um bloqueio que falha porque alguém tem o arquivo já bloqueado (EWOULDBLOCK) não é considerado um erro difícil, então autodying flock meramente retorna um valor falso. Na situação que estamos trabalhando com um sistema de arquivos que não suporta arquivos de portas, ou um sistema de arquivos de rede e a rede acabou de morrer, então autodying flock gera uma exceção apropriada quando se vê que o nosso errno não é EWOULDBLOCK.

Isso funciona muito bem na minha versão dev em sistemas Unix com sabor, mas falha terrivelmente sob o Windows. Parece que, enquanto Perl no Windows suporta a opção LOCK_NB, que não define EWOULDBLOCK. Em vez disso, o errno retornado é 33 ( "erro de domínio"), quando o bloqueio poderia ocorrer.

Obviamente eu pode codificar isso como uma constante em autodie, mas não é isso que eu quero fazer aqui, porque isso significa que eu estou ferrado se o errno nunca muda (ou mudou). Gostaria muito de compará-lo com o equivalente Windows do POSIX::EWOULDBLOCK, mas eu não posso para a vida de me encontrar onde tal coisa seria definido. Se você puder ajudar, me avise.

Respostas eu especificamente não querem:

  • Sugestões para o disco de código-lo como uma constante (ou pior ainda, deixar um número mágico flutuante sobre).
  • Não suportando a funcionalidade LOCK_NB em tudo no Windows.
  • Assumindo que qualquer falha de uma chamada LOCK_NB para flock deve retornar apenas falsa.
  • As sugestões que eu peço em P5P ou PerlMonks . Eu já sei sobre eles.
  • Uma explicação de como flock, ou exceções, ou Fatal trabalho. Eu já sei. Intimamente.
Foi útil?

Solução

Em Win32 Perl, nota "nativo" que $ ^ E é mais descritivo em 33, "O processo não pode acessar o arquivo porque outro processo bloqueou parte do arquivo", que é ERROR_LOCK_VIOLATION (disponível em Win32 :: winError )

Outras dicas

Para o código de erro específico do Windows, você quer usar $^E. Neste caso, é 33: "O processo não pode acessar o arquivo porque outro processo bloqueou uma parte do arquivo" (ERROR_LOCK_VIOLATION em winerror.h)

.

Infelizmente, eu não acho que Win32 :: winError está em núcleo . Por outro lado, se a Microsoft já renumerados os códigos de erro do Windows, praticamente todos os programas do Windows já escrito iria parar de trabalhar, então eu não acho que haverá um problema com hardcoding-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top