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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -316,74 +376,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 +452,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
|
||||
*/
|
||||
@ -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,
|
||||
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
|
||||
* for POSIX compatibility; we define them as well.
|
||||
|
Loading…
x
Reference in New Issue
Block a user