Index: winsup/cygwin/fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.290
diff -p -u -r1.290 fhandler.h
--- winsup/cygwin/fhandler.h	25 May 2006 05:40:51 -0000	1.290
+++ winsup/cygwin/fhandler.h	29 May 2006 02:11:49 -0000
@@ -967,6 +967,7 @@ class fhandler_tty_common: public fhandl
   select_record *select_write (select_record *s);
   select_record *select_except (select_record *s);
   bool is_slow () {return 1;}
+  virtual void pre_eof_hook (void);
 };
 
 class fhandler_tty_slave: public fhandler_tty_common
@@ -1023,6 +1024,7 @@ public:
   void set_close_on_exec (bool val);
   bool hit_eof ();
   int get_unit () const { return slave.minor; }
+  virtual void pre_eof_hook (void);
 };
 
 class fhandler_tty_master: public fhandler_pty_master
Index: winsup/cygwin/fhandler_tty.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_tty.cc,v
retrieving revision 1.166
diff -p -u -r1.166 fhandler_tty.cc
--- winsup/cygwin/fhandler_tty.cc	22 May 2006 04:50:54 -0000	1.166
+++ winsup/cygwin/fhandler_tty.cc	29 May 2006 02:11:49 -0000
@@ -1207,6 +1207,8 @@ fhandler_tty_common::close ()
   if (!get_ttyp ()->master_alive ())
     {
       termios_printf ("no more masters left. sending EOF");
+      /* If this is the master, it needs to close the master pipes now.  */
+      pre_eof_hook ();
       SetEvent (input_available_event);
     }
 
@@ -1221,6 +1223,34 @@ fhandler_tty_common::close ()
   return 0;
 }
 
+void
+fhandler_tty_common::pre_eof_hook (void)
+{
+  /* Nothing is needed in the slave/default case.  */
+}
+
+void
+fhandler_pty_master::pre_eof_hook (void)
+{
+  termios_printf ("freeing tty%d (%d)", get_unit (), get_ttyp ()->ntty);
+#if 0
+  if (get_ttyp ()->to_slave)
+    ForceCloseHandle1 (get_ttyp ()->to_slave, to_slave);
+  if (get_ttyp ()->from_slave)
+    ForceCloseHandle1 (get_ttyp ()->from_slave, from_slave);
+#endif
+  /* We must close the master pipes before the input_available_event is
+  signalled, or there is a race condition where the slave might see it as
+  a read of zero bytes instead of an EOF meaning SIGHUP.  */
+  if (get_ttyp ()->from_master)
+    CloseHandle (get_ttyp ()->from_master);
+  if (get_ttyp ()->to_master)
+    CloseHandle (get_ttyp ()->to_master);
+
+  if (!hExeced)
+    get_ttyp ()->init ();
+}
+
 int
 fhandler_pty_master::close ()
 {
@@ -1229,27 +1259,7 @@ fhandler_pty_master::close ()
     continue;
 #endif
 
-  if (get_ttyp ()->master_alive ())
-    fhandler_tty_common::close ();
-  else
-    {
-      termios_printf ("freeing tty%d (%d)", get_unit (), get_ttyp ()->ntty);
-#if 0
-      if (get_ttyp ()->to_slave)
-	ForceCloseHandle1 (get_ttyp ()->to_slave, to_slave);
-      if (get_ttyp ()->from_slave)
-	ForceCloseHandle1 (get_ttyp ()->from_slave, from_slave);
-#endif
-      if (get_ttyp ()->from_master)
-	CloseHandle (get_ttyp ()->from_master);
-      if (get_ttyp ()->to_master)
-	CloseHandle (get_ttyp ()->to_master);
-
-      fhandler_tty_common::close ();
-
-      if (!hExeced)
-	get_ttyp ()->init ();
-    }
+  fhandler_tty_common::close ();
 
   return 0;
 }
