Ensure sockets are not blocking after a select under Windows.

This commit is contained in:
Ray Satiro 2011-05-15 21:59:50 +02:00 committed by Giuseppe Scrivano
parent 53427a9b76
commit 4a685764a8
4 changed files with 63 additions and 2 deletions

View File

@ -1,5 +1,9 @@
2011-05-15 Ray Satiro <raysatiro@yahoo.com>
* connect.c (select_fd) [WINDOWS]: Ensure the socket is blocking.
* mswindows.h: Add declaration for set_windows_fd_as_blocking_socket.
* mswindows.c (set_windows_fd_as_blocking_socket): New function.
* openssl.c (openssl_read): Prevent loops on read errors.
2011-04-24 Giuseppe Scrivano <gscrivano@gnu.org>

View File

@ -656,7 +656,14 @@ select_fd (int fd, double maxtime, int wait_for)
tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);
do
{
result = select (fd + 1, rd, wr, NULL, &tmout);
#ifdef WINDOWS
/* gnulib select() converts blocking sockets to nonblocking in windows.
wget uses blocking sockets so we must convert them back to blocking. */
set_windows_fd_as_blocking_socket (fd);
#endif
}
while (result < 0 && errno == EINTR);
return result;
@ -678,6 +685,7 @@ test_socket_open (int sock)
{
fd_set check_set;
struct timeval to;
int ret = 0;
/* Check if we still have a valid (non-EOF) connection. From Andrew
* Maholski's code in the Unix Socket FAQ. */
@ -689,7 +697,15 @@ test_socket_open (int sock)
to.tv_sec = 0;
to.tv_usec = 1;
if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
ret = select (sock + 1, &check_set, NULL, NULL, &to);
#ifdef WINDOWS
/* gnulib select() converts blocking sockets to nonblocking in windows.
wget uses blocking sockets so we must convert them back to blocking
*/
set_windows_fd_as_blocking_socket ( sock );
#endif
if ( !ret )
/* We got a timeout, it means we're still connected. */
return true;
else

View File

@ -573,7 +573,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
return rc;
}
#ifdef ENABLE_IPV6
/* An inet_ntop implementation that uses WSAAddressToString.
Prototype complies with POSIX 1003.1-2004. This is only used under
@ -615,3 +615,40 @@ inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
return (const char *) dst;
}
#endif
void
set_windows_fd_as_blocking_socket (int fd)
{
/* 04/2011
gnulib select() converts blocking sockets to nonblocking in windows
discussed here:
http://old.nabble.com/blocking-socket-is-nonblocking-after-calling-gnulib-
select%28%29-in-windows-td31432857.html
wget uses blocking sockets so we must convert them back to blocking.
*/
int ret = 0;
int wsagle = 0;
const int zero = 0;
do
{
if(wsagle == WSAEINPROGRESS)
Sleep(1); /* use windows sleep */
WSASetLastError (0);
ret = ioctl (fd, FIONBIO, &zero);
wsagle = WSAGetLastError();
}
while (ret && (wsagle == WSAEINPROGRESS));
if(ret)
{
fprintf (stderr,
"ioctl() failed. The socket could not be set as blocking.\n" );
DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
abort ();
}
return;
}

View File

@ -118,6 +118,9 @@ const char *inet_ntop (int, const void *, char *, socklen_t);
# define gai_strerror strerror
#endif
/* ioctl needed by set_windows_fd_as_blocking_socket() */
#include <sys/ioctl.h>
/* Public functions. */
void ws_startup (void);
@ -125,5 +128,6 @@ void ws_changetitle (const char *);
void ws_percenttitle (double);
char *ws_mypath (void);
void windows_main (char **);
void set_windows_fd_as_blocking_socket (int);
#endif /* MSWINDOWS_H */