You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The pod documentation mentions lastFileError() reacting to FdGetOsFHandle(),
and File.xs indeed has code to save GetLastError() in that case. I tried
that as a workaround for issue #13. However, _get_osfhandle() does not
document GetLastError() being meaningful. Indeed, my experiments show that a
failing _get_osfhandle() can make GetLastError() return zero, among other
values. Test program:
use strict;
use warnings;
use Test::More;
use Win32API::File();
#use Socket; # changes the error codes furthermy$improbable_error_code = 15614; # ERROR_PACKAGE_REPOSITORY_CORRUPTEDmy($before, $after);
closeSTDIN;
formy$winsock_active (0, 1) {
require Socket if$winsock_active;
# fd 0 is closed but below the highest open fd# fd 100000 is closed and above the highest open fd# fd 1 is openformy$fd (0, 100000, 1) {
Win32API::File::fileLastError($improbable_error_code);
$before = 0+Win32API::File::fileLastError();
Win32API::File::FdGetOsFHandle($fd);
$after = 0+Win32API::File::fileLastError();
is($after, $before, "winsock=$winsock_active fd=$fd");
}
}
Output:
not ok 1 - winsock=0 fd=0
# Failed test 'winsock=0 fd=0'
# at //tsclient/remote/demo_closed.pl line 21.
# got: '6'
# expected: '15614'
not ok 2 - winsock=0 fd=100000
# Failed test 'winsock=0 fd=100000'
# at //tsclient/remote/demo_closed.pl line 21.
# got: '203'
# expected: '15614'
ok 3 - winsock=0 fd=1
not ok 4 - winsock=1 fd=0
# Failed test 'winsock=1 fd=0'
# at //tsclient/remote/demo_closed.pl line 21.
# got: '0'
# expected: '15614'
not ok 5 - winsock=1 fd=100000
# Failed test 'winsock=1 fd=100000'
# at //tsclient/remote/demo_closed.pl line 21.
# got: '203'
# expected: '15614'
ok 6 - winsock=1 fd=1
# Tests were run but no plan was declared and done_testing() was not seen.
I see the following ways of detecting FdGetOsFHandle() failure today, given
the need to work around issue #13 and $SUBJECT:
Test whether Perl is 32-bit. If 32-bit, compare the return value to 0xffffffff. Otherwise, compare the return value to 0xffffffffffffffff.
No known disadvantages.
Use a sequence like:
fileLastError($improbable_error_code);
FdGetOsFHandle(...);
if ($improbable_error_code == fileLastError()) { # succeeded ...
In practice, I expect _get_osfhandle() can set just a few of the thousands
of error codes, making all others viable as $improbable_error_code. Having
said that, it's infeasible to prove that GetLastError() will never report
$improbable_error_code after _get_osfhandle().
Test $!==9 (EBADF). _get_osfhandle() documents this, and I have observed
it to work. The risk would be FdGetOsFHandle() somehow making an
additional library call that clobbers errno. That risk feels significant.
I will likely use (1) for the moment.
The text was updated successfully, but these errors were encountered:
The pod documentation mentions lastFileError() reacting to FdGetOsFHandle(),
and
File.xs
indeed has code to save GetLastError() in that case. I triedthat as a workaround for issue #13. However, _get_osfhandle() does not
document GetLastError() being meaningful. Indeed, my experiments show that a
failing _get_osfhandle() can make GetLastError() return zero, among other
values. Test program:
Output:
I see the following ways of detecting FdGetOsFHandle() failure today, given
the need to work around issue #13 and $SUBJECT:
Test whether Perl is 32-bit. If 32-bit, compare the return value to
0xffffffff
. Otherwise, compare the return value to0xffffffffffffffff
.No known disadvantages.
Use a sequence like:
In practice, I expect _get_osfhandle() can set just a few of the thousands
of error codes, making all others viable as $improbable_error_code. Having
said that, it's infeasible to prove that GetLastError() will never report
$improbable_error_code after _get_osfhandle().
Test
$!==9
(EBADF
). _get_osfhandle() documents this, and I have observedit to work. The risk would be FdGetOsFHandle() somehow making an
additional library call that clobbers
errno
. That risk feels significant.I will likely use (1) for the moment.
The text was updated successfully, but these errors were encountered: