]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().
authorChristopher Faylor <me@cgf.cx>
Thu, 5 May 2011 22:30:53 +0000 (22:30 +0000)
committerChristopher Faylor <me@cgf.cx>
Thu, 5 May 2011 22:30:53 +0000 (22:30 +0000)
* debug.cc (close_handle): Call debugger on failure.
* devices.in (device::tty_to_real_device): Delete.
* devices.h (device::tty_to_real_device): Ditto.
* devices.cc: Regenerate.
* dtable.cc: Delete old ifdef'ed vfork code.
(dtable::release): Don't handle archetype here.
(dtable::init_std_file_from_handle): Consolidate console tests.  Generate
major/minor for tty ASAP.  Fix incorrect setting of DEV_TTYS* for serial.
(fh_alloc): New function derived from build_fh_pc.  Pass current tty when
building tty.
(build_pc_pc): Use fh_alloc to create.  Set name from fh->dev if appropriate.
Generate an archetype or point to one here.
(dtable::dup_worker): Deal with archetypes.  Rely on = operator copying whole
class rather than just fhandler_base.
(dtable::fixup_after_exec): Call close_with_arch to handle closing of fhandlers
with archetypes.
* fhandler.cc (fhandler_base::operator =): Call memcpy with fhandler's size()
rather than sizeof fhandler_base.
(fhandler_base::open_with_arch): New function.  Handles opening of fhandler's
with archetypes, dealing with usecounts, etc.
(fhandler_base::close_with_arch): Ditto for close.
* fhandler.h: Many changes for archetypes.
(fhandler_base::set_name): Set both normalized path and regular path.
(fhandler_base::open_with_arch): New function.
(fhandler_base::open_setup): Ditto.
(fhandler_base::use_archetype): Ditto.
(fhandler_base::_archetype_usecount): Ditto.
(fhandler_*::size): Ditto.
(fhandler_dev_tape::open): Remove virtual decoration.
(fhandler_console::use_archetype): New function.  Return true.
(fhandler_console::open_setup): New function.
(fhandler_console::dup): Delete.
(fhandler_tty_slave::fhandler_tty_slave): Redeclare to take an argument.
(fhandler_tty_slave::use_archetype): New function.  Return true.
(fhandler_tty_slave::cleanup): New function.
(fhandler_pty_master::use_archetype): New function.  Return true.
(fhandler_pty_master::cleanup): New function.
(fhandler_pty_master::is_tty_master): New function.  Return false.
(fhandler_tty_master::is_tty_master): New function.  Return true.
(fhandler_dev_dsp::fhandler_dev_dsp): New function.  Return true.
(report_tty_counts): Only report on archetype's usecount if there is one.
* fhandler_console.cc (fhandler_console::get_tty_stuff): Remove handling of
setsid, set_ctty, set_flags, and manage_console_count.
(fhandler_console::open_setup): New function.  Implement functionality removed
from get_tty_stuff.
(fhandler_console::dup): Delete.
(fhandler_console::output_tcsetattr): Set errno on error.
(fhandler_console::fhandler_console): Set device early.
(fhandler_console::init): Use open_with_arch to open console handles.
(fhandler_console::fixup_after_fork_exec): Nuke most of the stuff for dealing
with console handles.
* fhandler_dsp.cc (fhandler_dev_dsp::open): Remove archetype handling.
(fhandler_dev_dsp::write): Ditto.
(fhandler_dev_dsp::read): Ditto.
(fhandler_dev_dsp::close): Ditto.
(fhandler_dev_dsp::dup): Ditto.
(fhandler_dev_dsp::ioctl): Ditto.
(fhandler_dev_dsp::fixup_after_fork): Ditto.
(fhandler_dev_dsp::fixup_after_exec): Ditto.
* fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Add a little
more debugging.
(fhandler_tty_common::__release_output_mutex): Ditto.
(fhandler_pty_master::process_slave_output): Ditto.  Don't do signal handling
or pthread_cancel handling in the tty master thread.
(process_output): Minor reorg.
(fhandler_tty_slave::fhandler_tty_slave): Set device based on new ntty
argument.
(fhandler_tty_slave::open): Remove archetype handling.  Move some processing
into open_setup().
(fhandler_tty_slave::open_setup): New function.
(fhandler_tty_slave::cleanup): New function.
(fhandler_tty_slave::close): Remove archetype handling.  Move some processing
into cleanup().
(fhandler_tty_slave::init): Rename argument from f to h.  Open device using
open_with_arch().  Remove archetype handling.
(fhandler_pty_master::dup): Ditto.
(fhandler_pty_master::open): Ditto.
(fhandler_pty_master::close): Ditto.  Move some handling to cleanup().
(fhandler_pty_master::cleanup): New function.
(fhandler_tty_master::init_console): Give unique name to captive console
fhandler.
* pinfo.cc (_pinfo::set_ctty): Rename argument from arch to fh.  Eliminate
archetype assumption.
* syscalls.cc (close_all_files): Use close_with_arch for closing.
(open): Use open_with_arch() rather than open().
(close): Use close_with_arch() rather than close().

14 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.cc
winsup/cygwin/debug.cc
winsup/cygwin/devices.cc
winsup/cygwin/devices.h
winsup/cygwin/devices.in
winsup/cygwin/dtable.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_dsp.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/syscalls.cc

