]> sjero.net Git - wget/commitdiff
Ensure sockets are not blocking after a select under Windows.
authorRay Satiro <raysatiro@yahoo.com>
Sun, 15 May 2011 19:59:50 +0000 (21:59 +0200)
committerGiuseppe Scrivano <gscrivano@gnu.org>
Sun, 15 May 2011 19:59:50 +0000 (21:59 +0200)
src/ChangeLog
src/connect.c
src/mswindows.c
src/mswindows.h

index b938538dc7a54ede2a44a0aa033e8b3223ed8d1a..33bd319975944c1365685ae4c21bacdbf469ede2 100644 (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>
index 8f32f9843bb74d7fc58c589b3ae449505dd4e7c6..e12c049a11002e5a432f1758e1db7befe4ddf3ba 100644 (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
index d7749fa2ab35313d10bc078e041d70b86a5afb9b..51342300c206668f7448a85523f34eb9c1b9389e 100644 (file)
@@ -573,7 +573,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
   return rc;
 }
 
-\f
+
 #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;
+}
index 82ff5e183ed9b1b8e6e279897dbb7e983248ef36..e0a20e4afca89d197a020f0dddcc4e10786ff3d1 100644 (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 */