diff options
author | Martin Lambers <marlam@marlam.de> | 2009-02-03 07:30:20 +0100 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2009-03-01 17:38:26 +0100 |
commit | a8ccc7e88310f9187a1655a9969da3ae007e2aa3 (patch) | |
tree | 22b92202448f0968c671c956e44944d4a1fab6c1 /lib/getsockopt.c | |
parent | 3e4151d4339192f004275caa3b3de921a8575fb9 (diff) | |
download | gnulib-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.c | 29 |
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 (); |