windows: Wrap most Winsock2 Posix functions to set errno
While Winsock provides many Posix compatibility functions, they do not set errno, but use WSAGetLastError() for error reporting. The wrapped functions derive an errno from WSAGetLastError() on failure.
This commit is contained in:
parent
bc1139480f
commit
8b5d41a274
|
@ -316,74 +316,66 @@ static int wserr(int retval)
|
|||
{
|
||||
if (retval < 0)
|
||||
{
|
||||
switch (WSAGetLastError())
|
||||
static const struct {
|
||||
DWORD wsa;
|
||||
int err;
|
||||
} map[] = {
|
||||
{ WSANOTINITIALISED, EBADF },
|
||||
{ WSAENETDOWN, ENETDOWN },
|
||||
{ WSAENETRESET, ENETRESET },
|
||||
{ WSAECONNABORTED, ECONNABORTED },
|
||||
{ WSAESHUTDOWN, ECONNABORTED },
|
||||
{ WSAEACCES, EACCES },
|
||||
{ WSAEINTR, EINTR },
|
||||
{ WSAEINPROGRESS, EINPROGRESS },
|
||||
{ WSAEFAULT, EFAULT },
|
||||
{ WSAENOBUFS, ENOBUFS },
|
||||
{ WSAENOTSOCK, ENOTSOCK },
|
||||
{ WSAEOPNOTSUPP, EOPNOTSUPP },
|
||||
{ WSAEWOULDBLOCK, EWOULDBLOCK },
|
||||
{ WSAEMSGSIZE, EMSGSIZE },
|
||||
{ WSAEINVAL, EINVAL },
|
||||
{ WSAENOTCONN, ENOTCONN },
|
||||
{ WSAEHOSTUNREACH, EHOSTUNREACH },
|
||||
{ WSAENETUNREACH, ENETUNREACH },
|
||||
{ WSAECONNABORTED, ECONNABORTED },
|
||||
{ WSAECONNRESET, ECONNRESET },
|
||||
{ WSAETIMEDOUT, ETIMEDOUT },
|
||||
{ WSAEMFILE, EMFILE },
|
||||
{ WSAEALREADY, EALREADY },
|
||||
{ WSAEDESTADDRREQ, EDESTADDRREQ },
|
||||
{ WSAEISCONN, EISCONN },
|
||||
{ WSAEOPNOTSUPP, EOPNOTSUPP },
|
||||
{ WSAEPROTOTYPE, EPROTOTYPE },
|
||||
{ WSAENOPROTOOPT, ENOPROTOOPT },
|
||||
{ WSAEPROTONOSUPPORT, EPROTONOSUPPORT },
|
||||
{ WSAEPFNOSUPPORT, EPROTONOSUPPORT },
|
||||
{ WSAEAFNOSUPPORT, EAFNOSUPPORT },
|
||||
{ WSAEADDRNOTAVAIL, EADDRNOTAVAIL },
|
||||
{ WSAEADDRINUSE, EADDRINUSE },
|
||||
{ WSAETIMEDOUT, ETIMEDOUT },
|
||||
{ WSAECONNREFUSED, ECONNREFUSED },
|
||||
{ WSAELOOP, ELOOP },
|
||||
{ WSAENAMETOOLONG, ENAMETOOLONG },
|
||||
{ WSAENOTEMPTY, ENOTEMPTY },
|
||||
{ WSAEPROTOTYPE, EPROTOTYPE },
|
||||
{ WSAVERNOTSUPPORTED, ENOTSUP },
|
||||
};
|
||||
DWORD wsa, i;
|
||||
|
||||
wsa = WSAGetLastError();
|
||||
for (i = 0; i < countof(map); i++)
|
||||
{
|
||||
case WSANOTINITIALISED:
|
||||
errno = EBADF;
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
errno = ENETDOWN;
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
errno = ENETRESET;
|
||||
break;
|
||||
case WSAESHUTDOWN:
|
||||
errno = ECONNABORTED;
|
||||
break;
|
||||
case WSAEACCES:
|
||||
errno = EACCES;
|
||||
break;
|
||||
case WSAEINTR:
|
||||
errno = EINTR;
|
||||
break;
|
||||
case WSAEINPROGRESS:
|
||||
errno = EINPROGRESS;
|
||||
break;
|
||||
case WSAEFAULT:
|
||||
errno = EFAULT;
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
errno = ENOBUFS;
|
||||
break;
|
||||
case WSAENOTSOCK:
|
||||
errno = ENOTSOCK;
|
||||
break;
|
||||
case WSAEOPNOTSUPP:
|
||||
errno = EOPNOTSUPP;
|
||||
break;
|
||||
case WSAEWOULDBLOCK:
|
||||
errno = EWOULDBLOCK;
|
||||
break;
|
||||
case WSAEMSGSIZE:
|
||||
errno = EMSGSIZE;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
errno = ENOTCONN;
|
||||
break;
|
||||
case WSAEHOSTUNREACH:
|
||||
errno = EHOSTUNREACH;
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
errno = ECONNABORTED;
|
||||
break;
|
||||
case WSAECONNRESET:
|
||||
errno = ECONNRESET;
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
errno = ETIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
errno = ENOENT;
|
||||
break;
|
||||
if (map[i].wsa == wsa)
|
||||
{
|
||||
errno = map[i].err;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
errno = ENOENT;
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
}
|
||||
errno = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -400,6 +392,90 @@ static bool check_dontwait(int *flags)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef shutdown
|
||||
int windows_shutdown(int sockfd, int how)
|
||||
{
|
||||
return wserr(shutdown(sockfd, how));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef accept
|
||||
int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
return wserr(accept(sockfd, addr, addrlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef bind
|
||||
int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
return wserr(bind(sockfd, addr, addrlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef connect
|
||||
int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
return wserr(connect(sockfd, addr, addrlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef getsockname
|
||||
int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
return wserr(getsockname(sockfd, addr, addrlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef getsockopt
|
||||
int windows_getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
return wserr(getsockopt(sockfd, level, optname, optval, optlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef setsockopt
|
||||
int windows_setsockopt(int sockfd, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
return wserr(setsockopt(sockfd, level, optname, optval, optlen));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef socket
|
||||
int windows_socket(int domain, int type, int protocol)
|
||||
{
|
||||
return wserr(socket(domain, type, protocol));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
#undef select
|
||||
int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout)
|
||||
{
|
||||
return wserr(select(nfds, readfds, writefds, exceptfds, timeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
|
|
|
@ -272,6 +272,63 @@ char* getpass(const char *prompt);
|
|||
#define SHUT_WR SD_SEND
|
||||
#define SHUT_RDWR SD_BOTH
|
||||
|
||||
/**
|
||||
* shutdown(2) setting errno
|
||||
*/
|
||||
#define shutdown windows_shutdown
|
||||
int windows_shutdown(int sockfd, int how);
|
||||
|
||||
/**
|
||||
* accept(2) setting errno
|
||||
*/
|
||||
#define accept windows_accept
|
||||
int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
/**
|
||||
* bind(2) setting errno
|
||||
*/
|
||||
#define bind windows_bind
|
||||
int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* connect(2) setting errno
|
||||
*/
|
||||
#define connect windows_connect
|
||||
int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* getsockname(2) setting errno
|
||||
*/
|
||||
#define getsockname windows_getsockname
|
||||
int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
/**
|
||||
* getsockopt(2) setting errno
|
||||
*/
|
||||
#define getsockopt windows_getsockopt
|
||||
int windows_getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, socklen_t *optlen);
|
||||
|
||||
/**
|
||||
* setsockopt(2) setting errno
|
||||
*/
|
||||
#define setsockopt windows_setsockopt
|
||||
int windows_setsockopt(int sockfd, int level, int optname,
|
||||
const void *optval, socklen_t optlen);
|
||||
|
||||
/**
|
||||
* socket(2) setting errno
|
||||
*/
|
||||
#define socket windows_socket
|
||||
int windows_socket(int domain, int type, int protocol);
|
||||
|
||||
/**
|
||||
* select(2) setting errno
|
||||
*/
|
||||
#define select windows_select
|
||||
int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
/**
|
||||
* close(2) working for file handles and Winsock sockets
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue