setsockopt: Add support for timeouts on W32
authorMartin Lambers <marlam@marlam.de>
Tue, 3 Feb 2009 06:30:20 +0000 (07:30 +0100)
committerSimon Josefsson <simon@josefsson.org>
Sun, 1 Mar 2009 16:38:26 +0000 (17:38 +0100)
Provide POSIX semantics for socket timeout options on W32.
 * lib/setsockopt.c: Convert struct timeval to milliseconds on W32.
 * lib/getsockopt.c: Convert milliseconds to struct timeval on W32.
 * modules/setsockopt: Depend on sys_time module for struct timeval.
 * modules/getsockopt: Depend on sys_time module for struct timeval.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
lib/getsockopt.c
lib/setsockopt.c
modules/getsockopt
modules/setsockopt

index 7be8bed51b86c0fedfb560186b256e3868dd7661..3da37a99cda1521ecc92f089ed36be84badae315 100644 (file)
 /* Get winsock2.h. */
 #include <sys/socket.h>
 
+/* Get struct timeval. */
+#include <sys/time.h>
+
+/* Get memcpy. */
+#include <string.h>
+
 /* Get set_winsock_errno, FD_TO_SOCKET etc. */
 #include "w32sock.h"
 
 int
 rpl_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
 {
+  int r;
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = getsockopt (sock, level, optname, optval, optlen);
+
+  if (level == SOL_SOCKET && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+    {
+      int milliseconds;
+      int milliseconds_len = sizeof (int);
+      struct timeval tv;
+      size_t n;
+      r = getsockopt (sock, level, optname, &milliseconds, &milliseconds_len);
+      tv.tv_sec = milliseconds / 1000;
+      tv.tv_usec = (milliseconds - 1000 * tv.tv_sec) * 1000;
+      n = sizeof (struct timeval);
+      if (n > *optlen)
+         n = *optlen;
+      memcpy (optval, &tv, n);
+      *optlen = n;
+    }
+  else
+    {
+      r = getsockopt (sock, level, optname, optval, optlen);
+    }
+
   if (r < 0)
     set_winsock_errno ();
 
index 09f048e48a7e1a3b28a6a639c0812ae00124ab82..64f4a814ede78a343e36a69631194a1365250012 100644 (file)
@@ -23,6 +23,9 @@
 /* Get winsock2.h. */
 #include <sys/socket.h>
 
+/* Get struct timeval. */
+#include <sys/time.h>
+
 /* Get set_winsock_errno, FD_TO_SOCKET etc. */
 #include "w32sock.h"
 
 int
 rpl_setsockopt (int fd, int level, int optname, const void *optval, int optlen)
 {
+  int r;
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = setsockopt (sock, level, optname, optval, optlen);
+
+  if (level == SOL_SOCKET && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+    {
+      const struct timeval *tv = optval;
+      int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+      r = setsockopt (sock, level, optname, &milliseconds, sizeof (int));
+    }
+  else
+    {
+      r = setsockopt (sock, level, optname, optval, optlen);
+    }
+
   if (r < 0)
     set_winsock_errno ();
 
index efb762af52ecc2ac00eb3e770bc29711ffbe9c93..40ff64981733fed51b55c4cc22897520108d36f1 100644 (file)
@@ -7,6 +7,7 @@ lib/w32sock.h
 
 Depends-on:
 sys_socket
+sys_time
 errno
 
 configure.ac:
index d665f8ee63c6123077a8e723d6b2cb9953e2a921..b429510a0141e96a49ecfb05348d87d39abe2489 100644 (file)
@@ -7,6 +7,7 @@ lib/w32sock.h
 
 Depends-on:
 sys_socket
+sys_time
 errno
 
 configure.ac: