summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/dtable.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/dtable.cc')
-rw-r--r--winsup/cygwin/dtable.cc170
1 files changed, 44 insertions, 126 deletions
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 5fbe0f4b9..654526065 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -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)
{