windows: Add send/recv and sendto/recvfrom wrappers supporting MSG_DONTWAIT
This commit is contained in:
parent
82fcb80276
commit
20021277f2
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue