windows: Add send/recv and sendto/recvfrom wrappers supporting MSG_DONTWAIT
This commit is contained in:
@@ -97,3 +97,102 @@ int socketpair(int domain, int type, int protocol, int sv[2])
|
|||||||
closesocket(c);
|
closesocket(c);
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -251,6 +251,42 @@ static inline int dlclose(void *handle)
|
|||||||
*/
|
*/
|
||||||
int socketpair(int domain, int type, int protocol, int sv[2]);
|
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
|
/* Windows does not support "ll" format printf length modifiers. Mingw
|
||||||
* therefore maps these to the Windows specific I64 length modifier. That
|
* 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
|
* won't work for us, as we use our own printf backend on Windows, which works
|
||||||
|
|||||||
Reference in New Issue
Block a user