[Spread-users] [BUG][PATCH] fd to session troubles

Tim Peters tim at zope.com
Mon Feb 4 14:36:27 EST 2002


[Marc Zyngier]
>> ... More or less. In fact, it doesn't compile out of the box,
>> because of EWOULDBLOCK that doesn't exist as such on Windows.

]Jonathan Stanton]
> Ok. I think this one might also not exist on some more esoteric Unixes.

EWOULDBLOCK is POSIX, and the same thing is called EAGAIN on some older
Unices.  I've heard that there are systems where EWOULDBLOCK and EAGAIN both
exist but aren't equal, but don't know of a specific one.  I'd risk defining
EWOULDBLOCK to EAGAIN if the latter exists but the former doesn't, do an
#error if both exist but aren't equal, and use EWOULDBLOCK exclusively.

> I know using the WSA error stuff is "better" on windows,

Worse than that:  it's required, or you can have no idea what a -1 return
from a socket op on Windows means (the value of errno then isn't related to
the socket op at all).

> but isn't there at least a backwands compatible Posix errno error
> reporting that I can enable as default until everything is converted?
> It seems odd that windows has most of the posix/unix stuff (at least
> as a compatibility layer) but doesn't do error reporting the same way.

Windows was built for thread safety from the ground up, and errno isn't
threadsafe (at least not under compilers that haven't tricked errno into
being a thread-local storage gimmick -- a global vrbl shared across threads
just can't work).  That's why all the Windows APIs use an error-reporting
function instead (they're threadsafe); about the only places they use errno
is where ANSI C requires it.

One pleasant approach is to use, e.g., "s_errno" for checking errno values
after socket ops, and then

    #define s_errno WSAGetLastError()

on Windows and

    #define s_errno errno

elsewhere.  A platform-neutral set of constants to check against also needs
to be #define'd.

MS *used* to do the last part for you in winsock.h, but gave up because
conflicts with errno.h couldn't be resolved.  There's still a commented-out
block of code for this in winsock.h:

/*
 * Windows Sockets errors redefined as regular Berkeley error constants.
 * These are commented out in Windows NT to avoid conflicts with errno.h.
 * Use the WSA constants instead.
 */
#if 0
#define EWOULDBLOCK             WSAEWOULDBLOCK
#define EINPROGRESS             WSAEINPROGRESS
#define EALREADY                WSAEALREADY
#define ENOTSOCK                WSAENOTSOCK
#define EDESTADDRREQ            WSAEDESTADDRREQ
#define EMSGSIZE                WSAEMSGSIZE
#define EPROTOTYPE              WSAEPROTOTYPE
#define ENOPROTOOPT             WSAENOPROTOOPT
#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
#define EOPNOTSUPP              WSAEOPNOTSUPP
#define EPFNOSUPPORT            WSAEPFNOSUPPORT
#define EAFNOSUPPORT            WSAEAFNOSUPPORT
#define EADDRINUSE              WSAEADDRINUSE
#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
#define ENETDOWN                WSAENETDOWN
#define ENETUNREACH             WSAENETUNREACH
#define ENETRESET               WSAENETRESET
#define ECONNABORTED            WSAECONNABORTED
#define ECONNRESET              WSAECONNRESET
#define ENOBUFS                 WSAENOBUFS
#define EISCONN                 WSAEISCONN
#define ENOTCONN                WSAENOTCONN
#define ESHUTDOWN               WSAESHUTDOWN
#define ETOOMANYREFS            WSAETOOMANYREFS
#define ETIMEDOUT               WSAETIMEDOUT
#define ECONNREFUSED            WSAECONNREFUSED
#define ELOOP                   WSAELOOP
#define ENAMETOOLONG            WSAENAMETOOLONG
#define EHOSTDOWN               WSAEHOSTDOWN
#define EHOSTUNREACH            WSAEHOSTUNREACH
#define ENOTEMPTY               WSAENOTEMPTY
#define EPROCLIM                WSAEPROCLIM
#define EUSERS                  WSAEUSERS
#define EDQUOT                  WSAEDQUOT
#define ESTALE                  WSAESTALE
#define EREMOTE                 WSAEREMOTE
#endif

> ...
> About the sp.c problem, I would think there has to be a way to
> set the returned error on Windows, libraries often have to change set
> what error applications who see them will get. Maybe a WSASetError() ? :-)

Almost!  It's

    void WSASetLastError(int);

A (say) s_set_errno macro can use this to "do the right thing" so that the
s_errno macro suggested above works across boxes.

Be thankful you haven't bumped into BeOS or RISCOS yet <wink>.






More information about the Spread-users mailing list