]> sourceware.org Git - newlib-cygwin.git/commitdiff
* fhandler.h (enum conn_state): Add connect_failed state.
authorCorinna Vinschen <corinna@vinschen.de>
Mon, 18 Apr 2005 18:56:52 +0000 (18:56 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 18 Apr 2005 18:56:52 +0000 (18:56 +0000)
* fhandler_socket.cc (fhandler_socket::connect): Set connect_state to
connect_failed when connect failed.
* poll.cc (poll): Change errno to EINVAL if allocating memory fails,
according to SUSv3. Add socket descriptors always to except_fds. Test
for failed connect and set revents flags appropriately.
* select.cc (set_bits): Set connect_state to connect_failed when
select indicates failed nonblocking connect.
(fhandler_dev_null::select_except): Set except_ready to false so that
/dev/null is not always in except state.
(peek_socket): Fix bogus conditional.
(fhandler_socket::select_write): Treat all connect_states except
unconnected equivalent to return consistent results.
(fhandler_windows::select_except): Set except_ready to false so that
/dev/windows is not always in except state.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/poll.cc
winsup/cygwin/select.cc

index d205c47548f0e3f6bb6f80defddfda107750fe6c..a1f575ab42627eeb08c6f065f6a2f564bb9ff661 100644 (file)
@@ -1,3 +1,21 @@
+2005-04-18  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (enum conn_state): Add connect_failed state.
+       * fhandler_socket.cc (fhandler_socket::connect): Set connect_state to
+       connect_failed when connect failed.
+       * poll.cc (poll): Change errno to EINVAL if allocating memory fails,
+       according to SUSv3. Add socket descriptors always to except_fds. Test
+       for failed connect and set revents flags appropriately.
+       * select.cc (set_bits): Set connect_state to connect_failed when
+       select indicates failed nonblocking connect.
+       (fhandler_dev_null::select_except): Set except_ready to false so that
+       /dev/null is not always in except state.
+       (peek_socket): Fix bogus conditional.
+       (fhandler_socket::select_write): Treat all connect_states except
+       unconnected equivalent to return consistent results.
+       (fhandler_windows::select_except): Set except_ready to false so that
+       /dev/windows is not always in except state.
+
 2005-04-18  Christopher Faylor  <cgf@timesys.com>
 
        * include/cygwin/version.h: Bump DLL minor number to 16.
index a7fcb9086904565d389b344811c7f67fd6a03793..7611378bd4a551cd6b802e1835e8ff4f62efe19d 100644 (file)
@@ -50,7 +50,8 @@ enum conn_state
 {
   unconnected = 0,
   connect_pending = 1,
-  connected = 2
+  connected = 2,
+  connect_failed = 3
 };
 
 enum line_edit_status
index aa412081ed066bb4cf9bfe482d588fd9cdd3b749..7c7e2daf8c007ada54d5cb43666ae457f82c2097 100644 (file)
@@ -706,7 +706,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
       err = WSAGetLastError ();
       /* Special handling for connect to return the correct error code
         when called on a non-blocking socket. */
-      if (is_nonblocking () || connect_state () == connect_pending)
+      if (is_nonblocking ())
        {
          if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
            in_progress = true;
@@ -736,6 +736,8 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
 
   if (err == WSAEINPROGRESS || err == WSAEALREADY)
     connect_state (connect_pending);
+  else if (err)
+    connect_state (connect_failed);
   else
     connect_state (connected);
 
index c6a98f4221648c26862502f7eb83382c22c34e0c..50f67537217ac3b8a4e0c301afe1b8deb2a70596 100644 (file)
@@ -45,7 +45,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
 
   if (!read_fds || !write_fds || !except_fds)
     {
-      set_errno (ENOMEM);
+      set_errno (EINVAL);      /* According to SUSv3. */
       return -1;
     }
 
@@ -63,7 +63,9 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
            FD_SET(fds[i].fd, read_fds);
          if (fds[i].events & POLLOUT)
            FD_SET(fds[i].fd, write_fds);
-         if (fds[i].events & POLLPRI)
+         /* On sockets, except_fds is needed to catch failed connects. */
+         if ((fds[i].events & POLLPRI)
+             || cygheap->fdtab[fds[i].fd]->is_socket ())
            FD_SET(fds[i].fd, except_fds);
        }
       else if (fds[i].fd >= 0)
@@ -87,11 +89,12 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
              fds[i].revents = POLLHUP;
            else
              {
+               fhandler_socket *sock;
+
                if (FD_ISSET(fds[i].fd, read_fds))
                  {
                    char peek[1];
-                   fhandler_socket *sock =
-                                     cygheap->fdtab[fds[i].fd]->is_socket ();
+                   sock = cygheap->fdtab[fds[i].fd]->is_socket ();
                    if (!sock)
                      fds[i].revents |= POLLIN;
                    else
@@ -125,10 +128,19 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
                        set_errno (old_errno);
                      }
                  }
-               if (FD_ISSET(fds[i].fd, write_fds))
-                 fds[i].revents |= POLLOUT;
-               if (FD_ISSET(fds[i].fd, except_fds))
-                 fds[i].revents |= POLLPRI;
+               /* Handle failed connect. */
+               if (FD_ISSET(fds[i].fd, write_fds)
+                   && FD_ISSET(fds[i].fd, except_fds)
+                   && (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
+                   && sock->connect_state () == connect_failed)
+                 fds[i].revents |= (POLLIN | POLLERR);
+               else 
+                 {
+                   if (FD_ISSET(fds[i].fd, write_fds))
+                     fds[i].revents |= POLLOUT;
+                   if (FD_ISSET(fds[i].fd, except_fds))
+                     fds[i].revents |= POLLPRI;
+                 }
              }
          }
       }