index df65b3bf5b3e7eddfbc67106331464ecb0856f0c..7ef8f010152a727c25cf037eab12acbd6703a725 100644 (file)
@@ -1,3 +1,96 @@
+2011-05-05  Christopher Faylor  <me.cygwin2011@cgf.cx>
+
+       * cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().
+       * debug.cc (close_handle): Call debugger on failure.
+       * devices.in (device::tty_to_real_device): Delete.
+       * devices.h (device::tty_to_real_device): Ditto.
+       * devices.cc: Regenerate.
+       * dtable.cc: Delete old ifdef'ed vfork code.
+       (dtable::release): Don't handle archetype here.
+       (dtable::init_std_file_from_handle): Consolidate console tests.
+       Generate major/minor for tty ASAP.  Fix incorrect setting of DEV_TTYS*
+       for serial.
+       (fh_alloc): New function derived from build_fh_pc.  Pass current tty
+       when building tty.
+       (build_pc_pc): Use fh_alloc to create.  Set name from fh->dev if
+       appropriate.  Generate an archetype or point to one here.
+       (dtable::dup_worker): Deal with archetypes.  Rely on = operator copying
+       whole class rather than just fhandler_base.
+       (dtable::fixup_after_exec): Call close_with_arch to handle closing of
+       fhandlers with archetypes.
+       * fhandler.cc (fhandler_base::operator =): Call memcpy with fhandler's
+       size() rather than sizeof fhandler_base.
+       (fhandler_base::open_with_arch): New function.  Handles opening of
+       fhandler's with archetypes, dealing with usecounts, etc.
+       (fhandler_base::close_with_arch): Ditto for close.
+       * fhandler.h: Many changes for archetypes.
+       (fhandler_base::set_name): Set both normalized path and regular path.
+       (fhandler_base::open_with_arch): New function.
+       (fhandler_base::open_setup): Ditto.
+       (fhandler_base::use_archetype): Ditto.
+       (fhandler_base::_archetype_usecount): Ditto.
+       (fhandler_*::size): Ditto.
+       (fhandler_dev_tape::open): Remove virtual decoration.
+       (fhandler_console::use_archetype): New function.  Return true.
+       (fhandler_console::open_setup): New function.
+       (fhandler_console::dup): Delete.
+       (fhandler_tty_slave::fhandler_tty_slave): Redeclare to take an
+       argument.
+       (fhandler_tty_slave::use_archetype): New function.  Return true.
+       (fhandler_tty_slave::cleanup): New function.
+       (fhandler_pty_master::use_archetype): New function.  Return true.
+       (fhandler_pty_master::cleanup): New function.
+       (fhandler_pty_master::is_tty_master): New function.  Return false.
+       (fhandler_tty_master::is_tty_master): New function.  Return true.
+       (fhandler_dev_dsp::fhandler_dev_dsp): New function.  Return true.
+       (report_tty_counts): Only report on archetype's usecount if there is
+       one.
+       * fhandler_console.cc (fhandler_console::get_tty_stuff): Remove
+       handling of setsid, set_ctty, set_flags, and manage_console_count.
+       (fhandler_console::open_setup): New function.  Implement functionality
+       removed from get_tty_stuff.
+       (fhandler_console::dup): Delete.
+       (fhandler_console::output_tcsetattr): Set errno on error.
+       (fhandler_console::fhandler_console): Set device early.
+       (fhandler_console::init): Use open_with_arch to open console handles.
+       (fhandler_console::fixup_after_fork_exec): Nuke most of the stuff for
+       dealing with console handles.
+       * fhandler_dsp.cc (fhandler_dev_dsp::open): Remove archetype handling.
+       (fhandler_dev_dsp::write): Ditto.
+       (fhandler_dev_dsp::read): Ditto.
+       (fhandler_dev_dsp::close): Ditto.
+       (fhandler_dev_dsp::dup): Ditto.
+       (fhandler_dev_dsp::ioctl): Ditto.
+       (fhandler_dev_dsp::fixup_after_fork): Ditto.
+       (fhandler_dev_dsp::fixup_after_exec): Ditto.
+       * fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Add a
+       little more debugging.
+       (fhandler_tty_common::__release_output_mutex): Ditto.
+       (fhandler_pty_master::process_slave_output): Ditto.  Don't do signal
+       handling or pthread_cancel handling in the tty master thread.
+       (process_output): Minor reorg.
+       (fhandler_tty_slave::fhandler_tty_slave): Set device based on new ntty
+       argument.
+       (fhandler_tty_slave::open): Remove archetype handling.  Move some
+       processing into open_setup().
+       (fhandler_tty_slave::open_setup): New function.
+       (fhandler_tty_slave::cleanup): New function.
+       (fhandler_tty_slave::close): Remove archetype handling.  Move some
+       processing into cleanup().
+       (fhandler_tty_slave::init): Rename argument from f to h.  Open device
+       using open_with_arch().  Remove archetype handling.
+       (fhandler_pty_master::dup): Ditto.
+       (fhandler_pty_master::open): Ditto.
+       (fhandler_pty_master::close): Ditto.  Move some handling to cleanup().
+       (fhandler_pty_master::cleanup): New function.
+       (fhandler_tty_master::init_console): Give unique name to captive
+       console fhandler.
+       * pinfo.cc (_pinfo::set_ctty): Rename argument from arch to fh.
+       Eliminate archetype assumption.
+       * syscalls.cc (close_all_files): Use close_with_arch for closing.
+       (open): Use open_with_arch() rather than open().
+       (close): Use close_with_arch() rather than close().
+
 2011-05-05  Corinna Vinschen  <corinna@vinschen.de>
 
        * pinfo.h (class push_process_state): New class to push a process state
index 8dde3dfe9cf31decb397b663f7367470ff24e8b9..8a2a1f4dc374ed28f1c9ec212a39afbf54b69e23 100644 (file)
@@ -107,11 +107,7 @@ void
 init_cygheap::close_ctty ()
 {
   debug_printf ("closing cygheap->ctty %p", cygheap->ctty);
-  /* FIXME: Support for console-as-ctty is limited due to the fact that
-     the console doesn't use archetypes - even though they could and should */
-  if (cygheap->ctty->get_ttyp ()
-      && cygheap->ctty->get_ttyp ()->ntty != TTY_CONSOLE)
-    cygheap->ctty->close ();
+  cygheap->ctty->close_with_arch ();
   cygheap->ctty = NULL;
 }
 
index bea256cae5284bb68de94eb0e1cac980016dc587..3e2aa11451b8425eff002ef1349d8fab15e67043 100644 (file)
@@ -226,7 +226,10 @@ close_handle (const char *func, int ln, HANDLE h, const char *name, bool force)
   ret = CloseHandle (h);
 
   if (!ret)
-    small_printf ("CloseHandle(%s<%p>) failed %s:%d, %E\n", name, h, func, ln);
+    {
+      system_printf ("CloseHandle(%s<%p>) failed %s:%d, %E", name, h, func, ln);
+      try_to_debug ();
+    }
   return ret;
 }
 #endif /*DEBUGGING*/
index 569d239e133b2838bedda64fba8a3077288071e5..0bcaae0bc9fa7c2d41040c8daa3600f3ab43a6a9 100644 (file)
@@ -43439,15 +43439,6 @@ device::parse (_dev_t dev)
   parse (_major (dev), _minor (dev));
 }
 
-void
-device::tty_to_real_device ()
-{
-  if (!real_tty_attached (myself))
-    *this = myself->ctty < 0 ? dev_bad_storage : *console_dev;
-  else
-    parse (DEV_TTYS_MAJOR, myself->ctty);
-}
-
 void
 device::parsedisk (int drive, int part)
 {
index b4927f1ba7ec67aa3c4aaeea497bd94750301925..5c9909a5f0d1a95407928afd802bce5e93a87f69 100644 (file)
@@ -268,7 +268,6 @@ struct device
     return true;
   }
   static void init ();
-  void tty_to_real_device ();
   inline operator int () const {return devn;}
   inline void setfs (bool x) {dev_on_fs = x;}
   inline bool isfs () const {return dev_on_fs || devn == FH_FS;}
index 7ce8994bbb06cb0e0dcc7ee53b13d5282baf8770..1b59d9493e38c4e3ae87c670f4fb42687115d5a6 100644 (file)
@@ -146,15 +146,6 @@ device::parse (_dev_t dev)
   parse (_major (dev), _minor (dev));
 }
 
-void
-device::tty_to_real_device ()
-{
-  if (!real_tty_attached (myself))
-    *this = myself->ctty < 0 ? dev_bad_storage : *console_dev;
-  else
-    parse (DEV_TTYS_MAJOR, myself->ctty);
-}
-
 void
 device::parsedisk (int drive, int part)
 {
index 5fbe0f4b90895778e335bd478f55c4a0d0ab167a..654526065efcf36e20fda87eb82687fa286903d7 100644 (file)
@@ -245,10 +245,7 @@ dtable::release (int fd)
     {
       if (fds[fd]->need_fixup_before ())
        dec_need_fixup_before ();
-      fhandler_base *arch = fds[fd]->archetype;
       delete fds[fd];
-      if (arch && !arch->usecount)
-       cygheap->fdtab.delete_archetype (arch);
       fds[fd] = NULL;
     }
 }
@@ -309,25 +306,20 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
       else
        dev = *pipew_dev;
     }
-  else if (GetConsoleScreenBufferInfo (handle, &buf))
+  else if (GetConsoleScreenBufferInfo (handle, &buf)
+          || GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
     {
-      /* Console output */
-      if (ISSTATE (myself, PID_USETTY))
-       dev.parse (FH_TTY);
-      else
+      /* Console I/O */
+      if (!ISSTATE (myself, PID_USETTY))
        dev = *console_dev;
-    }
-  else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
-    {
-      /* Console input */
-      if (ISSTATE (myself, PID_USETTY))
-       dev.parse (FH_TTY);
+      else if (myself->ctty >= 0)
+       dev.parse (DEV_TTYS_MAJOR, myself->ctty);
       else
-       dev = *console_dev;
+       dev.parse (FH_TTY);
     }
   else if (GetCommState (handle, &dcb))
-    /* serial */
-    dev.parse (DEV_TTYS_MAJOR, 0);
+    /* FIXME: Not right - assumes ttyS0 */
+    dev.parse (DEV_SERIAL_MAJOR, 0);
   else
     /* Try to figure it out from context - probably a disk file */
     handle_to_fn (handle, name);
@@ -434,15 +426,15 @@ build_fh_dev (const device& dev, const char *unix_name)
 }
 
 #define fh_unset ((fhandler_base *) 1)
-fhandler_base *
-build_fh_pc (path_conv& pc, bool set_name)
+static fhandler_base *
+fh_alloc (device dev)
 {
   fhandler_base *fh = fh_unset;
 
-  switch (pc.dev.major)
+  switch (dev.major)
     {
     case DEV_TTYS_MAJOR:
-      fh = cnew (fhandler_tty_slave) ();
+      fh = cnew (fhandler_tty_slave) (dev.minor);
       break;
     case DEV_TTYM_MAJOR:
       fh = cnew (fhandler_tty_master) ();
@@ -469,7 +461,7 @@ build_fh_pc (path_conv& pc, bool set_name)
       fh = cnew (fhandler_serial) ();
       break;
     default:
-      switch (pc.dev)
+      switch (dev)
        {
        case FH_CONSOLE:
        case FH_CONIN:
@@ -548,8 +540,8 @@ build_fh_pc (path_conv& pc, bool set_name)
          {
            if (myself->ctty == TTY_CONSOLE)
              fh = cnew (fhandler_console) ();
-           else if (myself->ctty >= 0)
-             fh = cnew (fhandler_tty_slave) ();
+           else
+             fh = cnew (fhandler_tty_slave) (myself->ctty);
            break;
          }
        case FH_KMSG:
@@ -560,12 +552,34 @@ build_fh_pc (path_conv& pc, bool set_name)
 
   if (fh == fh_unset)
     fh = cnew (fhandler_nodevice) ();
+  return fh;
+}
+
+fhandler_base *
+build_fh_pc (path_conv& pc, bool set_name)
+{
+  fhandler_base *fh = fh_alloc (pc.dev);
 
   if (!fh)
     set_errno (EMFILE);
+  else if (fh->dev () != FH_BAD)
+    fh->set_name (fh->dev ().name);
   else if (set_name)
     fh->set_name (pc);
 
+  if (!fh->use_archetype ())
+    /* doesn't use archetypes */;
+  else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ())))
+    debug_printf ("found an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().major, fh->dev ().minor);
+  else
+    {
+      debug_printf ("creating an archetype for %s(%d/%d)", fh->get_name (), fh->dev ().major, fh->dev ().minor);
+      fh->archetype = fh_alloc (fh->pc.dev);
+      *fh->archetype = *fh;
+      fh->archetype->archetype = NULL;
+      *cygheap->fdtab.add_archetype () = fh->archetype;
+    }
+
   debug_printf ("fh %p", fh);
   return fh;
 }
@@ -582,7 +596,8 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
   else
     {
       *newfh = *oldfh;
-      newfh->set_io_handle (NULL);
+      if (!oldfh->archetype)
+       newfh->set_io_handle (NULL);
       newfh->pc.reset_conv_handle ();
       if (oldfh->dup (newfh))
        {
@@ -592,11 +607,10 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
        }
       else
        {
+         newfh->usecount = 0;
+         newfh->archetype_usecount (1);
          /* The O_CLOEXEC flag enforces close-on-exec behaviour. */
-         if (flags & O_CLOEXEC)
-           newfh->set_close_on_exec (true);
-         else
-           newfh->close_on_exec (false);
+         newfh->set_close_on_exec (!!(flags & O_CLOEXEC));
          debug_printf ("duped '%s' old %p, new %p", oldfh->get_name (), oldfh->get_io_handle (), newfh->get_io_handle ());
        }
     }
@@ -754,7 +768,7 @@ dtable::fixup_after_exec ()
            if (fh->archetype)
              {
                debug_printf ("closing fd %d since it is an archetype", i);
-               fh->close ();
+               fh->close_with_arch ();
              }
            release (i);
          }
@@ -786,102 +800,6 @@ dtable::fixup_after_fork (HANDLE parent)
       }
 }
 
-#ifdef NEWVFORK
-int
-dtable::vfork_child_dup ()
-{
-  fhandler_base **newtable;
-  lock ();
-  newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof (fds[0]));
-  int res = 1;
-
-  /* Remove impersonation */
-  cygheap->user.deimpersonate ();
-  if (cygheap->ctty)
-    {
-      cygheap->ctty->usecount++;
-      cygheap->console_count++;
-      report_tty_counts (cygheap->ctty, "vfork dup", "incremented ", "");
-    }
-
-  for (size_t i = 0; i < size; i++)
-    if (not_open (i))
-      continue;
-    else if ((newtable[i] = dup_worker (fds[i])) != NULL)
-      newtable[i]->set_close_on_exec (fds[i]->close_on_exec ());
-    else
-      {
-       res = 0;
-       goto out;
-      }
-
-  fds_on_hold = fds;
-  fds = newtable;
-
-out:
-  /* Restore impersonation */
-  cygheap->user.reimpersonate ();
-
-  unlock ();
-  return 1;
-}
-
-void
-dtable::vfork_parent_restore ()
-{
-  lock ();
-
-  fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
-  close_all_files ();
-  fhandler_base **deleteme = fds;
-  fds = fds_on_hold;
-  fds_on_hold = NULL;
-  cfree (deleteme);
-  unlock ();
-
-  if (cygheap->ctty != ctty_on_hold)
-    {
-      cygheap->ctty = ctty_on_hold;            // revert
-      cygheap->ctty->close ();                 // Undo previous bump of this archetype
-    }
-  cygheap->ctty_on_hold = NULL;
-}
-
-void
-dtable::vfork_child_fixup ()
-{
-  if (!fds_on_hold)
-    return;
-  debug_printf ("here");
-  fhandler_base **saveme = fds;
-  fds = fds_on_hold;
-
-  fhandler_base *fh;
-  for (int i = 0; i < (int) size; i++)
-    if ((fh = fds[i]) != NULL)
-      {
-       fh->clear_readahead ();
-       if (!fh->archetype && fh->close_on_exec ())
-         release (i);
-       else
-         {
-           fh->close ();
-           release (i);
-         }
-      }
-
-  fds = saveme;
-  cfree (fds_on_hold);
-  fds_on_hold = NULL;
-
-  if (cygheap->ctty_on_hold)
-    {
-      cygheap->ctty_on_hold->close ();
-      cygheap->ctty_on_hold = NULL;
-    }
-}
-#endif /*NEWVFORK*/
-
 static void
 decode_tty (char *buf, WCHAR *w32)
 {
index 9fad7ce4d8d0f15ef3657729b74fda91fdb93b3f..304feed630e9da8b50739e5df0eca36dbf9a7810 100644 (file)
@@ -39,7 +39,7 @@ struct __cygwin_perfile *perfile_table;
 inline fhandler_base&
 fhandler_base::operator =(fhandler_base& x)
 {
-  memcpy (this, &x, sizeof *this);
+  memcpy (this, &x, size ());
   pc = x.pc;
   rabuf = NULL;
   ralen = 0;
@@ -449,6 +449,40 @@ done:
   return res;
 }
 
+int
+fhandler_base::open_with_arch (int flags, mode_t mode)
+{
+  int res;
+  close_on_exec (flags & O_CLOEXEC);
+  if (!(res = (archetype && archetype->io_handle)
+       || open (flags, (mode & 07777) & ~cygheap->umask)))
+    {
+      if (archetype)
+       delete archetype;
+    }
+  else if (archetype)
+    {
+      if (!archetype->io_handle)
+       {
+         usecount = 0;
+         *archetype = *this;
+         archetype_usecount (1);
+         archetype->archetype = NULL;
+       }
+      else
+       {
+         fhandler_base *arch = archetype;
+         *this = *archetype;
+         archetype = arch;
+         archetype_usecount (1);
+         usecount = 0;
+       }
+      open_setup (flags);
+    }
+
+  return res;
+}
+
 /* Open system call handler function. */
 int
 fhandler_base::open (int flags, mode_t mode)
@@ -1029,6 +1063,48 @@ fhandler_base::pwrite (void *, size_t, _off64_t)
   return -1;
 }
 
+int
+fhandler_base::close_with_arch ()
+{
+  int res;
+  fhandler_base *fh;
+  if (usecount)
+    {
+      if (!--usecount)
+       debug_printf ("closing passed in archetype, usecount %d", usecount);
+      else
+       {
+         debug_printf ("not closing passed in archetype, usecount %d", usecount);
+         return 0;
+       }
+      fh = this;
+    }
+  else if (!archetype)
+    fh = this;
+  else
+    {
+      cleanup ();
+      if (archetype_usecount (-1) == 0)
+       {
+         debug_printf ("closing archetype");
+         fh = archetype;
+       }
+      else
+       {
+         debug_printf ("not closing archetype");
+         return 0;
+       }
+    }
+
+  res = fh->close ();
+  if (archetype)
+    {
+      cygheap->fdtab.delete_archetype (archetype);
+      archetype = NULL;
+    }
+  return res;
+}
+
 int
 fhandler_base::close ()
 {
index 14922b8b9fad7fc12e27ca7606b3bb148ba1af61..6ceaff33ab7642a172f1243c773a6d2fe0458134 100644 (file)
@@ -178,8 +178,13 @@ class fhandler_base
 
   path_conv pc;
 
+  virtual bool use_archetype () const {return false;}
   virtual void set_name (path_conv &pc);
-  virtual void set_name (const char *s) {pc.set_normalized_path (s);}
+  virtual void set_name (const char *s)
+  {
+    pc.set_normalized_path (s);
+    pc.set_path (s);
+  }
   int error () const {return pc.error;}
   void set_error (int error) {pc.error = error;}
   bool exists () const {return pc.exists ();}
@@ -290,9 +295,24 @@ class fhandler_base
   bool fork_fixup (HANDLE, HANDLE &, const char *);
   virtual bool need_fixup_before () const {return false;}
 
-  virtual int open (int, mode_t = 0);
+  int open_with_arch (int, mode_t = 0);
+  virtual int open (int, mode_t);
+  virtual void open_setup (int flags) { return; }
+
   int open_fs (int, mode_t = 0);
+  virtual int close_with_arch ();
   virtual int close ();
+  virtual void cleanup () { return; }
+  int _archetype_usecount (const char *fn, int ln, int n)
+  {
+    if (!archetype)
+      return 0;
+    archetype->usecount += n;
+    if (strace.active ())
+      strace.prntf (_STRACE_ALL, fn, "line %d:  %s<%p> usecount + %d = %d", ln, get_name (), archetype, n, archetype->usecount);
+    return archetype->usecount;
+  }
+# define archetype_usecount(n) _archetype_usecount (__PRETTY_FUNCTION__, __LINE__, (n))
   int close_fs () { return fhandler_base::close (); }
   virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
@@ -548,6 +568,7 @@ class fhandler_socket: public fhandler_base
   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
   int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
   int __stdcall link (const char *) __attribute__ ((regparm (2)));
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_base_overlapped: public fhandler_base
@@ -612,6 +633,7 @@ public:
   static int create (fhandler_pipe *[2], unsigned, int);
   static int create_selectable (LPSECURITY_ATTRIBUTES, HANDLE&, HANDLE&, DWORD, const char * = NULL);
   friend class fhandler_fifo;
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_fifo: public fhandler_base_overlapped
@@ -645,6 +667,7 @@ public:
   select_record *select_read (select_stuff *);
   select_record *select_write (select_stuff *);
   select_record *select_except (select_stuff *);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_mailslot : public fhandler_base_overlapped
@@ -657,6 +680,7 @@ class fhandler_mailslot : public fhandler_base_overlapped
   ssize_t __stdcall raw_write (const void *, size_t) __attribute__ ((regparm (3)));
   int ioctl (unsigned int cmd, void *);
   select_record *select_read (select_stuff *);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_raw: public fhandler_base
@@ -689,6 +713,7 @@ class fhandler_dev_raw: public fhandler_base
 
   void fixup_after_fork (HANDLE);
   void fixup_after_exec ();
+  size_t size () const { return sizeof (*this);}
 };
 
 #define MAX_PARTITIONS 15
@@ -732,6 +757,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
   ssize_t __stdcall raw_write (const void *ptr, size_t ulen) __attribute__ ((regparm (3)));
   _off64_t lseek (_off64_t offset, int whence);
   int ioctl (unsigned int cmd, void *buf);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_tape: public fhandler_dev_raw
@@ -749,7 +775,7 @@ class fhandler_dev_tape: public fhandler_dev_raw
  public:
   fhandler_dev_tape ();
 
-  virtual int open (int flags, mode_t mode = 0);
+  int open (int flags, mode_t mode = 0);
   virtual int close ();
 
   void __stdcall raw_read (void *ptr, size_t& ulen) __attribute__ ((regparm (3)));
@@ -763,6 +789,7 @@ class fhandler_dev_tape: public fhandler_dev_raw
   virtual void fixup_after_fork (HANDLE parent);
   virtual void set_close_on_exec (bool val);
   virtual int ioctl (unsigned int cmd, void *buf);
+  size_t size () const { return sizeof (*this);}
 };
 
 /* Standard disk file */
@@ -806,6 +833,7 @@ class fhandler_disk_file: public fhandler_base
 
   ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
   ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_cygdrive: public fhandler_disk_file
@@ -827,6 +855,7 @@ class fhandler_cygdrive: public fhandler_disk_file
   void rewinddir (DIR *);
   int closedir (DIR *);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_serial: public fhandler_base
@@ -875,6 +904,7 @@ class fhandler_serial: public fhandler_base
   select_record *select_write (select_stuff *);
   select_record *select_except (select_stuff *);
   bool is_slow () {return true;}
+  size_t size () const { return sizeof (*this);}
 };
 
 #define acquire_output_mutex(ms) \
@@ -1048,7 +1078,10 @@ class fhandler_console: public fhandler_termios
 
   fhandler_console* is_console () { return this; }
 
-  int open (int flags, mode_t mode = 0);
+  bool use_archetype () const {return true;}
+
+  int open (int flags, mode_t mode);
+  void open_setup (int flags);
 
   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
   ssize_t __stdcall write (const void *ptr, size_t len);
@@ -1059,9 +1092,6 @@ class fhandler_console: public fhandler_termios
   int tcsetattr (int a, const struct termios *t);
   int tcgetattr (struct termios *t);
 
-  /* Special dup as we must dup two handles */
-  int dup (fhandler_base *child);
-
   int ioctl (unsigned int cmd, void *);
   int init (HANDLE, DWORD, mode_t);
   bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
@@ -1080,6 +1110,7 @@ class fhandler_console: public fhandler_termios
   bool is_slow () {return true;}
   static bool need_invisible ();
   static bool has_a () {return !invisible_console;}
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_tty_common: public fhandler_termios
@@ -1124,9 +1155,11 @@ class fhandler_tty_slave: public fhandler_tty_common
 
  public:
   /* Constructor */
-  fhandler_tty_slave ();
+  fhandler_tty_slave (int);
 
+  bool use_archetype () const {return true;}
   int open (int flags, mode_t mode = 0);
+  void open_setup (int flags);
   ssize_t __stdcall write (const void *ptr, size_t len);
   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
   int init (HANDLE, DWORD, mode_t);
@@ -1136,6 +1169,7 @@ class fhandler_tty_slave: public fhandler_tty_common
   int tcflush (int);
   int ioctl (unsigned int cmd, void *);
   int close ();
+  void cleanup ();
   int dup (fhandler_base *child);
   void fixup_after_fork (HANDLE parent);
   void fixup_after_exec ();
@@ -1146,6 +1180,7 @@ class fhandler_tty_slave: public fhandler_tty_common
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_pty_master: public fhandler_tty_common
@@ -1161,6 +1196,7 @@ public:
   /* Constructor */
   fhandler_pty_master ();
 
+  virtual bool use_archetype () const {return true;}
   DWORD pty_master_thread ();
   int process_slave_output (char *buf, size_t len, int pktmode_on);
   void doecho (const void *str, DWORD len);
@@ -1169,6 +1205,7 @@ public:
   ssize_t __stdcall write (const void *ptr, size_t len);
   void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
   int close ();
+  void cleanup ();
 
   int tcsetattr (int a, const struct termios *t);
   int tcgetattr (struct termios *t);
