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 перестанут работать, поэтому я не думаю, что возникнет проблема с ее жестким кодированием.