Windows Perl 下的 EWOULDBLOCK 等效 errno
-
02-07-2019 - |
题
你好,Stackoverflowers,
我是 Perl 的作者 自动模具 pragma,它将 Perl 的内置函数更改为在失败时抛出异常。它类似于 致命的, ,但具有词法作用域、可扩展的异常模型、更智能的返回检查以及更好的错误消息。它将取代 Fatal
Perl 的未来版本(暂定为 5.10.1+)中包含该模块,但目前可以从 Perl 5.8.0 及更高版本的 CPAN 下载。
下一个版本 autodie
将为调用添加特殊处理 flock
与 LOCK_NB
(非阻塞)选项。虽然一次失败 flock
调用通常会导致异常 autodie
, ,失败的调用 flock
使用 LOCK_NB
如果返回的 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 下却严重失败。看起来虽然 Windows 下的 Perl 支持 LOCK_NB
选项,它没有定义 EWOULDBLOCK
. 。相反,当发生阻塞时,返回的 errno 是 33(“域错误”)。
显然我可以将其硬编码为常量 autodie
, ,但这不是我想要在这里做的,因为这意味着如果 errno 改变(或已经改变),我就完蛋了。我很想将它与 Windows 的等效项进行比较 POSIX::EWOULDBLOCK
, ,但我一生都找不到定义这样的事情的地方。如果你能帮忙,请告诉我。
我特别不想要的答案:
- 建议将其硬编码为常量(或者更糟糕的是,留下一个浮动的幻数)。
- 不支持
LOCK_NB
Windows 下的所有功能。 - 假设任何故障来自
LOCK_NB
拨电至flock
应该仅返回 false。 - 我在 p5p 或 上询问的建议 佩尔蒙克斯. 。我已经了解他们了。
- 如何解释
flock
, ,或例外,或Fatal
工作。我已经知道了。亲密地。
解决方案
在 Win32“本机”Perl 下,请注意 $^E 在 33 处更具描述性,“该进程无法访问该文件,因为另一个进程锁定了该文件的一部分”,即 ERROR_LOCK_VIOLATION
(可从 Win32::Win错误).
其他提示
对于 Windows 特定的错误代码,您需要使用 $^E
. 。在本例中,它是 33:“该进程无法访问该文件,因为另一个进程已锁定该文件的一部分”(ERROR_LOCK_VIOLATION
在 winerror.h
).
不幸的是,我不认为 Win32::Win错误 是在核心。另一方面,如果微软重新编号 Windows 错误代码,几乎所有编写的 Windows 程序都会停止工作,所以我认为对其进行硬编码不会有问题。