mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-06 00:00:47 -04:00
Merge branch 'win-errno'
Improves errno handling for Winsock2 compatibility functions.
This commit is contained in:
commit
a2c2ce9693
@ -309,6 +309,66 @@ char* getpass(const char *prompt)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
#undef strerror_s
|
||||||
|
int strerror_s_extended(char *buf, size_t buflen, int errnum)
|
||||||
|
{
|
||||||
|
const char *errstr [] = {
|
||||||
|
/* EADDRINUSE */ "Address in use",
|
||||||
|
/* EADDRNOTAVAIL */ "Address not available",
|
||||||
|
/* EAFNOSUPPORT */ "Address family not supported",
|
||||||
|
/* EALREADY */ "Connection already in progress",
|
||||||
|
/* EBADMSG */ "Bad message",
|
||||||
|
/* ECANCELED */ "Operation canceled",
|
||||||
|
/* ECONNABORTED */ "Connection aborted",
|
||||||
|
/* ECONNREFUSED */ "Connection refused",
|
||||||
|
/* ECONNRESET */ "Connection reset",
|
||||||
|
/* EDESTADDRREQ */ "Destination address required",
|
||||||
|
/* EHOSTUNREACH */ "Host is unreachable",
|
||||||
|
/* EIDRM */ "Identifier removed",
|
||||||
|
/* EINPROGRESS */ "Operation in progress",
|
||||||
|
/* EISCONN */ "Socket is connected",
|
||||||
|
/* ELOOP */ "Too many levels of symbolic links",
|
||||||
|
/* EMSGSIZE */ "Message too large",
|
||||||
|
/* ENETDOWN */ "Network is down",
|
||||||
|
/* ENETRESET */ "Connection aborted by network",
|
||||||
|
/* ENETUNREACH */ "Network unreachable",
|
||||||
|
/* ENOBUFS */ "No buffer space available",
|
||||||
|
/* ENODATA */ "No message is available",
|
||||||
|
/* ENOLINK */ "No link",
|
||||||
|
/* ENOMSG */ "No message of the desired type",
|
||||||
|
/* ENOPROTOOPT */ "Protocol not available",
|
||||||
|
/* ENOSR */ "No stream resources",
|
||||||
|
/* ENOSTR */ "Not a stream",
|
||||||
|
/* ENOTCONN */ "The socket is not connected",
|
||||||
|
/* ENOTRECOVERABLE */ "State not recoverable",
|
||||||
|
/* ENOTSOCK */ "Not a socket",
|
||||||
|
/* ENOTSUP */ "Not supported",
|
||||||
|
/* EOPNOTSUPP */ "Operation not supported on socket",
|
||||||
|
/* EOTHER */ "Other error",
|
||||||
|
/* EOVERFLOW */ "Value too large to be stored in data type",
|
||||||
|
/* EOWNERDEAD */ "Previous owner died",
|
||||||
|
/* EPROTO */ "Protocol error",
|
||||||
|
/* EPROTONOSUPPORT */ "Protocol not supported",
|
||||||
|
/* EPROTOTYPE */ "Protocol wrong type for socket",
|
||||||
|
/* ETIME */ "Timeout",
|
||||||
|
/* ETIMEDOUT */ "Connection timed out",
|
||||||
|
/* ETXTBSY */ "Text file busy",
|
||||||
|
/* EWOULDBLOCK */ "Operation would block",
|
||||||
|
};
|
||||||
|
int offset = EADDRINUSE;
|
||||||
|
|
||||||
|
if (errnum < offset || errnum > offset + countof(errstr))
|
||||||
|
{
|
||||||
|
return strerror_s(buf, buflen, errnum);
|
||||||
|
}
|
||||||
|
strncpy(buf, errstr[errnum - offset], buflen);
|
||||||
|
buf[buflen - 1] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set errno for a function setting WSA error on failure
|
* Set errno for a function setting WSA error on failure
|
||||||
*/
|
*/
|
||||||
@ -316,74 +376,66 @@ static int wserr(int retval)
|
|||||||
{
|
{
|
||||||
if (retval < 0)
|
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:
|
if (map[i].wsa == wsa)
|
||||||
errno = EBADF;
|
{
|
||||||
break;
|
errno = map[i].err;
|
||||||
case WSAENETDOWN:
|
return retval;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
errno = ENOENT;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
else
|
errno = 0;
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +452,90 @@ static bool check_dontwait(int *flags)
|
|||||||
return FALSE;
|
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
|
* See header
|
||||||
*/
|
*/
|
||||||
|
@ -272,6 +272,63 @@ char* getpass(const char *prompt);
|
|||||||
#define SHUT_WR SD_SEND
|
#define SHUT_WR SD_SEND
|
||||||
#define SHUT_RDWR SD_BOTH
|
#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
|
* close(2) working for file handles and Winsock sockets
|
||||||
*/
|
*/
|
||||||
@ -304,6 +361,26 @@ ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
|
|||||||
ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
|
ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||||
const struct sockaddr *dest_addr, socklen_t addrlen);
|
const struct sockaddr *dest_addr, socklen_t addrlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declaration missing on older WinGW
|
||||||
|
*/
|
||||||
|
_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* strerror_s, but supporting POSIX compatiblity errno >= 100
|
||||||
|
*/
|
||||||
|
#define strerror_s strerror_s_extended
|
||||||
|
int strerror_s_extended(char *buf, size_t buflen, int errnum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* strerror_r(2) replacement, XSI variant
|
||||||
|
*/
|
||||||
|
static inline int strerror_r(int errnum, char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
return strerror_s(buf, buflen, errnum);
|
||||||
|
}
|
||||||
|
#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MinGW does provide extended errno values. Windows itself knowns them
|
* MinGW does provide extended errno values. Windows itself knowns them
|
||||||
* for POSIX compatibility; we define them as well.
|
* for POSIX compatibility; we define them as well.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user