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 a flock dovrebbe restituire semplicemente falso.
  • Suggerimenti che chiedo a p5p o perlmonks . Li conosco già.
  • Una spiegazione di come funzionano flock , o eccezioni, o Fatal . Lo so già. Intimamente.
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top