index 1c469cf6342ba01699e44a1187ce55a41791f29d..2daa88a5f6b08add62f1a175e77f175ab95844f6 100644 (file)
@@ -352,7 +352,7 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
        {
          UNIX_FD_SET (me->fd, writefds);
          if ((sock = me->fh->is_socket ()))
-           sock->connect_state (connected);
+           sock->connect_state (connect_failed);
        }
       if (me->except_selected)
        UNIX_FD_SET (me->fd, exceptfds);
@@ -915,7 +915,7 @@ fhandler_dev_null::select_except (select_record *s)
     }
   s->h = get_handle ();
   s->except_selected = true;
-  s->except_ready = true;
+  s->except_ready = false;
   return s;
 }
 
@@ -1271,11 +1271,11 @@ peek_socket (select_record *me, bool)
          set_winsock_errno ();
          return 0;
        }
-      if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
+      if (WINSOCK_FD_ISSET (h, &ws_readfds))
        me->read_ready = true;
-      if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
+      if (WINSOCK_FD_ISSET (h, &ws_writefds))
        me->write_ready = true;
-      if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || ((me->except_selected || me->except_on_write) && me->except_ready))
+      if (WINSOCK_FD_ISSET (h, &ws_exceptfds))
        me->except_ready = true;
     }
   return me->read_ready || me->write_ready || me->except_ready;
@@ -1460,7 +1460,7 @@ fhandler_socket::select_write (select_record *s)
   s->peek = peek_socket;
   s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
   s->write_selected = true;
-  if (connect_state () == connect_pending)
+  if (connect_state () != unconnected)
     {
       s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
       s->except_on_write = true;
@@ -1559,7 +1559,7 @@ fhandler_windows::select_except (select_record *s)
   s->peek = peek_windows;
   s->h = get_handle ();
   s->except_selected = true;
-  s->except_ready = true;
+  s->except_ready = false;
   s->windows_handle = true;
   return s;
 }
This page took 0.04581 seconds and 5 git commands to generate.