From 19ba6f2195b2e7f87cd1aac75cd28335ca94b1ff Mon Sep 17 00:00:00 2001
From: Christopher Faylor <me@cgf.cx>
Date: Tue, 30 Oct 2001 07:43:46 +0000
Subject: [PATCH] * dtable.cc (dtable::dup2): Add some debugging.  Use methods
 from passed in class rather than cygheap->fdtab. * fhandler_socket.cc
 (fhandler_socket::fixup_before_fork_exec): Add more debugging output.
 (fhandler_socket::dup): Allocate new space for prot_info_ptr for duplicated
 entry. * syscalls.cc (stat_worker): Always delete fh if it has been created.

---
 winsup/cygwin/ChangeLog          | 10 ++++++++++
 winsup/cygwin/dtable.cc          |  7 ++++---
 winsup/cygwin/fhandler_socket.cc | 20 +++++++++++---------
 winsup/cygwin/syscalls.cc        |  3 ++-
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 67a1a80be..efe6926da 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,13 @@
+2001-10-30  Christopher Faylor  <cgf@redhat.com>
+
+	* dtable.cc (dtable::dup2): Add some debugging.  Use methods from
+	passed in class rather than cygheap->fdtab.
+	* fhandler_socket.cc (fhandler_socket::fixup_before_fork_exec): Add
+	more debugging output.
+	(fhandler_socket::dup): Allocate new space for prot_info_ptr for
+	duplicated entry.
+	* syscalls.cc (stat_worker): Always delete fh if it has been created.
+
 2001-10-29  Corinna Vinschen  <corinna@vinschen.de>
 
 	* security.cc (is_group_member): Call NetLocalGroupGetMembers() for
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index f82be14a2..4a14712a3 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -383,6 +383,7 @@ dtable::dup2 (int oldfd, int newfd)
       goto done;
     }
 
+  debug_printf ("newfh->io_handle %p, oldfh->io_handle %p", newfh->get_io_handle (), fds[oldfd]->get_io_handle ());
   SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
 
   if (newfd < 0)
@@ -392,11 +393,11 @@ dtable::dup2 (int oldfd, int newfd)
       goto done;
     }
 
-  if ((size_t) newfd >= cygheap->fdtab.size)
+  if ((size_t) newfd >= size)
    {
      int inc_size = NOFILE_INCR * ((newfd + NOFILE_INCR - 1) / NOFILE_INCR) -
-		    cygheap->fdtab.size;
-     cygheap->fdtab.extend (inc_size);
+		    size;
+     extend (inc_size);
    }
 
   if (!not_open (newfd))
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index ae8df07a1..9784118d5 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -169,11 +169,12 @@ fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
       debug_printf ("Without Winsock 2.0");
     }
   else if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
-    debug_printf ("WSADuplicateSocket went fine, dwServiceFlags1=%d",
-		  prot_info_ptr->dwServiceFlags1);
+    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");
+      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 ();
     }
 }
@@ -203,7 +204,7 @@ fhandler_socket::fixup_after_fork (HANDLE parent)
     }
   else
     {
-      debug_printf ("WSASocket went fine %p", new_sock);
+      debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_io_handle ());
       set_io_handle ((HANDLE) new_sock);
     }
 
@@ -230,6 +231,9 @@ fhandler_socket::dup (fhandler_base *child)
   fhandler_socket *fhs = (fhandler_socket *) child;
   fhs->addr_family = addr_family;
   fhs->set_io_handle (get_io_handle ());
+
+  fhs->prot_info_ptr = (LPWSAPROTOCOL_INFOA)
+    cmalloc (HEAP_BUF, sizeof (WSAPROTOCOL_INFOA));
   fhs->fixup_before_fork_exec (GetCurrentProcessId ());
   if (winsock2_active)
     {
@@ -287,11 +291,9 @@ fhandler_socket::close ()
   setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
 	      (const char *)&linger, sizeof linger);
 
-  if (closesocket (get_socket ()))
-    {
-      set_winsock_errno ();
-      res = -1;
-    }
+  while (closesocket (get_socket ())
+         && WSAGetLastError () == WSAEWOULDBLOCK)
+    continue;
 
   close_secret_event ();
 
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index bfd5af8b6..637ecaf90 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1026,10 +1026,11 @@ stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
 	  	    pc, (DWORD) real_path);
       memset (buf, 0, sizeof (struct stat));
       res = fh->fstat (buf, pc);
-      delete fh;
     }
 
  done:
+  if (fh)
+    delete fh;
   MALLOC_CHECK;
   syscall_printf ("%d = (%s, %p)", res, name, buf);
   return res;