From 6b1faf45d199f2d485d062a75779b8b0199263da Mon Sep 17 00:00:00 2001
From: "Wesley W. Terpstra" <w.terpstra@gsi.de>
Date: Fri, 10 Feb 2012 10:41:41 +0000
Subject: [PATCH] Handle (non)blocking more portably.

---
 api/transport/posix-ip.c  | 10 ++++++++++
 api/transport/posix-ip.h  |  9 ++++++++-
 api/transport/posix-tcp.c | 11 +++++++++++
 api/transport/posix-udp.c |  6 ++++++
 api/transport/ssh.c       | 12 ++++++++++++
 5 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/api/transport/posix-ip.c b/api/transport/posix-ip.c
index f270bb6..b45d147 100644
--- a/api/transport/posix-ip.c
+++ b/api/transport/posix-ip.c
@@ -127,3 +127,13 @@ socklen_t eb_posix_ip_resolve(const char* prefix, const char* address, int type,
   freeaddrinfo(match);
   return len;
 }
+
+void eb_posix_ip_non_blocking(eb_posix_sock_t sock, unsigned long on) {
+#if defined(__WIN32)
+  ioctlsocket(sock, FIONBIO, &on);
+#elif defined(EB_POSIX_IP_NON_BLOCKING_NOOP)
+  /* no-op. DONTWAIT is faster */
+#else
+  ioctl(sock, FIONBIO, &on);
+#endif
+}
diff --git a/api/transport/posix-ip.h b/api/transport/posix-ip.h
index f831c1c..acd8c9b 100644
--- a/api/transport/posix-ip.h
+++ b/api/transport/posix-ip.h
@@ -32,7 +32,6 @@
 
 #ifdef __WIN32
 #define _WIN32_WINNT 0x0501
-#define MSG_DONTWAIT 0 // !!!
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <sys/time.h>
@@ -41,6 +40,7 @@ typedef SOCKET eb_posix_sock_t;
 #else
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 #include <sys/select.h>
 #include <sys/time.h>
 #include <netinet/in.h>
@@ -49,8 +49,15 @@ typedef SOCKET eb_posix_sock_t;
 typedef eb_descriptor_t eb_posix_sock_t;
 #endif
 
+#ifdef MSG_DONTWAIT
+#define EB_POSIX_IP_NON_BLOCKING_NOOP
+#else
+#define MSG_DONTWAIT 0
+#endif
+
 EB_PRIVATE void eb_posix_ip_close(eb_posix_sock_t sock);
 EB_PRIVATE eb_posix_sock_t eb_posix_ip_open(int type, int port);
 EB_PRIVATE socklen_t eb_posix_ip_resolve(const char* prefix, const char* address, int type, struct sockaddr_storage* out);
+EB_PRIVATE void eb_posix_ip_non_blocking(eb_posix_sock_t sock, unsigned long on);
 
 #endif
diff --git a/api/transport/posix-tcp.c b/api/transport/posix-tcp.c
index 94297b1..3a2e9dd 100644
--- a/api/transport/posix-tcp.c
+++ b/api/transport/posix-tcp.c
@@ -112,6 +112,9 @@ int eb_posix_tcp_poll(struct eb_transport* transportp, struct eb_link* linkp, ui
   transport = (struct eb_posix_tcp_transport*)transportp;
   link = (struct eb_posix_tcp_link*)linkp;
   
+  /* Set non-blocking */
+  eb_posix_ip_non_blocking(link->socket, 1);
+  
   result = recv(link->socket, (char*)buf, len, MSG_DONTWAIT);
   
   if (result == -1 && errno == EAGAIN) return 0;
@@ -126,6 +129,10 @@ int eb_posix_tcp_recv(struct eb_transport* transportp, struct eb_link* linkp, ui
   if (linkp == 0) return 0;
   
   link = (struct eb_posix_tcp_link*)linkp;
+
+  /* Set blocking */
+  eb_posix_ip_non_blocking(link->socket, 0);
+
   result = recv(link->socket, (char*)buf, len, 0);
   
   /* EAGAIN impossible on blocking read */
@@ -139,5 +146,9 @@ void eb_posix_tcp_send(struct eb_transport* transportp, struct eb_link* linkp, u
   /* linkp == 0 impossible if poll == 0 returns 0 */
   
   link = (struct eb_posix_tcp_link*)linkp;
+  
+  /* Set blocking */
+  eb_posix_ip_non_blocking(link->socket, 0);
+
   send(link->socket, (const char*)buf, len, 0);
 }
diff --git a/api/transport/posix-udp.c b/api/transport/posix-udp.c
index 92d1814..96f63c8 100644
--- a/api/transport/posix-udp.c
+++ b/api/transport/posix-udp.c
@@ -110,6 +110,9 @@ int eb_posix_udp_poll(struct eb_transport* transportp, struct eb_link* linkp, ui
   
   transport = (struct eb_posix_udp_transport*)transportp;
   
+  /* Set non-blocking */
+  eb_posix_ip_non_blocking(transport->socket, 1);
+  
   eb_posix_udp_sa_len = sizeof(eb_posix_udp_sa);
   result = recvfrom(transport->socket, (char*)buf, len, MSG_DONTWAIT, (struct sockaddr*)&eb_posix_udp_sa, &eb_posix_udp_sa_len);
   
@@ -137,6 +140,9 @@ void eb_posix_udp_send(struct eb_transport* transportp, struct eb_link* linkp, u
   transport = (struct eb_posix_udp_transport*)transportp;
   link = (struct eb_posix_udp_link*)linkp;
   
+  /* Set blocking */
+  eb_posix_ip_non_blocking(transport->socket, 0);
+  
   if (link == 0)
     sendto(transport->socket, (const char*)buf, len, 0, (struct sockaddr*)&eb_posix_udp_sa, eb_posix_udp_sa_len);
   else
diff --git a/api/transport/ssh.c b/api/transport/ssh.c
index f190ed1..bad77c1 100644
--- a/api/transport/ssh.c
+++ b/api/transport/ssh.c
@@ -121,6 +121,10 @@ int eb_ssh_poll(struct eb_transport* transportp, struct eb_link* linkp, uint8_t*
   if (linkp == 0) return 0;
   
   link = (struct eb_ssh_link*)linkp;
+  
+  /* Set non-blocking */
+  eb_posix_ip_non_blocking(link->socket, 1);
+
   result = recv(link->socket, (char*)buf, len, MSG_DONTWAIT);
   
   if (result == -1 && errno == EAGAIN) return 0;
@@ -135,6 +139,10 @@ int eb_ssh_recv(struct eb_transport* transportp, struct eb_link* linkp, uint8_t*
   if (linkp == 0) return 0;
   
   link = (struct eb_ssh_link*)linkp;
+  
+  /* Set blocking */
+  eb_posix_ip_non_blocking(link->socket, 0);
+
   result = recv(link->socket, (char*)buf, len, 0);
   
   /* EAGAIN impossible on blocking read */
@@ -147,5 +155,9 @@ void eb_ssh_send(struct eb_transport* transportp, struct eb_link* linkp, uint8_t
   
   /* linkp == 0 impossible if poll returns 0 on 0 */
   link = (struct eb_ssh_link*)linkp;
+  
+  /* Set blocking */
+  eb_posix_ip_non_blocking(link->socket, 0);
+
   send(link->socket, (const char*)buf, len, 0);
 }
-- 
GitLab