]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
windows: Add send/recv and sendto/recvfrom wrappers supporting MSG_DONTWAIT
authorMartin Willi <martin@revosec.ch>
Wed, 16 Oct 2013 16:31:24 +0000 (18:31 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Jun 2014 13:52:59 +0000 (15:52 +0200)
src/libstrongswan/utils/windows.c
src/libstrongswan/utils/windows.h

index a519b3b0de9ea4fc1b3354f97da00fe04a6a71fd..06e0f82958b5e7e7b71a8eb910e3a351ed451b3f 100644 (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;
+}
index 23a6666c47a44d226ac83e195a4f4cd50be9ea69..9761c068aaf12fdee195b89010fcf50c6ee46c22 100644 (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