summaryrefslogtreecommitdiff
path: root/lib/getsockopt.c
diff options
context:
space:
mode:
authorMartin Lambers <marlam@marlam.de>2009-02-03 07:30:20 +0100
committerSimon Josefsson <simon@josefsson.org>2009-03-01 17:38:26 +0100
commita8ccc7e88310f9187a1655a9969da3ae007e2aa3 (patch)
tree22b92202448f0968c671c956e44944d4a1fab6c1 /lib/getsockopt.c
parent3e4151d4339192f004275caa3b3de921a8575fb9 (diff)
downloadgnulib-a8ccc7e88310f9187a1655a9969da3ae007e2aa3.tar.gz
setsockopt: Add support for timeouts on W32
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>
Diffstat (limited to 'lib/getsockopt.c')
-rw-r--r--lib/getsockopt.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/getsockopt.c b/lib/getsockopt.c
index 7be8bed51b..3da37a99cd 100644
--- a/lib/getsockopt.c
+++ b/lib/getsockopt.c
@@ -23,6 +23,12 @@
/* 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"
@@ -31,8 +37,29 @@
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 ();