在Windows Perl下,EWOULDBLOCK等效的错误代码是什么?

10

你们好,Stackoverflowers:

我是Perl的autodie预处理器的作者,它可以修改Perl内置函数以便在出错时抛出异常。它类似于Fatal,但具有词法作用域、可扩展的异常模型、更智能的返回检查和更友好的错误消息。它将取代未来版本的Perl(暂定为5.10.1+)中的Fatal模块,但目前可以从CPAN下载,并且兼容Perl 5.8.0及以上版本。

autodie的下一个版本将为使用LOCK_NB(非阻塞)选项调用flock添加特殊处理。虽然在autodie下失败的flock调用通常会导致异常,但使用LOCK_NB失败的flock调用将仅在返回的errno($!)为EWOULDBLOCK时仅返回false。

这样做的原因是为了让人们可以继续编写像下面这样的代码:

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仅返回false值。 在我们使用不支持文件锁或网络文件系统并且网络刚刚断开的文件系统时,autodying flock会生成适当的异常,因为它看到我们的errno不是EWOULDBLOCK
这在我的Unix版本的开发系统上完全正常,但在Windows下却失败了。似乎在Windows下,虽然Perl支持LOCK_NB选项,但它没有定义EWOULDBLOCK。 相反,当阻塞发生时返回的errno为33(“域错误”)。
显然,我可以将其硬编码为autodie中的常量,但这不是我想在这里做的事情,因为这意味着如果errno发生变化(或已更改),我就无法解决。 我很想将其与POSIX :: EWOULDBLOCK的Windows等效项进行比较,但我无论如何都找不到定义这种东西的地方。 如果您能帮忙,请告诉我。
我明确不想要的答案:
  • 将其硬编码为常量(更糟糕的是,让一个魔数漂浮着)的建议。
  • 在Windows下根本不支持LOCK_NB功能。
  • 假设从flockLOCK_NB调用失败只应该返回false。
  • 建议我在p5p或perlmonks上询问。我已经知道它们了。
  • flock,或异常,或Fatal如何工作的说明。我已经很熟悉了。
2个回答

11

在Win32“本地”Perl中,需要注意的是$^E更具描述性,例如错误代码33,“另一个进程锁定了文件的一部分,因此无法访问该文件”,这个错误码是ERROR_LOCK_VIOLATION(可从Win32::WinError获得)。


5
对于 Windows 特定的错误码,您需要使用 $^E。在这种情况下,它是 33:“因为另一个进程锁定了文件的某个部分,所以该进程无法访问该文件”(winerror.h 中的 ERROR_LOCK_VIOLATION)。
不幸的是,我不认为核心库中包含 Win32::WinError。另一方面,如果 Microsoft 重新编号 Windows 错误代码,几乎所有已编写的 Windows 程序都将停止工作,因此我认为硬编码不会有问题。

这正是我正在寻找的!Win32::WinError不是核心模块,我并不太烦恼。如果它存在,我可以从中提取常量。如果不存在,我总是可以回退到硬编码(但不美观)的值33。再次感谢!保罗 - pjf
1
Win32::WinError很可能位于“Windows Core”中,也就是说,它是Perl Win32发行版中包含的每个模块之一(就像“libwin32”捆绑包中的所有内容一样)。 - tye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接