]> sourceware.org Git - newlib-cygwin.git/commitdiff
* fhandler.h (UNCONNECTED): New define.
authorCorinna Vinschen <corinna@vinschen.de>
Fri, 5 Jul 2002 18:26:23 +0000 (18:26 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Fri, 5 Jul 2002 18:26:23 +0000 (18:26 +0000)
(CONNECT_PENDING): Ditto.
(CONNECTED): Ditto.
(class fhandler_socket): Add member `had_connect_or_listen'.
Add member functions `is_unconnected', `is_connect_pending' and
`is_connected'.
* fhandler_socket.cc (fhandler_socket::connect): Set member
`had_connect_or_listen' according to return code of WinSock
call.
(fhandler_socket::listen): Ditto.
* net.cc (cygwin_getsockopt): Modify SO_ERROR return value in
case of socket with pending connect().
* select.cc (peek_socket): Only add socket to matching fd_set
if it's not "ready".  Call WINSOCK_SELECT only if at least one
socket is in one of the fd_sets.
(start_thread_socket): Only add socket to matching fd_set
if it's not "ready".
(fhandler_socket::select_write): Set write_ready to true also
if socket isn't connected or listening.

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

index 15f24ae986feb95c6c1d111f943116681cccf11d..849e5a623fb575105d3e8ae7fd711d592adf8880 100644 (file)
@@ -1,3 +1,25 @@
+2002-07-05  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (UNCONNECTED): New define.
+       (CONNECT_PENDING): Ditto.
+       (CONNECTED): Ditto.
+       (class fhandler_socket): Add member `had_connect_or_listen'.
+       Add member functions `is_unconnected', `is_connect_pending' and
+       `is_connected'.
+       * fhandler_socket.cc (fhandler_socket::connect): Set member
+       `had_connect_or_listen' according to return code of WinSock
+       call.
+       (fhandler_socket::listen): Ditto.
+       * net.cc (cygwin_getsockopt): Modify SO_ERROR return value in
+       case of socket with pending connect().
+       * select.cc (peek_socket): Only add socket to matching fd_set
+       if it's not "ready".  Call WINSOCK_SELECT only if at least one
+       socket is in one of the fd_sets.
+       (start_thread_socket): Only add socket to matching fd_set
+       if it's not "ready".
+       (fhandler_socket::select_write): Set write_ready to true also
+       if socket isn't connected or listening.
+
 2002-07-04  Corinna Vinschen  <corinna@vinschen.de>
 
        * fhandler_socket.cc (fhandler_socket::set_sun_path): Don't free
index 5727d24ab103f7a769192fe4fd13e76917341ac9..980957a67c8da66e9518a9cedd9cc3e16c047dc0 100644 (file)
@@ -101,6 +101,10 @@ enum
    both flags are set. */
 #define O_NONBLOCK_MASK (O_NONBLOCK | OLD_O_NDELAY)
 
+#define UNCONNECTED     0
+#define CONNECT_PENDING 1
+#define CONNECTED       2
+
 extern const char *windows_device_names[];
 extern struct __cygwin_perfile *perfile_table;
 #define __fmode (*(user_data->fmode_ptr))
@@ -367,6 +371,7 @@ class fhandler_socket: public fhandler_base
   HANDLE secret_event;
   struct _WSAPROTOCOL_INFOA *prot_info_ptr;
   char *sun_path;
+  int had_connect_or_listen;
 
  public:
   fhandler_socket ();
@@ -380,6 +385,10 @@ class fhandler_socket: public fhandler_base
   void set_shutdown_read () {FHSETF (SHUTRD);}
   void set_shutdown_write () {FHSETF (SHUTWR);}
 
+  bool is_unconnected () {return had_connect_or_listen == UNCONNECTED;}
+  bool is_connect_pending () {return had_connect_or_listen == CONNECT_PENDING;}
+  bool is_connected () {return had_connect_or_listen == CONNECTED;}
+
   int bind (const struct sockaddr *name, int namelen);
   int connect (const struct sockaddr *name, int namelen);
   int listen (int backlog);
index 7970e4b63b00dd63f7921a6bcd9e24823fef9701..e95655510e1ea08e5e321a815c3af2b7699c1456 100644 (file)
@@ -455,6 +455,10 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
        }
     }
 
