windows: Add send/recv and sendto/recvfrom wrappers supporting MSG_DONTWAIT

This commit is contained in:
Martin Willi 2013-10-16 18:31:24 +02:00
parent 82fcb80276
commit 20021277f2
2 changed files with 135 additions and 0 deletions

View File

@ -97,3 +97,102 @@ int socketpair(int domain, int type, int protocol, int sv[2])
closesocket(c);
return -1;
}
/**
* Check and clear the dontwait flag
*/
static bool check_dontwait(int *flags)
{
if (*flags & MSG_DONTWAIT)
{
*flags &= ~MSG_DONTWAIT;
return TRUE;
}
return FALSE;
}
/**
* See header
*/
#undef recv
ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags)
{
u_long on = 1, off = 0;
ssize_t outlen = -1;
if (!check_dontwait(&flags))
{
return recv(sockfd, buf, len, flags);
}
if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
{
outlen = recv(sockfd, buf, len, flags);
ioctlsocket(sockfd, FIONBIO, &off);
}
return outlen;
}
/**
* See header
*/
#undef recvfrom
ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
u_long on = 1, off = 0;
ssize_t outlen = -1;
if (!check_dontwait(&flags))
{
return recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
}
if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
{
outlen = recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
ioctlsocket(sockfd, FIONBIO, &off);
}
return outlen;
}
/**
* See header
*/
#undef send
ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags)
{
u_long on = 1, off = 0;
ssize_t outlen = -1;
if (!check_dontwait(&flags))
{
return send(sockfd, buf, len, flags);
}
if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
{
outlen = send(sockfd, buf, len, flags);
ioctlsocket(sockfd, FIONBIO, &off);
}
return outlen;
}
/**
* See header
*/
#undef sendto
ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
u_long on = 1, off = 0;
ssize_t outlen = -1;
if (!check_dontwait(&flags))
{
return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
if (ioctlsocket(sockfd, FIONBIO, &on) == 0)
{
outlen = sendto(sockfd, buf, len, flags, dest_addr, addrlen);
ioctlsocket(sockfd, FIONBIO, &off);
}
return outlen;
}

View File

@ -251,6 +251,42 @@ static inline int dlclose(void *handle)
*/
int socketpair(int domain, int type, int protocol, int sv[2]);
/**
* Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT
*/
#define MSG_DONTWAIT MSG_INTERRUPT
/**
* EWOULDBLOCK is EAGAIN on other systems as well
*/
#define EWOULDBLOCK EAGAIN
/**
* recv(2) with support for MSG_DONTWAIT
*/
#define recv(...) windows_recv(__VA_ARGS__)
ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags);
/**
* recvfrom(2) with support for MSG_DONTWAIT
*/
#define recvfrom(...) windows_recvfrom(__VA_ARGS__)
ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
/**
* recvfrom(2) with support for MSG_DONTWAIT
*/
#define send(...) windows_send(__VA_ARGS__)
ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
/**
* recvfrom(2) with support for MSG_DONTWAIT
*/
#define sendto(...) windows_send(__VA_ARGS__)
ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
/* Windows does not support "ll" format printf length modifiers. Mingw
* therefore maps these to the Windows specific I64 length modifier. That
* won't work for us, as we use our own printf backend on Windows, which works