aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-12-11 06:12:41 +0000
committerChristopher Faylor <me@cgf.cx>2003-12-11 06:12:41 +0000
commit8e10c4311f9612951c82da5e844d51d985552d65 (patch)
tree23808644eb736e80e3160f30a07fe0357babe5f2
parent3f23411449cf414d447bf793a20f42ed3f8e5061 (diff)
downloadnewlib-8e10c4311f9612951c82da5e844d51d985552d65.zip
newlib-8e10c4311f9612951c82da5e844d51d985552d65.tar.gz
newlib-8e10c4311f9612951c82da5e844d51d985552d65.tar.bz2
* cygheap.h (cygheap_types): Add HEAP_ARCHETYPES.
(init_cheap::ctty): Change to pointer. * dtable.h (dtable::find_archetype): Declare new function. (dtable::add_archetype): Declare new function. (dtable::delete_archetype): Declare new function. (dtable::narchetypes): Declare. (dtable::farchetypes): Declare. (dtable::initial_archetype_size): Declare. (dtable::dtable): Initialize new fields. (dtable::initial_archetype_size): Declare. * dtable.cc (dtable::find_archetype): Define new function. (dtable::add_archetype): Define new function. (dtable::delete_archetype): Define new function. (dtable::initial_archetype_size): Define. * fhandler.h (fhandler_base::archetype): Declare. (fhandler_base::usecount): Declare. * fhandler.cc (fhandler_base::fhandler_base): Initialize new fields. * fhandler_console.cc (fhandler_console::get_tty_stuff): Pass NULL to third argument of set_ctty. * fhandler_tty.cc (fhandler_tty_slave::open): Accommodate new archetype method to create only one instance of a tty. (fhandler_tty_slave::close): Don't close handles unless archetype usecount is zero. When that happens, close archetype too. (fhandler_tty_slave::dup): Just copy archetype. Set use count appropriately. Set ctty, if appropriate. (fhandler_tty_common::dup): Remove slave considerations. (fhandler_tty_common::set_close_on_exec): Remove cygheap->ctty considerations. * pinfo.cc (_pinfo::set_ctty): Accommodate new archetype methods. * pinfo.h (_pinfo::set_ctty): Make third argument explicit. * syscalls.cc (close_all_files): Decrement controlling tty use count before closing all handles to allow controlling tty to be closed. Remove previous controlling tty considerations.
-rw-r--r--winsup/cygwin/ChangeLog36
-rw-r--r--winsup/cygwin/cygheap.h3
-rw-r--r--winsup/cygwin/dtable.cc33
-rw-r--r--winsup/cygwin/dtable.h9
-rw-r--r--winsup/cygwin/fhandler.cc4
-rw-r--r--winsup/cygwin/fhandler.h6
-rw-r--r--winsup/cygwin/fhandler_console.cc2
-rw-r--r--winsup/cygwin/fhandler_tty.cc75
-rw-r--r--winsup/cygwin/pinfo.cc19
-rw-r--r--winsup/cygwin/pinfo.h2
-rw-r--r--winsup/cygwin/syscalls.cc17
11 files changed, 162 insertions, 44 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6f732d1..bcf8273 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,39 @@
+2003-12-11 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.h (cygheap_types): Add HEAP_ARCHETYPES.
+ (init_cheap::ctty): Change to pointer.
+ * dtable.h (dtable::find_archetype): Declare new function.
+ (dtable::add_archetype): Declare new function.
+ (dtable::delete_archetype): Declare new function.
+ (dtable::narchetypes): Declare.
+ (dtable::farchetypes): Declare.
+ (dtable::initial_archetype_size): Declare.
+ (dtable::dtable): Initialize new fields.
+ (dtable::initial_archetype_size): Declare.
+ * dtable.cc (dtable::find_archetype): Define new function.
+ (dtable::add_archetype): Define new function.
+ (dtable::delete_archetype): Define new function.
+ (dtable::initial_archetype_size): Define.
+ * fhandler.h (fhandler_base::archetype): Declare.
+ (fhandler_base::usecount): Declare.
+ * fhandler.cc (fhandler_base::fhandler_base): Initialize new fields.
+ * fhandler_console.cc (fhandler_console::get_tty_stuff): Pass NULL to
+ third argument of set_ctty.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Accommodate new archetype
+ method to create only one instance of a tty.
+ (fhandler_tty_slave::close): Don't close handles unless archetype
+ usecount is zero. When that happens, close archetype too.
+ (fhandler_tty_slave::dup): Just copy archetype. Set use count
+ appropriately. Set ctty, if appropriate.
+ (fhandler_tty_common::dup): Remove slave considerations.
+ (fhandler_tty_common::set_close_on_exec): Remove cygheap->ctty
+ considerations.
+ * pinfo.cc (_pinfo::set_ctty): Accommodate new archetype methods.
+ * pinfo.h (_pinfo::set_ctty): Make third argument explicit.
+ * syscalls.cc (close_all_files): Decrement controlling tty use count
+ before closing all handles to allow controlling tty to be closed.
+ Remove previous controlling tty considerations.
+
2003-12-09 Christopher Faylor <cgf@redhat.com>
* fhandler_tty.cc (fhandler_tty_common::dup): Just copy cygheap->ctty
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index d326f59..afe7d01 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -18,6 +18,7 @@ enum cygheap_types
HEAP_BUF,
HEAP_MOUNT,
HEAP_SIGS,
+ HEAP_ARCHETYPES,
HEAP_1_START,
HEAP_1_STR,
HEAP_1_ARGV,
@@ -260,7 +261,7 @@ struct init_cygheap
#endif
struct sigaction *sigs;
- fhandler_tty_slave ctty; /* Current tty */
+ fhandler_tty_slave *ctty; /* Current tty */
};
#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536))
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index e3268ed..70e52f4 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -163,6 +163,39 @@ dtable::stdio_init ()
set_console_ctty ();
}
+const int dtable::initial_archetype_size;
+
+fhandler_base *
+dtable::find_archetype (device& dev)
+{
+ for (unsigned i = 0; i < farchetype; i++)
+ if (archetypes[i]->get_device () == (unsigned) dev)
+ return archetypes[i];
+ return NULL;
+}
+
+fhandler_base **
+dtable::add_archetype ()
+{
+ if (farchetype++ >= narchetypes)
+ archetypes = (fhandler_base **) crealloc (archetypes, (narchetypes += initial_archetype_size) * sizeof archetypes[0]);
+ return archetypes + farchetype - 1;
+}
+
+void
+dtable::delete_archetype (fhandler_base *fh)
+{
+ for (unsigned i = 0; i < narchetypes; i++)
+ if (fh == archetypes[i])
+ {
+ if (i < --farchetype)
+ archetypes[i] = archetypes[farchetype];
+ break;
+ }
+
+ delete fh;
+}
+
int
dtable::find_unused_handle (int start)
{
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 7267ce6..0b2db91 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -21,12 +21,16 @@ class dtable
{
fhandler_base **fds;
fhandler_base **fds_on_hold;
+ fhandler_base **archetypes;
+ unsigned narchetypes;
+ unsigned farchetype;
+ static const int initial_archetype_size = 8;
int first_fd_for_open;
int cnt_need_fixup_before;
public:
size_t size;
- dtable () : first_fd_for_open(3), cnt_need_fixup_before(0) {}
+ dtable () : archetypes (NULL), narchetypes (0), farchetype (0), first_fd_for_open(3), cnt_need_fixup_before(0) {}
void init () {first_fd_for_open = 3;}
void dec_need_fixup_before ()
@@ -69,6 +73,9 @@ public:
void set_file_pointers_for_exec ();
bool in_vfork_cleanup () {return fds_on_hold == fds;}
fhandler_fifo *find_fifo (ATOM);
+ fhandler_base *find_archetype (device& dev);
+ fhandler_base **add_archetype ();
+ void delete_archetype (fhandler_base *);
};
fhandler_base *build_fh_dev (const device&, const char * = NULL);
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 997e807..d9d3770 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1177,7 +1177,9 @@ fhandler_base::fhandler_base ():
rabuflen (0),
open_status (0),
fs_flags (0),
- read_state (NULL)
+ read_state (NULL),
+ archetype (NULL),
+ usecount (0)
{
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index b90e3bf..4ab7f02 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -121,8 +121,11 @@ class fhandler_base
DWORD fs_flags;
HANDLE read_state;
path_conv pc;
+ class fhandler_base *archetype;
public:
+ int usecount;
+
void set_name (path_conv &pc);
int error () const {return pc.error;}
void set_error (int error) {pc.error = error;}
@@ -130,6 +133,7 @@ class fhandler_base
int pc_binmode () const {return pc.binmode ();}
device& dev () {return pc.dev;}
operator DWORD& () {return (DWORD) pc;}
+ virtual size_t size () const {return sizeof (*this);}
virtual fhandler_base& operator =(fhandler_base &x);
fhandler_base ();
@@ -138,7 +142,7 @@ class fhandler_base
/* Non-virtual simple accessor functions. */
void set_io_handle (HANDLE x) { io_handle = x; }
- DWORD get_device () { return dev ().devn; }
+ DWORD& get_device () { return dev ().devn; }
DWORD get_major () { return dev ().major; }
DWORD get_minor () { return dev ().minor; }
virtual int get_unit () { return dev ().minor; }
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index e5b6120..46f1cb1 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -94,7 +94,7 @@ fhandler_console::get_tty_stuff (int flags = 0)
{
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);
+ myself->set_ctty (&shared_console_info->tty_min_state, flags, NULL);
dev_state->scroll_region.Bottom = -1;
dev_state->dwLastCursorPosition.X = -1;
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 4e888c0..85a4cc7 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -447,16 +447,16 @@ fhandler_tty_slave::fhandler_tty_slave ()
int
fhandler_tty_slave::open (int flags, mode_t)
{
- if (get_device () != FH_TTY)
- /* nothing to do */;
- else if (!cygheap->ctty.get_io_handle ())
+ if (get_device () == FH_TTY)
pc.dev.tty_to_real_device ();
- else
+ fhandler_tty_slave *arch = (fhandler_tty_slave *)
+ cygheap->fdtab.find_archetype (pc.dev);
+ if (arch)
{
- *this = cygheap->ctty;
- fhandler_console::open_fhs++;
+ *this = *(fhandler_tty_slave *) arch;
termios_printf ("copied tty fhandler from cygheap");
- return 1;
+ fhandler_console::open_fhs++;
+ goto out;
}
tcinit (cygwin_shared->tty[get_unit ()]);
@@ -519,8 +519,9 @@ fhandler_tty_slave::open (int flags, mode_t)
return 0;
}
- HANDLE from_master_local = NULL;
- HANDLE to_master_local = NULL;
+ HANDLE from_master_local;
+ HANDLE to_master_local;
+ from_master_local = to_master_local = NULL;
#ifdef USE_SERVER
if (!wincap.has_security ()
@@ -569,7 +570,6 @@ fhandler_tty_slave::open (int flags, mode_t)
set_io_handle (from_master_local);
set_output_handle (to_master_local);
- myself->set_ctty (get_ttyp (), flags, this);
set_open_status ();
if (fhandler_console::open_fhs++ == 0 && !GetConsoleCP ()
@@ -590,8 +590,19 @@ fhandler_tty_slave::open (int flags, mode_t)
if (b)
init_console_handler ();
}
- termios_printf ("incremented open_fhs %d", fhandler_console::open_fhs);
- termios_printf ("tty%d opened", get_unit ());
+
+ // FIXME: Do this better someday
+ arch = (fhandler_tty_slave *) cmalloc (HEAP_ARCHETYPES, sizeof (*this));
+ *((fhandler_tty_slave **) cygheap->fdtab.add_archetype ()) = arch;
+ archetype = arch;
+ *arch = *this;
+
+out:
+ usecount = 0;
+ archetype->usecount++;
+ myself->set_ctty (get_ttyp (), flags, arch);
+ termios_printf ("%s opened, incremented open_fhs %d, archetype usecount %d",
+ pc.dev.name, fhandler_console::open_fhs, archetype->usecount);
return 1;
}
@@ -601,10 +612,19 @@ fhandler_tty_slave::close ()
{
if (!--fhandler_console::open_fhs && myself->ctty == -1)
FreeConsole ();
- termios_printf ("decremented open_fhs %d", fhandler_console::open_fhs);
- if (myself->ctty >= 0 && get_io_handle () == cygheap->ctty.get_io_handle ())
- return 0;
- return fhandler_tty_common::close ();
+ termios_printf ("decremented open_fhs %d, archetype usecount %d",
+ fhandler_console::open_fhs, archetype->usecount);
+ if (--archetype->usecount)
+ {
+ termios_printf ("just exiting because archetype usecount is > 0");
+ return 0;
+ }
+
+ termios_printf ("closing last open %s handle", pc.dev.name);
+ fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
+ int res = fhandler_tty_common::close ();
+ cygheap->fdtab.delete_archetype (arch);
+ return res;
}
int
@@ -888,8 +908,14 @@ int
fhandler_tty_slave::dup (fhandler_base *child)
{
fhandler_console::open_fhs++;
- termios_printf ("incremented open_fhs %d", fhandler_console::open_fhs);
- return fhandler_tty_common::dup (child);
+ fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
+ *(fhandler_tty_slave *) child = *arch;
+ archetype->usecount++;
+ child->usecount = 0;
+ myself->set_ctty (get_ttyp (), openflags, arch);
+ termios_printf ("incremented open_fhs %d, archetype usecount %d",
+ fhandler_console::open_fhs, archetype->usecount);
+ return 0;
}
int
@@ -898,13 +924,6 @@ fhandler_tty_common::dup (fhandler_base *child)
fhandler_tty_slave *fts = (fhandler_tty_slave *) child;
int errind;
- if (get_io_handle () == cygheap->ctty.get_io_handle ())
- {
- *fts = cygheap->ctty;
- termios_printf ("duped ctty");
- return 0;
- }
-
fts->tcinit (get_ttyp ());
attach_tty (get_unit ());
@@ -987,9 +1006,6 @@ fhandler_tty_common::dup (fhandler_base *child)
goto err;
}
- if (get_major () == DEV_TTYS_MAJOR)
- myself->set_ctty (get_ttyp (), openflags, fts);
-
return 0;
err:
@@ -1315,8 +1331,7 @@ fhandler_pty_master::ptsname ()
void
fhandler_tty_common::set_close_on_exec (int val)
{
- if (get_major () == DEV_TTYS_MAJOR
- && get_io_handle () == cygheap->ctty.get_io_handle ())
+ if (get_major () == DEV_TTYS_MAJOR)
set_close_on_exec_flag (val);
else
{
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index dfd140f..f18ced7 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -255,7 +255,7 @@ pinfo::set_acl()
}
void
-_pinfo::set_ctty (tty_min *tc, int flags, fhandler_tty_slave *fhctty)
+_pinfo::set_ctty (tty_min *tc, int flags, fhandler_tty_slave *arch)
{
if ((ctty < 0 || ctty == tc->ntty) && !(flags & O_NOCTTY))
{
@@ -276,8 +276,21 @@ _pinfo::set_ctty (tty_min *tc, int flags, fhandler_tty_slave *fhctty)
sid = tc->getsid ();
if (tc->getpgid () == 0)
tc->setpgid (pgid);
- if (fhctty && !cygheap->ctty.get_io_handle ())
- cygheap->ctty = *fhctty;
+ if (cygheap->ctty != arch)
+ {
+ if (cygheap->ctty)
+ syscall_printf ("ctty NULL");
+ else
+ {
+ syscall_printf ("ctty %p, usecount %d", cygheap->ctty,
+ cygheap->ctty->usecount);
+ if (!--cygheap->ctty->usecount)
+ cygheap->ctty->close ();
+ }
+ cygheap->ctty = arch;
+ if (arch)
+ arch->usecount++;
+ }
}
}
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index f411b8c..2795563 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -112,7 +112,7 @@ public:
commune_result commune_send (DWORD, ...);
bool alive ();
char *cmdline (size_t &);
- void set_ctty (class tty_min *, int, class fhandler_tty_slave * = NULL);
+ void set_ctty (class tty_min *, int, class fhandler_tty_slave *);
friend void __stdcall set_myself (pid_t, HANDLE);
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1a77c36..9922182 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -89,6 +89,12 @@ close_all_files (void)
{
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files");
+ if (cygheap->ctty)
+ {
+ debug_printf ("decrementing ctty usecount");
+ cygheap->ctty->usecount--;
+ }
+
fhandler_base *fh;
for (int i = 0; i < (int) cygheap->fdtab.size; i++)
if ((fh = cygheap->fdtab[i]) != NULL)
@@ -97,9 +103,6 @@ close_all_files (void)
cygheap->fdtab.release (i);
}
- if (cygheap->ctty.get_io_handle ())
- cygheap->ctty.fhandler_tty_common::close ();
-
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files");
user_shared->delqueue.process_queue ();
}
@@ -320,10 +323,14 @@ setsid (void)
myself->ctty = -1;
myself->sid = getpid ();
myself->pgid = getpid ();
- if (cygheap->ctty.get_io_handle ())
- cygheap->ctty.fhandler_tty_common::close ();
syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid,
myself->pgid, myself->ctty, fhandler_console::open_fhs);
+ if (cygheap->ctty)
+ {
+ if (!--cygheap->ctty->usecount)
+ cygheap->ctty->close ();
+ cygheap->ctty = NULL;
+ }
return myself->sid;
}