OSDN Git Service

* fhandler.h (class fhandler_socket): Remove prot_info_ptr.
authorcorinna <corinna>
Thu, 27 Jul 2006 09:11:36 +0000 (09:11 +0000)
committercorinna <corinna>
Thu, 27 Jul 2006 09:11:36 +0000 (09:11 +0000)
(fhandler_socket::fixup_before_fork_exec): Remove.
(fhandler_socket::fixup_after_exec): Remove.
(fhandler_socket::need_fixup_before): Remove.
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Drop
initializing prot_info_ptr.  Remove unused code.
(fhandler_socket::~fhandler_socket): Drop free'ing prot_info_ptr.
(struct wsa_event): Rename connect_errorcode to errorcode.
(fhandler_socket::evaluate_events): Handle FD_CLOSE error condition
as FD_CONNECT error condition, except, never reset an FD_CLOSE error
condition.  Always set FD_WRITE after successfully recorded FD_CONNECT.
(fhandler_socket::fixup_before_fork_exec): Remove.
(fhandler_socket::fixup_after_fork): Revert to using handle duplication.
(fhandler_socket::fixup_after_exec): Remove.
(fhandler_socket::dup): Revert to using handle duplication.
(fhandler_socket::send_internal): Only call wait_for_events in case
of WSAEWOULDBLOCK condition.
(fhandler_socket::set_close_on_exec): Call
fhandler_base::set_close_on_exec.
* net.cc (fdsock): Just set socket to inheritable on non-NT.  Don't
call inc_need_fixup_before.
* select.cc (peek_socket): Don't set except_ready on every FD_CLOSE,
just on error.

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

index c75a91d..d3693c5 100644 (file)
@@ -1,3 +1,29 @@
+2006-07-27  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (class fhandler_socket): Remove prot_info_ptr.
+       (fhandler_socket::fixup_before_fork_exec): Remove.
+       (fhandler_socket::fixup_after_exec): Remove.
+       (fhandler_socket::need_fixup_before): Remove.
+       * fhandler_socket.cc (fhandler_socket::fhandler_socket): Drop
+       initializing prot_info_ptr.  Remove unused code.
+       (fhandler_socket::~fhandler_socket): Drop free'ing prot_info_ptr.
+       (struct wsa_event): Rename connect_errorcode to errorcode.
+       (fhandler_socket::evaluate_events): Handle FD_CLOSE error condition
+       as FD_CONNECT error condition, except, never reset an FD_CLOSE error
+       condition.  Always set FD_WRITE after successfully recorded FD_CONNECT.
+       (fhandler_socket::fixup_before_fork_exec): Remove.
+       (fhandler_socket::fixup_after_fork): Revert to using handle duplication.
+       (fhandler_socket::fixup_after_exec): Remove.
+       (fhandler_socket::dup): Revert to using handle duplication.
+       (fhandler_socket::send_internal): Only call wait_for_events in case
+       of WSAEWOULDBLOCK condition.
+       (fhandler_socket::set_close_on_exec): Call
+       fhandler_base::set_close_on_exec.
+       * net.cc (fdsock): Just set socket to inheritable on non-NT.  Don't
+       call inc_need_fixup_before.
+       * select.cc (peek_socket): Don't set except_ready on every FD_CLOSE,
+       just on error.
+
 2006-07-26  Brian ford  <Brian.Ford@FlightSafety.com>
 
        * fhandler.cc (fhandler_base::read): Call get_readahead_into_buffer
index 6468560..7b9ba7e 100644 (file)
@@ -418,7 +418,6 @@ class fhandler_socket: public fhandler_base
   void af_local_set_sockpair_cred ();
 
  private:
-  struct _WSAPROTOCOL_INFOA *prot_info_ptr;
   char *sun_path;
   struct status_flags
   {
@@ -481,10 +480,7 @@ class fhandler_socket: public fhandler_base
   int dup (fhandler_base *child);
 
   void set_close_on_exec (bool val);
-  virtual void fixup_before_fork_exec (DWORD);
   void fixup_after_fork (HANDLE);
-  void fixup_after_exec ();
-  bool need_fixup_before () const {return true;}
   char *get_proc_fd_name (char *buf);
 
   select_record *select_read (select_record *s);
index 6385820..a6f760a 100644 (file)
@@ -136,22 +136,10 @@ fhandler_socket::fhandler_socket () :
   status ()
 {
   need_fork_fixup (true);
-  prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
-                                                sizeof (WSAPROTOCOL_INFOA));
-#if 0
-  if (pc.is_fs_special ())
-    {
-      fhandler_socket * fhs = (fhandler_socket *) fh;
-      fhs->set_addr_family (AF_LOCAL);
-      fhs->set_sun_path (posix_path);
-    }
-#endif
 }
 
 fhandler_socket::~fhandler_socket ()
 {
-  if (prot_info_ptr)
-    cfree (prot_info_ptr);
   if (sun_path)
     cfree (sun_path);
 }