@@ -1184,6 +1221,8 @@ public:
   void fixup_after_fork (HANDLE parent);
   void fixup_after_exec ();
   int tcgetpgrp ();
+  virtual bool is_tty_master () const {return false;}
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_tty_master: public fhandler_pty_master
@@ -1191,11 +1230,14 @@ class fhandler_tty_master: public fhandler_pty_master
  public:
   /* Constructor */
   fhandler_console *console;   // device handler to perform real i/o.
+  bool use_archetype () const {return false;}
 
   fhandler_tty_master ();
   int init ();
   int init_console ();
   void set_winsize (bool);
+  bool is_tty_master () const {return true;}
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_null: public fhandler_base
@@ -1206,6 +1248,7 @@ class fhandler_dev_null: public fhandler_base
   select_record *select_read (select_stuff *);
   select_record *select_write (select_stuff *);
   select_record *select_except (select_stuff *);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_zero: public fhandler_base
@@ -1224,6 +1267,7 @@ class fhandler_dev_zero: public fhandler_base
   virtual bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
                                      _off64_t offset, DWORD size,
                                      void *address);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_random: public fhandler_base
@@ -1245,6 +1289,7 @@ class fhandler_dev_random: public fhandler_base
   _off64_t lseek (_off64_t offset, int whence);
   int close ();
   int dup (fhandler_base *child);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_mem: public fhandler_base
@@ -1269,7 +1314,8 @@ class fhandler_dev_mem: public fhandler_base
   int msync (HANDLE h, caddr_t addr, size_t len, int flags);
   bool fixup_mmap_after_fork (HANDLE h, int prot, int flags,
                              _off64_t offset, DWORD size, void *address);
-} ;
+  size_t size () const { return sizeof (*this);}
+};
 
 class fhandler_dev_clipboard: public fhandler_base
 {
@@ -1288,6 +1334,7 @@ class fhandler_dev_clipboard: public fhandler_base
 
   int dup (fhandler_base *child);
   void fixup_after_exec ();
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_windows: public fhandler_base
@@ -1310,6 +1357,7 @@ class fhandler_windows: public fhandler_base
   select_record *select_read (select_stuff *);
   select_record *select_write (select_stuff *);
   select_record *select_except (select_stuff *);
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_dev_dsp: public fhandler_base
@@ -1334,12 +1382,13 @@ class fhandler_dev_dsp: public fhandler_base
   int ioctl (unsigned int cmd, void *);
   _off64_t lseek (_off64_t, int);
   int close ();
-  int dup (fhandler_base *child);
   void fixup_after_fork (HANDLE parent);
   void fixup_after_exec ();
  private:
   void close_audio_in ();
   void close_audio_out (bool immediately = false);
+  size_t size () const { return sizeof (*this);}
+  bool use_archetype () const {return true;}
 };
 
 class fhandler_virtual : public fhandler_base
@@ -1374,6 +1423,7 @@ class fhandler_virtual : public fhandler_base
   virtual bool fill_filebuf ();
   char *get_filebuf () { return filebuf; }
   void fixup_after_exec ();