+  if (!res)
+    had_connect_or_listen = CONNECTED;
+  else if (WSAGetLastError () == WSAEINPROGRESS)
+    had_connect_or_listen = CONNECT_PENDING;
   return res;
 }
 
@@ -464,6 +468,8 @@ fhandler_socket::listen (int backlog)
   int res = ::listen (get_socket (), backlog);
   if (res)
     set_winsock_errno ();
+  else
+    had_connect_or_listen = CONNECTED;
   return res;
 }
 
index 870bf7865e20213e4ba7a748370a8ac77bc9ddac..1445ae68364615123b074f5ee95ce8fa3c5d2473 100644 (file)
@@ -712,6 +712,8 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen)
       if (optname == SO_ERROR)
        {
          int *e = (int *) optval;
+         if (!*e && fh->is_connect_pending ())
+           *e = WSAEINPROGRESS;
          *e = find_winsock_errno (*e);
        }
 
index b50ffb1f2cc6cb0436e868fd05118897712dd864..46f0c6963f03c31eb9576f0f87cba138c1cb78f1 100644 (file)
@@ -1180,39 +1180,44 @@ peek_socket (select_record *me, bool)
   set_handle_or_return_if_not_open (h, me);
   select_printf ("considering handle %p", h);
 
-  if (me->read_selected)
+  if (me->read_selected && !me->read_ready)
     {
       select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (),
                     me->fd);
       WINSOCK_FD_SET (h, &ws_readfds);
     }
-  if (me->write_selected)
+  if (me->write_selected && !me->write_ready)
     {
       select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (),
                     me->fd);
       WINSOCK_FD_SET (h, &ws_writefds);
     }
-  if (me->except_selected)
+  if (me->except_selected && !me->except_ready)
     {
       select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (),
                     me->fd);
       WINSOCK_FD_SET (h, &ws_exceptfds);
     }
-  int r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
-  select_printf ("WINSOCK_SELECT returned %d", r);
-  if (r == -1)
+  int r;
+  if ((me->read_selected && !me->read_ready)
+      || (me->write_selected && !me->write_ready)
+      || (me->except_selected && !me->except_ready))
     {
-      select_printf ("error %d", WSAGetLastError ());
-      set_winsock_errno ();
-      return 0;
+      r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
+      select_printf ("WINSOCK_SELECT returned %d", r);
+      if (r == -1)
+       {
+         select_printf ("error %d", WSAGetLastError ());
+         set_winsock_errno ();
+         return 0;
+       }
+      if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
+       me->read_ready = true;
+      if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
+       me->write_ready = true;
+      if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
+       me->except_ready = true;
     }
-
-  if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
-    me->read_ready = true;
-  if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
-    me->write_ready = true;
-  if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
-    me->except_ready = true;
   return me->read_ready || me->write_ready || me->except_ready;
 }
 
@@ -1280,17 +1285,17 @@ start_thread_socket (select_record *me, select_stuff *stuff)
       {
        HANDLE h = s->fh->get_handle ();
        select_printf ("Handle %p", h);
-       if (s->read_selected)
+       if (s->read_selected && !s->read_ready)
          {
            WINSOCK_FD_SET (h, &si->readfds);
            select_printf ("Added to readfds");
          }
-       if (s->write_selected)
+       if (s->write_selected && !s->write_ready)
          {
            WINSOCK_FD_SET (h, &si->writefds);
            select_printf ("Added to writefds");
          }
-       if (s->except_selected)
+       if (s->except_selected && !s->except_ready)
          {
            WINSOCK_FD_SET (h, &si->exceptfds);
            select_printf ("Added to exceptfds");
@@ -1410,7 +1415,7 @@ fhandler_socket::select_write (select_record *s)
       s->cleanup = socket_cleanup;
     }
   s->peek = peek_socket;
-  s->write_ready = saw_shutdown_write ();
+  s->write_ready = saw_shutdown_write () || !is_connected ();
   s->write_selected = true;
   return s;
 }
This page took 0.040659 seconds and 5 git commands to generate.