@@ -398,7 +386,7 @@ struct wsa_event
 {
   LONG serial_number;
   long events;
-  int  connect_errorcode;
+  int  errorcode;
   pid_t owner;
 };
 
@@ -520,7 +508,9 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
          LOCK_EVENTS;
          wsock_events->events |= evts.lNetworkEvents;
          if (evts.lNetworkEvents & FD_CONNECT)
-           wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
+           wsock_events->errorcode = evts.iErrorCode[FD_CONNECT_BIT];
+         else if (evts.lNetworkEvents & FD_CLOSE)
+           wsock_events->errorcode = evts.iErrorCode[FD_CLOSE_BIT];
          UNLOCK_EVENTS;
          if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
            kill (wsock_events->owner, SIGURG);
@@ -530,16 +520,22 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
   LOCK_EVENTS;
   if ((events = (wsock_events->events & event_mask)) != 0)
     {
-      if (events & FD_CONNECT)
+      if (events & (FD_CONNECT | FD_CLOSE))
        {
          int wsa_err = 0;
-         if ((wsa_err = wsock_events->connect_errorcode) != 0)
+         if ((wsa_err = wsock_events->errorcode) != 0)
            {
              WSASetLastError (wsa_err);
              ret = SOCKET_ERROR;
            }
-         wsock_events->connect_errorcode = 0;
-         wsock_events->events &= ~FD_CONNECT;
+         if (events & FD_CONNECT)
+           {
+             if (!wsock_events->errorcode)
+               wsock_events->events |= FD_WRITE;
+             wsock_events->events &= ~FD_CONNECT;
+           }
+         if (!(events & FD_CLOSE))
+           wsock_events->errorcode = 0;
        }
       if (erase)
        wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
@@ -599,83 +595,28 @@ fhandler_socket::release_events ()
 }
 
 void
-fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
-{
-  if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
-    debug_printf ("WSADuplicateSocket went fine, sock %p, win_proc_id %d, prot_info_ptr %p",
-                 get_socket (), win_proc_id, prot_info_ptr);
-  else
-    {
-      debug_printf ("WSADuplicateSocket error, sock %p, win_proc_id %d, prot_info_ptr %p",
-                   get_socket (), win_proc_id, prot_info_ptr);
-      set_winsock_errno ();
-    }
-}
-
-void
 fhandler_socket::fixup_after_fork (HANDLE parent)
 {
-  SOCKET new_sock;
-
-  debug_printf ("WSASocket begin, dwServiceFlags1=%d",
-               prot_info_ptr->dwServiceFlags1);
-
-  if ((new_sock = WSASocketA (FROM_PROTOCOL_INFO,
-                                  FROM_PROTOCOL_INFO,
-                                  FROM_PROTOCOL_INFO,
-                                  prot_info_ptr, 0, 0)) == INVALID_SOCKET)
-    {
-      debug_printf ("WSASocket error");
-      set_io_handle ((HANDLE)INVALID_SOCKET);
-      set_winsock_errno ();
-    }
-  else
-    {
-      debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_socket ());
-
-      /* Go figure!  Even though the original socket was not inheritable,
-        the duplicated socket is inheritable again.  This can lead to all
-        sorts of trouble, apparently.  Note that there's no way to prevent
-        this on 9x, not even by trying to reset socket inheritance using
-        DuplicateHandle and closing the original socket. */
-      if (wincap.has_set_handle_information ())
-       SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
-
-      set_io_handle ((HANDLE) new_sock);
-    }
-  if (parent)  /* fork, not exec or dup */
-    {
-      fork_fixup (parent, wsock_mtx, "wsock_mtx");
-      fork_fixup (parent, wsock_evt, "wsock_evt");
-    }
-}
-
-void
-fhandler_socket::fixup_after_exec ()
-{
-  if (!close_on_exec ())
-    fixup_after_fork (NULL);
+  fork_fixup (parent, wsock_mtx, "wsock_mtx");
+  fork_fixup (parent, wsock_evt, "wsock_evt");
+  fhandler_base::fixup_after_fork (parent);
 }
 
 int
 fhandler_socket::dup (fhandler_base *child)
 {
-  HANDLE nh;
-
   debug_printf ("here");
   fhandler_socket *fhs = (fhandler_socket *) child;
 
   if (!DuplicateHandle (hMainProc, wsock_mtx, hMainProc, &fhs->wsock_mtx, 0,
                        TRUE, DUPLICATE_SAME_ACCESS))
     {
-      system_printf ("DuplicateHandle(%x) failed, %E", wsock_mtx);
       __seterrno ();
       return -1;
     }
   if (!DuplicateHandle (hMainProc, wsock_evt, hMainProc, &fhs->wsock_evt, 0,
                        TRUE, DUPLICATE_SAME_ACCESS))
     {
-      system_printf ("DuplicateHandle(%x) failed, %E", wsock_evt);
       __seterrno ();
       CloseHandle (fhs->wsock_mtx);
       return -1;
@@ -698,48 +639,13 @@ fhandler_socket::dup (fhandler_base *child)
        }
     }
   fhs->connect_state (connect_state ());
-
-  /* Since WSADuplicateSocket() fails on NT systems when the process
-     is currently impersonating a non-privileged account, we revert
-     to the original account before calling WSADuplicateSocket() and
-     switch back afterwards as it's also in fork().
-     If WSADuplicateSocket() still fails for some reason, we fall back
-     to DuplicateHandle(). */
-  WSASetLastError (0);
-  cygheap->user.deimpersonate ();
-  fhs->set_io_handle (get_io_handle ());
-  fhs->fixup_before_fork_exec (GetCurrentProcessId ());
-  cygheap->user.reimpersonate ();
-  if (!WSAGetLastError ())
-    {
-      /* Call with NULL parent, otherwise wsock_mtx and wsock_evt are
-         duplicated again with wrong close_on_exec settings. */
-      fhs->fixup_after_fork (NULL);
-      if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
-       {
-         cygheap->fdtab.inc_need_fixup_before ();
-         return 0;
-       }
-    }
-  debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
-
-  /* We don't call fhandler_base::dup here since that requires
-     having winsock called from fhandler_base and it creates only
-     inheritable sockets which is wrong for winsock2. */
-
-  if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
-                       FALSE, DUPLICATE_SAME_ACCESS))
+  int ret = fhandler_base::dup (child);
+  if (ret)
     {
-      system_printf ("DuplicateHandle(%x) failed, %E", get_io_handle ());
-      __seterrno ();
       CloseHandle (fhs->wsock_evt);
       CloseHandle (fhs->wsock_mtx);
-      return -1;
     }
-  VerifyHandle (nh);
-  fhs->set_io_handle (nh);
-  cygheap->fdtab.inc_need_fixup_before ();
-  return 0;
+  return ret;
 }
 
 int __stdcall
@@ -1379,7 +1285,8 @@ fhandler_socket::send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags,
         wsock_events->events &= ~FD_WRITE;
       UNLOCK_EVENTS;
     }
-  while (res && err && !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
+  while (res && err == WSAEWOULDBLOCK
+        && !(res = wait_for_events (FD_WRITE | FD_CLOSE)));
 
   if (res == SOCKET_ERROR)
     set_winsock_errno ();
@@ -1682,7 +1589,7 @@ fhandler_socket::set_close_on_exec (bool val)
 {
   set_no_inheritance (wsock_mtx, val);
   set_no_inheritance (wsock_evt, val);
-  close_on_exec (val);
+  fhandler_base::set_close_on_exec (val);
   debug_printf ("set close_on_exec for %s to %d", get_name (), val);
 }
 
index 80f34a8..87a4135 100644 (file)
@@ -501,14 +501,16 @@ cygwin_getprotobynumber (int number)
 bool
 fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
 {
-  if (wincap.has_set_handle_information ())
+  /* NT systems apparently set sockets to inheritable by default */
+  if (!wincap.has_set_handle_information ()
+      && !DuplicateHandle (hMainProc, (HANDLE) soc,
+                          hMainProc, (HANDLE *) &soc,
+                          0, TRUE,
+                          DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
     {
-      /* NT systems apparently set sockets to inheritable by default */
-      SetHandleInformation ((HANDLE) soc, HANDLE_FLAG_INHERIT, 0);
-      debug_printf ("reset socket inheritance");
+      debug_printf ("set socket inheritance failed, %E");
+      return false;
     }
-  else
-    debug_printf ("not setting socket inheritance");
   fd = build_fh_dev (*dev);
   if (!fd.isopen ())
     return false;
@@ -517,7 +519,6 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
     return false;
   fd->set_flags (O_RDWR | O_BINARY);
   fd->uninterruptible_io (true);
-  cygheap->fdtab.inc_need_fixup_before ();
   debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
 #if 0
   /* Same default buffer sizes as on Linux (instead of WinSock default 8K).
index a1abba6..abfe9e5 100644 (file)
@@ -1279,7 +1279,7 @@ peek_socket (select_record *me, bool)
        me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
     }
   if (me->except_selected)
-    me->except_ready |= ret || !!(events & (FD_OOB | FD_CLOSE));
+    me->except_ready |= ret || !!(events & FD_OOB);
 
   return me->read_ready || me->write_ready || me->except_ready;
 }