diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 95ea83c7f1e..d6bfa941333 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1251,30 +1251,28 @@ static char *strdup_lower(const char *str) /* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option * from an fd and return the value converted to milli seconds - * or -1 if there is an infinite time out */ -static inline int get_rcvsnd_timeo( int fd, int optname) + * or 0 if there is an infinite time out */ +static inline INT64 get_rcvsnd_timeo( int fd, int optname) { struct timeval tv; socklen_t len = sizeof(tv); - int ret = getsockopt(fd, SOL_SOCKET, optname, &tv, &len); - if( ret >= 0) - ret = tv.tv_sec * 1000 + tv.tv_usec / 1000; - if( ret <= 0 ) /* tv == {0,0} means infinite time out */ - return -1; - return ret; + int res = getsockopt(fd, SOL_SOCKET, optname, &tv, &len); + if (res < 0) + return 0; + return (UINT64)tv.tv_sec * 1000 + tv.tv_usec / 1000; } /* macro wrappers for portability */ #ifdef SO_RCVTIMEO #define GET_RCVTIMEO(fd) get_rcvsnd_timeo( (fd), SO_RCVTIMEO) #else -#define GET_RCVTIMEO(fd) (-1) +#define GET_RCVTIMEO(fd) (0) #endif #ifdef SO_SNDTIMEO #define GET_SNDTIMEO(fd) get_rcvsnd_timeo( (fd), SO_SNDTIMEO) #else -#define GET_SNDTIMEO(fd) (-1) +#define GET_SNDTIMEO(fd) (0) #endif /* utility: given an fd, will block until one of the events occurs */ @@ -5076,18 +5074,20 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, while (wsa->first_iovec < wsa->n_iovecs) { struct pollfd pfd; - int timeout = GET_SNDTIMEO(fd); + int poll_timeout = -1; + INT64 timeout = GET_SNDTIMEO(fd); - if (timeout != -1) + if (timeout) { timeout -= GetTickCount() - timeout_start; - if (timeout < 0) timeout = 0; + if (timeout < 0) poll_timeout = 0; + else poll_timeout = timeout <= INT_MAX ? timeout : INT_MAX; } pfd.fd = fd; pfd.events = POLLOUT; - if (!timeout || !poll( &pfd, 1, timeout )) + if (!poll_timeout || !poll( &pfd, 1, poll_timeout )) { err = WSAETIMEDOUT; goto error; /* msdn says a timeout in send is fatal */ @@ -7130,18 +7130,21 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, if ( is_blocking ) { struct pollfd pfd; - int timeout = GET_RCVTIMEO(fd); - if (timeout != -1) + int poll_timeout = -1; + INT64 timeout = GET_RCVTIMEO(fd); + + if (timeout) { timeout -= GetTickCount() - timeout_start; - if (timeout < 0) timeout = 0; + if (timeout < 0) poll_timeout = 0; + else poll_timeout = timeout <= INT_MAX ? timeout : INT_MAX; } pfd.fd = fd; pfd.events = POLLIN; if (*lpFlags & WS_MSG_OOB) pfd.events |= POLLPRI; - if (!timeout || !poll( &pfd, 1, timeout )) + if (!poll_timeout || !poll( &pfd, 1, poll_timeout )) { err = WSAETIMEDOUT; /* a timeout is not fatal */