Windows Perl下的EWOULDBLOCK等效errno

时间:2020-03-06 14:42:13  来源:igfitidea点击:

G'day Stackoverflowers,

我是Perl的autodie pragma的作者,该文件更改了Perl的内置函数以在失败时引发异常。它类似于致命的,但具有词法作用域,可扩展的异常模型,更智能的返回检查以及好得多的错误消息。它会在Perl的将来版本(临时为5.10.1+)中替代"致命"模块,但目前可以从CPAN下载Perl 5.8.0及更高版本。

下一个版本的autodie将使用LOCK_NB(非阻塞)选项为对flock的调用添加特殊处理。尽管失败的flock调用通常会在autodie下导致异常,但是如果返回的errno($!)为EWOULDBLOCK,则使用LOCK_NB失败的对flock的调用只会返回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"操作只会返回一个假值。在我们正在使用不支持文件锁的文件系统或者网络文件系统且网络刚刚死机的情况下,当看到我们的errno不是EWOULDBLOCK'时,自动执行flock`会生成适当的异常。 。

在Unix风格的系统上,在我的dev版本中,该功能正常工作,但是在Windows下,它却严重失败。看起来,虽然Windows下的Perl支持LOCK_NB选项,但它没有定义EWOULDBLOCK。而是在发生阻塞时返回的错误号为33("域错误")。

显然,我可以将其硬编码为一个常量到autodie中,但这不是我要在此处执行的操作,因为这意味着如果errno发生更改(或者已更改),我就会感到困惑。我想将其与Windows的POSIX :: EWOULDBLOCK进行比较,但是我一生无法找到在哪里定义这样的东西。如果我们可以提供帮助,请告诉我。

我特别不想要的答案:

  • 建议将其硬编码为一个常数(或者更糟糕的是,留下一个不可思议的数字)。
  • Windows下根本不支持LOCK_NB功能。
  • 假设从LOCK_NB调用到flock的任何失败应该只返回false。
  • 我对p5p或者perlmonks提出的建议。我已经知道了。
  • 关于"群",异常或者"致命"工作方式的说明。我已经知道了亲密地。

解决方案

在Win32"本机" Perl下,请注意$ ^ E在33处更具描述性,"该进程无法访问文件,因为另一个进程锁定了文件的一部分",即ERROR_LOCK_VIOLATION(可从Win32 :: WinError获得)。

对于Windows特定的错误代码,我们想使用$$ E。在这种情况下,值为33:"该进程无法访问文件,因为另一个进程已锁定了文件的一部分"(winerror.h中的ERROR_LOCK_VIOLATION)。

不幸的是,我不认为Win32 :: WinError是核心。另一方面,如果Microsoft重新编号Windows错误代码,几乎所有曾经编写的Windows程序都会停止工作,因此我认为对其进行硬编码不会有问题。