EWOULDBLOCK errno equivalente in Windows Perl
-
02-07-2019 - |
Domanda
G'day Stackoverflowers,
Sono l'autore del autodie di Perl, che modifica gli incorporati di Perl in generare eccezioni in caso di fallimento. È simile a Fatal , ma con ambito lessicale, un modello di eccezione estensibile, controllo del ritorno più intelligente, e messaggi di errore molto, molto più belli. Sostituirà il modulo Fatal
nelle versioni future di Perl (provvisoriamente 5.10.1+), ma attualmente può essere scaricato dal CPAN per Perl 5.8.0 e versioni successive.
La prossima versione di autodie
aggiungerà una gestione speciale per le chiamate a flock
con l'opzione LOCK_NB
(non bloccante). Mentre una chiamata flock
non riuscita genererebbe normalmente un'eccezione in autodie
, una chiamata non riuscita a flock
utilizzando LOCK_NB
restituisce semplicemente false se l'errore restituito ( $!
) è EWOULDBLOCK
.
Il motivo è che le persone possono continuare a scrivere codice come:
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.
}
Nel codice sopra, un blocco che fallisce perché qualcun altro ha già il file bloccato ( EWOULDBLOCK
) non è considerato un errore grave, quindi autodire flock
semplicemente restituisce un valore falso. Nella situazione in cui stiamo lavorando con un filesystem che non supporta i file-lock, o un filesystem di rete e la rete è appena morta, l'autodiffusione di flock
genera un'eccezione appropriata quando vede che il nostro errno non è EWOULDBLOCK
.
Funziona bene nella mia versione di sviluppo su sistemi basati su Unix, ma fallisce orribilmente sotto Windows. Sembra che mentre Perl in Windows supporta l'opzione LOCK_NB
, non definisce EWOULDBLOCK
. Invece, l'errno restituito è 33 (" Errore di dominio ") quando si verificherebbe un blocco.
Ovviamente posso codificare questo come costante in autodie
, ma non è quello che voglio fare qui, perché significa che sono fregato se l'errno cambia (o è cambiato) ). Mi piacerebbe confrontarlo con l'equivalente di Windows di POSIX :: EWOULDBLOCK
, ma per la vita non riesco a trovare dove sarebbe definita una cosa del genere. Se puoi aiutare, fammi sapere.
Risposte che in particolare non desidero:
- Suggerimenti per codificarlo come una costante (o peggio ancora, lasciare fluttuare un numero magico).
- Non supporta la funzionalità
LOCK_NB
in Windows. - Supponendo che qualsiasi errore da una chiamata
LOCK_NB
aflock
dovrebbe restituire semplicemente falso. - Suggerimenti che chiedo a p5p o perlmonks . Li conosco già.
- Una spiegazione di come funzionano
flock
, o eccezioni, oFatal
. Lo so già. Intimamente.
Soluzione
In Win32 " native " Perl, nota che $ ^ E è più descrittivo a 33, "Il processo non può accedere al file perché un altro processo ha bloccato una parte del file " che è ERROR_LOCK_VIOLATION
(disponibile da Win32 :: WinError ).
Altri suggerimenti
Per il codice di errore specifico di Windows, si desidera utilizzare $ ^ E
. In questo caso, è 33: " Il processo non può accedere al file perché un altro processo ha bloccato una parte del file " ( ERROR_LOCK_VIOLATION
in winerror.h
).
Sfortunatamente, non credo che Win32 :: WinError è fondamentale . D'altra parte, se Microsoft avesse mai rinumerato i codici di errore di Windows, praticamente tutti i programmi Windows mai scritti smetterebbero di funzionare, quindi non credo che ci sarà un problema con la sua codifica.