develooper Front page | perl.perl5.porters | Postings from February 2016

Putting Winsock errors into $^E

Thread Next
From:
Steve Hay via perl5-porters
Date:
February 17, 2016 08:59
Subject:
Putting Winsock errors into $^E
Message ID:
CADED=K4B4Y9yMsnfE+qt6hO+xv2W+kfT2UfBoy5VPT3Tw4Kwsw@mail.gmail.com
Nearly a year ago there was some discussion about the way in which
perl handles errors from socket functions on Windows:

http://nntp.perl.org/group/perl.perl5.porters/226581
http://nntp.perl.org/group/perl.perl5.porters/226793
http://nntp.perl.org/group/perl.perl5.porters/226604

There were two main issues:

One was some minor breakage caused by checking for a hard-coded
Winsock error code (10035) instead of a POSIX error constant
(EWOULDBLOCK) which they are mapped to. The values placed in $!
changed in 5.20.0 to incorporate the same mapping of WSAE* values to
E* that had long been in effect since 5.8 in Errno.pm and 5.12 in
POSIX.pm. This was done to avert some problems caused by the addition
of new POSIX error constants in the errno.h of VC10+ and recent gccs.
The danger of breakage for anyone using hard-coded error codes was
documented in 5.20.0's perldelta:

http://perldoc.perl.org/perl5200delta.html#Assignments-of-Windows-sockets-error-codes-to-%24!-now-prefer-_errno.h_-values-over-WSAGetLastError%28%29-values

The second, more significant, issue is the fact that this old mapping,
despite many other languages apparently having similar code in them
(e.g. similar code was found in each of Python, Ruby, Tcl and PHP), is
not good because some similarly-named constants do not have compatible
meanings (e.g. EINPROGRESS indicates that a non-blocking connection
could not be immediately established and will instead be established
asynchronously, whereas WSAEINPROGRESS indicates that a blocking
operation (which Winsock only allows a single one of per-task or
thread) is currently executing. In fact, WSAEWOULDBLOCK matches
EINPROGRESS far better than WSAEINPROGRESS does).

The most robust solution that was put forward (myself, Leon and Sinan
all suggested it) to solve the various issues with defining/exporting
error constants and mapping/setting error codes in $! was to simply
forget about $! and POSIX error codes for Winsock functions, and
instead just set the Winsock error code directly into $^E.

I therefore propose to leave the whole $! thing as it is now, put the
Winsock error codes into $^E after each Winsock function call, export
the WSAE* error constants from Errno.pm and POSIX.pm for checking
those error codes against and henceforth encourage people to test $^E
(against WSAE* constants) rather than $! (against E* constants) on
Windows from 5.24.0 onwards.

I have made the necessary code changes in the top three commits on this branch:

http://perl5.git.perl.org/perl.git/shortlog/refs/heads/smoke-me/steveh/oserror

This works for me, and has smoked as cleanly as seems to be normal:

http://perl.develop-help.com/?b=smoke-me/steveh/oserror

I would like to commit this before the "user-visible changes freeze"
on 20th, and will do so if no objections are raised. I will, of
course, add some appropriate documentation (in perldelta and
elsewhere) too.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About