+  virtual size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_proc: public fhandler_virtual
@@ -1387,6 +1437,7 @@ class fhandler_proc: public fhandler_virtual
   int open (int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   bool fill_filebuf ();
+  virtual size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_procsys: public fhandler_virtual
@@ -1406,6 +1457,7 @@ class fhandler_procsys: public fhandler_virtual
   ssize_t __stdcall write (const void *ptr, size_t len);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   bool fill_filebuf ();
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_procsysvipc: public fhandler_proc
@@ -1418,6 +1470,7 @@ class fhandler_procsysvipc: public fhandler_proc
   int open (int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   bool fill_filebuf ();
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_netdrive: public fhandler_virtual
@@ -1431,6 +1484,7 @@ class fhandler_netdrive: public fhandler_virtual
   int closedir (DIR *);
   int open (int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_registry: public fhandler_proc
@@ -1454,6 +1508,7 @@ class fhandler_registry: public fhandler_proc
   bool fill_filebuf ();
   int close ();
   int dup (fhandler_base *child);
+  size_t size () const { return sizeof (*this);}
 };
 
 class pinfo;
@@ -1468,6 +1523,7 @@ class fhandler_process: public fhandler_proc
   int open (int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   bool fill_filebuf ();
+  size_t size () const { return sizeof (*this);}
 };
 
 class fhandler_procnet: public fhandler_proc
@@ -1480,6 +1536,7 @@ class fhandler_procnet: public fhandler_proc
   int open (int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
   bool fill_filebuf ();
+  size_t size () const { return sizeof (*this);}
 };
 
 struct fhandler_nodevice: public fhandler_base
@@ -1492,7 +1549,7 @@ struct fhandler_nodevice: public fhandler_base
 #define report_tty_counts(fh, call, use_op) \
   termios_printf ("%s %s, %susecount %d",\
                  fh->ttyname (), call,\
-                 use_op, ((fhandler_tty_slave *) fh)->archetype->usecount);
+                 use_op, ((fhandler_tty_slave *) (fh->archetype ?: fh))->usecount);
 
 typedef union
 {
index b33b14deead3d6953e8398e3dda6fa62773c0bfa..8fe4414cc17cf905cf8b90c05971b75642e779ac 100644 (file)
@@ -94,8 +94,6 @@ fhandler_console::get_tty_stuff (int flags = 0)
   if (!shared_console_info->tty_min_state.ntty)
     {
       shared_console_info->tty_min_state.setntty (TTY_CONSOLE);
-      shared_console_info->tty_min_state.setsid (myself->sid);
-      myself->set_ctty (&shared_console_info->tty_min_state, flags, this);
 
       dev_state->scroll_region.Bottom = -1;
       dev_state->dwLastCursorPosition.X = -1;
@@ -700,8 +698,6 @@ fhandler_console::open (int flags, mode_t)
   set_io_handle (NULL);
   set_output_handle (NULL);
 
-  set_flags ((flags & ~O_TEXT) | O_BINARY);
-
   /* Open the input handle as handle_ */
   h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE,
                  FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags),
@@ -735,7 +731,6 @@ fhandler_console::open (int flags, mode_t)
 
   tc->rstcons (false);
   set_open_status ();
-  cygheap->manage_console_count ("fhandler_console::open", 1);
 
   DWORD cflags;
   if (GetConsoleMode (get_io_handle (), &cflags))
@@ -748,6 +743,14 @@ fhandler_console::open (int flags, mode_t)
   return 1;
 }
 
+void
+fhandler_console::open_setup (int flags)
+{
+  cygheap->manage_console_count ("fhandler_console::open", 1);
+  set_flags ((flags & ~O_TEXT) | O_BINARY);
+  myself->set_ctty (&shared_console_info->tty_min_state, flags, this);
+}
+
 int
 fhandler_console::close ()
 {
@@ -758,19 +761,6 @@ fhandler_console::close ()
   return 0;
 }
 
-/*  Special console dup to duplicate input and output  handles.  */
-
-int
-fhandler_console::dup (fhandler_base *child)
-{
-  fhandler_console *fhc = (fhandler_console *) child;
-
-  if (!fhc->open (get_flags () & ~O_NOCTTY, 0))
-    system_printf ("error opening console, %E");
-
-  return 0;
-}
-
 int
 fhandler_console::ioctl (unsigned int cmd, void *buf)
 {
@@ -855,6 +845,8 @@ fhandler_console::output_tcsetattr (int, struct termios const *t)
   DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
 
   int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
+  if (!res)
+    __seterrno_from_win_error (GetLastError ());
   syscall_printf ("%d = tcsetattr (,%x) (ENABLE FLAGS %x) (lflag %x oflag %x)",
                  res, t, flags, t->c_lflag, t->c_oflag);
   return res;
@@ -980,6 +972,7 @@ fhandler_console::tcgetattr (struct termios *t)
 fhandler_console::fhandler_console () :
   fhandler_termios ()
 {
+  dev ().parse (FH_CONSOLE);
   trunc_buf.len = 0;
 }
 
@@ -2094,7 +2087,7 @@ fhandler_console::init (HANDLE h, DWORD a, mode_t bin)
     flags = O_WRONLY;
   if (a == (GENERIC_READ | GENERIC_WRITE))
     flags = O_RDWR;
-  open (flags | O_BINARY | (h ? 0 : O_NOCTTY));
+  open_with_arch (flags | O_BINARY | (h ? 0 : O_NOCTTY));
   if (h && h != INVALID_HANDLE_VALUE)
     CloseHandle (h);   /* Reopened by open */
 
@@ -2127,24 +2120,7 @@ set_console_title (char *title)
 void
 fhandler_console::fixup_after_fork_exec (bool execing)
 {
-  HANDLE h = get_handle ();
-  HANDLE oh = get_output_handle ();
-
-  if ((execing && close_on_exec ()) || open (O_NOCTTY | get_flags (), 0))
-    cygheap->manage_console_count ("fhandler_console::fixup_after_fork_exec", -1);
-  else
-    {
-      if (!get_io_handle ())
-       system_printf ("error opening input console handle for %s after fork/exec, errno %d, %E", get_name (), get_errno ());
-      if (!get_output_handle ())
-       system_printf ("error opening output console handle for %s after fork/exec, errno %d, %E", get_name (), get_errno ());
-    }
-
-  if (!close_on_exec ())
-    {
-      CloseHandle (h);
-      CloseHandle (oh);
-    }
+  get_tty_stuff ();
 }
 
 bool NO_COPY fhandler_console::invisible_console;
index f784ca358c0f6f37d9b1faacd097621da8be6289..488cd864e6d710eb00d4da4aa042e54e3586fc81 100644 (file)
@@ -1006,11 +1006,6 @@ fhandler_dev_dsp::fhandler_dev_dsp ():
 int
 fhandler_dev_dsp::open (int flags, mode_t mode)
 {
-  if (cygheap->fdtab.find_archetype (dev ()))
-    {
-      set_errno (EBUSY);
-      return 0;
-    }
   int err = 0;
   UINT num_in = 0, num_out = 0;
   set_flags ((flags & ~O_TEXT) | O_BINARY);
@@ -1042,13 +1037,6 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
       set_open_status ();
       need_fork_fixup (true);
       nohandle (true);
-
-      // FIXME: Do this better someday
-      fhandler_dev_dsp *arch = (fhandler_dev_dsp *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
-      archetype = arch;
-      *((fhandler_dev_dsp **) cygheap->fdtab.add_archetype ()) = arch;
-      *arch = *this;
-      archetype->usecount = 1;
     }
   else
     set_errno (err);
@@ -1065,9 +1053,6 @@ ssize_t __stdcall
 fhandler_dev_dsp::write (const void *ptr, size_t len)
 {
   debug_printf ("ptr=%08x len=%d", ptr, len);
-  if ((fhandler_dev_dsp *) archetype != this)
-    return ((fhandler_dev_dsp *)archetype)->write(ptr, len);
-
   int len_s = len;
   const char *ptr_s = static_cast <const char *> (ptr);
 
@@ -1114,8 +1099,6 @@ void __stdcall
 fhandler_dev_dsp::read (void *ptr, size_t& len)
 {
   debug_printf ("ptr=%08x len=%d", ptr, len);
-  if ((fhandler_dev_dsp *) archetype != this)
-    return ((fhandler_dev_dsp *)archetype)->read(ptr, len);
 
   if (audio_in_)
     /* nothing to do */;
@@ -1181,27 +1164,8 @@ fhandler_dev_dsp::close ()
 {
   debug_printf ("audio_in=%08x audio_out=%08x",
                (int)audio_in_, (int)audio_out_);
-  if (!hExeced)
-    {
-      if ((fhandler_dev_dsp *) archetype != this)
-       return ((fhandler_dev_dsp *) archetype)->close ();
-
-      if (--usecount == 0)
-       {
-         close_audio_in ();
-         close_audio_out (exit_state != ES_NOT_EXITING);
-       }
-    }
-  return 0;
-}
-
-int
-fhandler_dev_dsp::dup (fhandler_base * child)
-{
-  debug_printf ("");
-  child->archetype = archetype;
-  child->set_flags (get_flags ());
-  archetype->usecount++;
+  close_audio_in ();
+  close_audio_out (exit_state != ES_NOT_EXITING);
   return 0;
 }
 
@@ -1210,9 +1174,6 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
 {
   debug_printf ("audio_in=%08x audio_out=%08x",
                (int)audio_in_, (int)audio_out_);
-  if ((fhandler_dev_dsp *) archetype != this)
-    return ((fhandler_dev_dsp *)archetype)->ioctl(cmd, ptr);
-
   int *intptr = (int *) ptr;
   switch (cmd)
     {
@@ -1419,11 +1380,9 @@ fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
 { // called from new child process
   debug_printf ("audio_in=%08x audio_out=%08x",
                (int)audio_in_, (int)audio_out_);
-  if (archetype != this)
-    return ((fhandler_dev_dsp *)archetype)->fixup_after_fork (parent);
 
   if (audio_in_)
-    audio_in_ ->fork_fixup (parent);
+    audio_in_->fork_fixup (parent);
   if (audio_out_)
     audio_out_->fork_fixup (parent);
 }
@@ -1435,9 +1394,6 @@ fhandler_dev_dsp::fixup_after_exec ()
                (int) audio_in_, (int) audio_out_, close_on_exec ());
   if (!close_on_exec ())
     {
-      if (archetype != this)
-       return ((fhandler_dev_dsp *) archetype)->fixup_after_exec ();
-
       audio_in_ = NULL;
       audio_out_ = NULL;
     }
index f55eab21e35166a2bd922356d4569bb2ff64e8cf..42e53919134fa607b292c3197d5c935d0055b3de 100644 (file)
@@ -113,7 +113,7 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
                                           DWORD ms)
 {
   if (strace.active ())
-    strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: waiting %d ms", ln, ms);
+    strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex (%p): waiting %d ms", ln, output_mutex, ms);
   DWORD res = WaitForSingleObject (output_mutex, ms);
   if (res == WAIT_OBJECT_0)
     {
@@ -138,11 +138,11 @@ fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
     {
 #ifndef DEBUGGING
       if (strace.active ())
-       strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex released", ln);
+       strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex(%p) released", ln, output_mutex);
 #else
       if (osi > 0)
        osi--;
-      termios_printf ("released at %s:%d, osi %d", fn, ln, osi);
+      termios_printf ("released(%p) at %s:%d, osi %d", output_mutex, fn, ln, osi);
       termios_printf ("  for %s:%d (%s)", ostack[osi].fn, ostack[osi].ln, ostack[osi].tname);
       ostack[osi].ln = -ln;
 #endif
@@ -299,7 +299,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
          while (1)
            {
              if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL))
-               goto err;
+               {
+                 termios_printf ("PeekNamedPipe failed, %E");
+                 goto err;
+               }
              if (n > 0)
                break;
              if (hit_eof ())
@@ -307,6 +310,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
              /* DISCARD (FLUSHO) and tcflush can finish here. */
              if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
                goto out;
+
+             if (is_tty_master ())
+               continue;
+
              if (is_nonblocking ())
                {
                  set_errno (EAGAIN);
@@ -321,17 +328,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
                  rc = -1;
                  goto out;
                }
-               
            }
 
-         if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
-           goto err;
+         if (!ReadFile (handle, outbuf, rlen, &n, NULL))
+           {
+             termios_printf ("ReadFile failed, %E");
+             goto err;
+           }
        }
 
       termios_printf ("bytes read %u", n);
       get_ttyp ()->write_error = 0;
       if (output_done_event != NULL)
-       SetEvent (output_done_event);
+         SetEvent (output_done_event);
 
       if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
        continue;
@@ -420,14 +429,17 @@ process_output (void *)
   for (;;)
     {
       int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
-      if (n <= 0)
+      if (n > 0)
+       {
+         n = tty_master->console->write ((void *) buf, (size_t) n);
+         tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
+       }
+      else
        {
          if (n < 0)
            termios_printf ("ReadFile %E");
          ExitThread (0);
        }
-      n = tty_master->console->write ((void *) buf, (size_t) n);
-      tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
     }
 }
 
@@ -454,9 +466,12 @@ process_ioctl (void *)
 /**********************************************************************/
 /* Tty slave stuff */
 
-fhandler_tty_slave::fhandler_tty_slave ()
+fhandler_tty_slave::fhandler_tty_slave (int ntty)
   : fhandler_tty_common (), inuse (NULL)
-{}
+{
+  if (ntty >= 0)
+    dev ().parse (DEV_TTYS_MAJOR, ntty);
+}
 
 /* FIXME: This function needs to close handles when it has
    a failing condition. */
@@ -472,28 +487,13 @@ fhandler_tty_slave::open (int flags, mode_t)
     NULL
   };
 
-  const char *errmsg = NULL;
-
   for (HANDLE **h = handles; *h; h++)
     **h = NULL;
 
-  if (get_device () == FH_TTY)
-    dev().tty_to_real_device ();
-  fhandler_tty_slave *arch = (fhandler_tty_slave *) cygheap->fdtab.find_archetype (pc.dev);
-  if (arch)
-    {
-      *this = *(fhandler_tty_slave *) arch;
-      termios_printf ("copied fhandler_tty_slave archetype");
-      set_flags ((flags & ~O_TEXT) | O_BINARY);
-      cygheap->manage_console_count ("fhandler_tty_slave::open<arch>", 1);
-      goto out;
-    }
-
   tcinit (cygwin_shared->tty[get_unit ()], false);
 
   cygwin_shared->tty.attach (get_unit ());
 
-  set_flags ((flags & ~O_TEXT) | O_BINARY);
   /* Create synchronisation events */
   char buf[MAX_PATH];
 
@@ -505,6 +505,8 @@ fhandler_tty_slave::open (int flags, mode_t)
   shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
   output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
 
+  const char *errmsg = NULL;
+
   if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
     {
       errmsg = "open output mutex failed, %E";
@@ -646,19 +648,6 @@ fhandler_tty_slave::open (int flags, mode_t)
   if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1
       && !output_done_event)
     fhandler_console::need_invisible ();
-
-  // FIXME: Do this better someday
-  arch = (fhandler_tty_slave *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
-  *((fhandler_tty_slave **) cygheap->fdtab.add_archetype ()) = arch;
-  archetype = arch;
-  *arch = *this;
-
-out:
-  usecount = 0;
-  arch->usecount++;
-  report_tty_counts (this, "opened", "");
-  myself->set_ctty (get_ttyp (), flags, arch);
-
   return 1;
 
 err:
@@ -672,8 +661,17 @@ err_no_msg:
   return 0;
 }
 
-int
-fhandler_tty_slave::close ()
+void
+fhandler_tty_slave::open_setup (int flags)
+{
+  set_flags ((flags & ~O_TEXT) | O_BINARY);
+  myself->set_ctty (get_ttyp (), flags, this);
+  cygheap->manage_console_count ("fhandler_tty_slave::setup", 1);
+  report_tty_counts (this, "opened", "");
+}
+
+void
+fhandler_tty_slave::cleanup ()
 {
   /* This used to always call fhandler_tty_common::close when hExeced but that
      caused multiple closes of the handles associated with this tty.  Since
@@ -681,20 +679,12 @@ fhandler_tty_slave::close ()
      or before a non-cygwin process has exited, it should be safe to just
      close this normally.  cgf 2006-05-20 */
   cygheap->manage_console_count ("fhandler_tty_slave::close", -1);
-
-  archetype->usecount--;
   report_tty_counts (this, "closed", "");
+}
 
-  if (archetype->usecount)
-    {
-#ifdef DEBUGGING
-      if (archetype->usecount < 0)
-       system_printf ("error: usecount %d", archetype->usecount);
-#endif
-      termios_printf ("just returning because archetype usecount is != 0");
-      return 0;
-    }
-
+int
+fhandler_tty_slave::close ()
+{
   termios_printf ("closing last open %s handle", ttyname ());
   if (inuse && !CloseHandle (inuse))
     termios_printf ("CloseHandle (inuse), %E");
@@ -702,7 +692,7 @@ fhandler_tty_slave::close ()
 }
 
 int
-fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
+fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
 {
   int flags = 0;
 
@@ -714,7 +704,7 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
   if (a == (GENERIC_READ | GENERIC_WRITE))
     flags = O_RDWR;
 
-  int ret = open (flags);
+  int ret = open_with_arch (flags);
 
   if (ret && !cygwin_finished_initializing && !being_debugged ())
     {
@@ -735,8 +725,8 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
        }
     }
 
-  if (f != INVALID_HANDLE_VALUE)
-    CloseHandle (f);   /* Reopened by open */
+  if (h != INVALID_HANDLE_VALUE)
+    CloseHandle (h);   /* Reopened by open */
 
   return ret;
 }
@@ -1037,38 +1027,14 @@ out:
 int
 fhandler_tty_slave::dup (fhandler_base *child)
 {
-  fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
-  /* In dtable::dup_worker, the path_conv member has already been assigned
-     from "this" to "child".  Part of this assigment (path_conv::operator=)
-     is to allocate memory for the strings "path" and "normalized_path from
-     cygheap.  The below `child = *arch' statement will overwrite child's
-     path_conv again, this time from "*arch".  By doing that, it will allocate
-     new strings from cygheap, overwriting the old pointer values.  Thus, the
-     old allocated strings are lost, and we're leaking memory for each tty dup,
-     unless we free the strings here.
-     FIXME: We can't redefine path_conv::operator= so that it frees the old
-     strings.  Probably it would be most helpful to copy only the required
-     members from *arch, rather than copying everything. */
-  child->pc.free_strings ();
-  *(fhandler_tty_slave *) child = *arch;
-  child->set_flags (get_flags ());
-  child->usecount = 0;
-  arch->usecount++;
   cygheap->manage_console_count ("fhandler_tty_slave::dup", 1);
-  report_tty_counts (child, "duped", "");
+  report_tty_counts (child, "duped slave", "");
   return 0;
 }
 
 int
 fhandler_pty_master::dup (fhandler_base *child)
 {
-  fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
-  /* See comment in fhandler_tty_slave::dup. */
-  child->pc.free_strings ();
-  *(fhandler_tty_master *) child = *arch;
-  child->set_flags (get_flags ());
-  child->usecount = 0;
-  arch->usecount++;
   report_tty_counts (child, "duped master", "");
   return 0;
 }
@@ -1435,15 +1401,8 @@ fhandler_pty_master::open (int flags, mode_t)
   set_flags ((flags & ~O_TEXT) | O_BINARY);
   set_open_status ();
 
-  /* FIXME: Do this better someday */
-  fhandler_pty_master *arch = (fhandler_tty_master *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
-  *((fhandler_pty_master **) cygheap->fdtab.add_archetype ()) = arch;
-  archetype = arch;
-  *arch = *this;
-  arch->dwProcessId = GetCurrentProcessId ();
+  dwProcessId = GetCurrentProcessId ();
 
-  usecount = 0;
-  arch->usecount++;
   char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
   __small_sprintf (buf, "opened pty master for tty%d", get_unit ());
   report_tty_counts (this, buf, "");
@@ -1482,6 +1441,12 @@ fhandler_tty_common::close ()
   return 0;
 }
 
+void
+fhandler_pty_master::cleanup ()
+{
+  report_tty_counts (this, "closing master", "");
+}
+
 int
 fhandler_pty_master::close ()
 {
@@ -1489,25 +1454,12 @@ fhandler_pty_master::close ()
   while (accept_input () > 0)
     continue;
 #endif
-  archetype->usecount--;
-  report_tty_counts (this, "closing master", "");
 
-  if (archetype->usecount)
-    {
-#ifdef DEBUGGING
-      if (archetype->usecount < 0)
-       system_printf ("error: usecount %d", archetype->usecount);
-#endif
-      termios_printf ("just returning because archetype usecount is != 0");
-      return 0;
-    }
-
-  fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
   termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
-                 arch->from_master, arch->to_master, arch->dwProcessId);
+                 from_master, to_master, dwProcessId);
   if (cygwin_finished_initializing)
     {
-      if (arch->master_ctl && get_ttyp ()->master_pid == myself->pid)
+      if (master_ctl && get_ttyp ()->master_pid == myself->pid)
        {
          char buf[MAX_PATH];
          pipe_request req = { (DWORD) -1 };
@@ -1517,13 +1469,13 @@ fhandler_pty_master::close ()
          __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
                           &installation_key, get_unit ());
          CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
-         CloseHandle (arch->master_ctl);
-         arch->master_thread->detach ();
+         CloseHandle (master_ctl);
+         master_thread->detach ();
        }
-      if (!ForceCloseHandle (arch->from_master))
-       termios_printf ("error closing from_master %p, %E", arch->from_master);
-      if (!ForceCloseHandle (arch->to_master))
-       termios_printf ("error closing from_master %p, %E", arch->to_master);
+      if (!ForceCloseHandle (from_master))
+       termios_printf ("error closing from_master %p, %E", from_master);
+      if (!ForceCloseHandle (to_master))
+       termios_printf ("error closing from_master %p, %E", to_master);
     }
   fhandler_tty_common::close ();
 
@@ -1674,7 +1626,7 @@ fhandler_tty_slave::fixup_after_exec ()
 int
 fhandler_tty_master::init_console ()
 {
-  console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym");
+  console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym_console");
   if (console == NULL)
     return -1;
 
@@ -1824,10 +1776,10 @@ reply:
 }
 
 static DWORD WINAPI
-pty_master_thread (VOID *arg)           
-{ 
+pty_master_thread (VOID *arg)
+{
   return ((fhandler_pty_master *) arg)->pty_master_thread ();
-} 
+}
 
 bool
 fhandler_pty_master::setup (bool ispty)
index 2096475a94cad968bf0e363794e2e3a70b0566ec..820559e0f1319d25385e845609ffcacf690c3475 100644 (file)
@@ -371,12 +371,33 @@ _pinfo::_ctty (char *buf)
 }
 
 void
-_pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *arch)
+_pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *fh)
 {
-  debug_printf ("old %s", __ctty ());
+  debug_printf ("old %s, ctty %d, tc->ntty %d flags & O_NOCTTY %p", __ctty (), ctty, tc->ntty, flags & O_NOCTTY);
   if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY))
     {
       ctty = tc->ntty;
+      if (cygheap->ctty != fh->archetype)
+       {
+         debug_printf ("/dev/tty%d cygheap->ctty %p, archetype %p", ctty, cygheap->ctty, fh->archetype);
+         if (!cygheap->ctty)
+           syscall_printf ("ctty was NULL");
+         else
+           {
+             syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
+                             cygheap->ctty->archetype_usecount (0));
+             cygheap->ctty->close ();
+           }
+         cygheap->ctty = (fhandler_termios *) fh->archetype;
+         if (cygheap->ctty)
+           {
+             fh->archetype_usecount (1);
+             /* guard ctty fh */
+             cygheap->manage_console_count ("_pinfo::set_ctty", 1);
+             report_tty_counts (cygheap->ctty, "ctty", "");
+           }
+       }
+
       lock_ttys here;
       syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d",
                      __ctty (), sid, pid, pgid, tc->getpgid (), tc->getsid ());
@@ -399,28 +420,8 @@ _pinfo::set_ctty (tty_min *tc, int flags, fhandler_termios *arch)
        sid = tc->getsid ();
       if (tc->getpgid () == 0)
          tc->setpgid (pgid);
-      if (cygheap->ctty != arch)
-       {
-         debug_printf ("cygheap->ctty %p, arch %p", cygheap->ctty, arch);
-         if (!cygheap->ctty)
-           syscall_printf ("ctty NULL");
-         else
-           {
-             syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
-                             cygheap->ctty->usecount);
-             cygheap->ctty->close ();
-           }
-         cygheap->ctty = arch;
-         if (arch)
-           {
-             arch->usecount++;
-             /* guard ctty arch */
-             cygheap->manage_console_count ("_pinfo::set_ctty", 1);
-             report_tty_counts (cygheap->ctty, "ctty", "");
-           }
-       }
     }
-    debug_printf ("cygheap->ctty now %p, arch %p", cygheap->ctty, arch);
+    debug_printf ("cygheap->ctty now %p, archetype %p", cygheap->ctty, fh->archetype);
 }
 
 /* Test to determine if a process really exists and is processing signals.
index 5585b332a78222bbd7ba43cd287237b1b122144b..d122c8dc279a445665e8a6843782553a8310296c 100644 (file)
@@ -101,7 +101,7 @@ close_all_files (bool norelease)
          DuplicateHandle (GetCurrentProcess (), fh->get_output_handle (),
                           GetCurrentProcess (), &h,
                           0, false, DUPLICATE_SAME_ACCESS);
-       fh->close ();
+       fh->close_with_arch ();
        if (!norelease)
          cygheap->fdtab.release (i);
       }
@@ -601,7 +601,7 @@ unlink_nt (path_conv &pc)
          NFS implements its own mechanism to remove in-use files which
         looks quite similar to what we do in try_to_bin for remote files.
         That's why we don't call try_to_bin on NFS.
-        
+
         Netapp filesystems don't understand the "move and delete" method
         at all and have all kinds of weird effects.  Just setting the delete
         dispositon usually works fine, though. */
@@ -721,7 +721,7 @@ unlink_nt (path_conv &pc)
             http://msdn.microsoft.com/en-us/library/ff545765%28VS.85%29.aspx
             "Subsequently, the only legal operation by such a caller is
             to close the open file handle."
-            
+
             FIXME? On Vista and later, we could use FILE_HARD_LINK_INFORMATION
             to find all hardlinks and use one of them to restore the R/O bit,
             after the NtClose, but before we stop the transaction.  This
@@ -1107,25 +1107,18 @@ open (const char *unix_path, int flags, ...)
              res = -1;
              set_errno (EEXIST);
            }
-         else if (fh->is_fs_special () && fh->device_access_denied (flags))
+         else if ((fh->is_fs_special () && fh->device_access_denied (flags))
+                  || !fh->open_with_arch (flags, (mode & 07777) & ~cygheap->umask))
            {
              delete fh;
              res = -1;
            }
          else
            {
-             fh->close_on_exec (flags & O_CLOEXEC);
-             if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
-               {
-                 delete fh;
-                 res = -1;
-               }
-             else
-               {
-                 cygheap->fdtab[fd] = fh;
-                 if ((res = fd) <= 2)
-                   set_std_handle (res);
-               }
+             fd = fh;
+             if (fd <= 2)
+               set_std_handle (fd);
+             res = fd;
            }
        }
     }
@@ -1185,7 +1178,7 @@ close (int fd)
     res = -1;
   else
     {
-      res = cfd->close ();
+      res = cfd->close_with_arch ();
       cfd.release ();
     }
 
@@ -1974,7 +1967,7 @@ rename (const char *oldpath, const char *newpath)
             filename has one of the blessed executable suffixes. */
          if (!old_explicit_suffix && oldpc.known_suffix
              && !newpc.is_binary ()
-             && !nt_path_has_executable_suffix (newpc.get_nt_native_path ()))  
+             && !nt_path_has_executable_suffix (newpc.get_nt_native_path ()))
            {
              rename_append_suffix (new2pc, newpath, nlen, ".exe");
              removepc = &newpc;
@@ -2040,7 +2033,7 @@ retry:
             a temporary filename and then rename the temp filename to the
             target filename.  This renaming fails due to the jealous virus
             scanner and the application fails to create the target file.
-            
+
             This kludge tries to work around that by yielding until the
             sharing violation goes away, or a signal arrived, or after
             about a second, give or take. */
This page took 0.081991 seconds and 5 git commands to generate.