EWOULDBLOCK эквивалентно errno под Windows Perl

G'day Stackruers,

Я являюсь автором прагмы Perl autodie, которая изменяет встроенные функции Perl для исключения при сбое. Это похоже на Fatal, но с лексической областью действия, расширяемой моделью исключений, более интеллектуальной проверкой возврата и множеством более приятных сообщений об ошибках. Это будет замена Fatal модуль в будущих выпусках Perl (предварительно 5.10.1+), но в настоящее время может быть загружен из CPAN для Perl 5.8.0 и выше.

Следующий выпуск autodie добавит специальную обработку для звонков flock с LOCK_NB (неблокирующая) опция. Пока не удалось flock вызов обычно приводит к исключению в autodie неудавшийся вызов flock с помощью LOCK_NB просто вернет false, если возвращаемое errno ($!) является EWOULDBLOCK,

Причина этого в том, что люди могут продолжать писать код вроде:

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

В приведенном выше коде блокировка не выполняется, потому что файл уже заблокирован кем-то другим (EWOULDBLOCK) не считается серьезной ошибкой, поэтому автоматическое смещение flock просто возвращает ложное значение. В ситуации, когда мы работаем с файловой системой, которая не поддерживает файловые блокировки, или с сетевой файловой системой, и сеть просто умерла, а затем автоматически умерла flock генерирует соответствующее исключение, когда видит, что наш errno не EWOULDBLOCK,

Это отлично работает в моей версии для разработчиков на Unix-системах, но в Windows происходит ужасно. Похоже, что в то время как Perl под Windows поддерживает LOCK_NB вариант, он не определяет EWOULDBLOCK, Вместо этого возвращается errno 33 ("Ошибка домена"), когда происходит блокировка.

Очевидно, я могу жестко закодировать это как константу в autodie, но это не то, что я хочу сделать здесь, потому что это означает, что я облажался, если ошибка когда-либо изменится (или изменилась). Я хотел бы сравнить его с эквивалентом Windows POSIX::EWOULDBLOCK, но я не могу за всю жизнь найти, где такая вещь будет определена. Если вы можете помочь, дайте мне знать.

Ответы, которые я специально не хочу:

  • Предложения жестко закодировать его как константу (или, что еще хуже, оставить магическое число плавающим).
  • Не поддерживает LOCK_NB функциональность вообще под виндой.
  • Предполагая, что любой отказ от LOCK_NB позвонить flock должен вернуть просто ложь.
  • Предложения, которые я спрашиваю на p5p или http://perlmonks.org/. Я уже знаю о них.
  • Объяснение того, как flock или исключения, или Fatal Работа. Я уже знаю. Тесно.

2 ответа

Решение

Под Win32 "родным" Perl, обратите внимание, что $^E более информативно на 33: "Процесс не может получить доступ к файлу, потому что другой процесс заблокировал часть файла", который ERROR_LOCK_VIOLATION (доступно из Win32:: WinError).

Для кода ошибки Windows, который вы хотите использовать $^E, В данном случае это 33: "Процесс не может получить доступ к файлу, потому что другой процесс заблокировал часть файла" (ERROR_LOCK_VIOLATION в winerror.h).

К сожалению, я не думаю, что Win32::WinError находится в ядре. С другой стороны, если Microsoft когда-нибудь перенумерует коды ошибок Windows, почти все написанные программы Windows перестанут работать, поэтому я не думаю, что возникнет проблема с ее жестким кодированием.

Другие вопросы по тегам