Hello Bruno! On Thu, 25. Dec 2008, 20:59:03 +0100, Bruno Haible wrote: > What about getsockopt()? I would guess it needs to do the opposite > conversion, no?
Yes of course, I forgot that because I did not use it. Here's an updated patch. I used memcpy() because POSIX requires silent truncation of the option value in case optlen is smaller than necessary. Is there a reason that the replacement getsockopt and setsockopt functions do not use the POSIX prototype (pointers with the 'restrict' keyword, length arguments with socklen_t)? Martin diff -ur gnulib/lib/getsockopt.c gnulib-local/lib/getsockopt.c --- gnulib/lib/getsockopt.c 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/lib/getsockopt.c 2008-12-25 23:01:56.000000000 +0100 @@ -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 (); diff -ur gnulib/lib/setsockopt.c gnulib-local/lib/setsockopt.c --- gnulib/lib/setsockopt.c 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/lib/setsockopt.c 2008-12-25 22:54:24.000000000 +0100 @@ -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" @@ -31,8 +34,20 @@ 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 (); diff -ur gnulib/modules/getsockopt gnulib-local/modules/getsockopt --- gnulib/modules/getsockopt 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/modules/getsockopt 2008-12-25 22:22:47.000000000 +0100 @@ -7,6 +7,7 @@ Depends-on: sys_socket +sys_time errno configure.ac: diff -ur gnulib/modules/setsockopt gnulib-local/modules/setsockopt --- gnulib/modules/setsockopt 2008-12-24 17:08:35.000000000 +0100 +++ gnulib-local/modules/setsockopt 2008-12-25 09:11:51.000000000 +0100 @@ -7,6 +7,7 @@ Depends-on: sys_socket +sys_time errno configure.ac: