diff options
author | Christopher Faylor <me@cgf.cx> | 2003-12-11 06:12:41 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-12-11 06:12:41 +0000 |
commit | 8e10c4311f9612951c82da5e844d51d985552d65 (patch) | |
tree | 23808644eb736e80e3160f30a07fe0357babe5f2 | |
parent | 3f23411449cf414d447bf793a20f42ed3f8e5061 (diff) | |
download | newlib-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/ChangeLog | 36 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/dtable.cc | 33 | ||||
-rw-r--r-- | winsup/cygwin/dtable.h | 9 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 4 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_console.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_tty.cc | 75 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 19 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 17 |
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; } |