From 3378bdfc0ab5a995ba09d37be67bbf0356a4d3b2 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 2 Jun 2006 15:41:34 +0000 Subject: * fhandler.cc (fhandler_base::fixup_after_exec): Declare here. * fhandler.h (fhandler_base::fixup_after_exec): Make non-inline. (fhandler_termios::fixup_after_fork): Delete declaration. (fhandler_termios::fixup_after_exec): Ditto. (fhandler_tty_common::inuse): Remove. (fhandler_tty_common::dup): Delete declaration. (fhandler_tty_common::fixup_after_fork): Ditto. (fhandler_tty_slave::fixup_after_exec): Declare new function. (fhandler_pty_master::dwProcessId): New variable. (fhandler_pty_master::from_master): Ditto. (fhandler_pty_master::to_master): Ditto. (fhandler_pty_master::setup): New function. (fhandler_pty_master::fixup_after_fork): Ditto. (fhandler_pty_master::fixup_after_exec): Ditto. * fhandler_termios.cc (fhandler_termios::fixup_after_exec): Delete definition. (fhandler_termios::fixup_after_fork): Ditto. * fhandler_tty.cc (fhandler_tty_master::init): Use fhandler_pty_master setup function rather than obsolete tty::common_init. Delete obsolete inuse setting. (fhandler_tty_slave::fhandler_tty_slave): Set inuse to NULL here. (fhandler_tty_slave::open): Change debugging output for clarity. Check for different things when doing a sanity check on the tty. Reflect the fact that master_pid now is the cygwin pid rather than the windows pid. Use "arch" rather than "archetype" for consistency. (fhandler_tty_slave::close): Close inuse here. (fhandler_tty_slave::dup): Remove old if 0'ed code. (fhandler_pty_master::dup): New function. Handles pty master archetype. (fhandler_pty_master::fhandler_pty_master): Zero pty_master specific fields. (fhandler_pty_master::open): Implement using archetypes, similar to slave. Use fhandler_pty_master setup function rather than obsolete tty::common_init. Don't set inuse. (fhandler_tty_common::close): Don't deal with inuse. Delete old if 0'ed code. (fhandler_pty_master::close): Implement using archetypes. Close from_master and to_master. (fhandler_tty_common::set_close_on_exec): Just set close_on_exec flag here since everything uses archetypes now. (fhandler_tty_common::fixup_after_fork): Delete definition. (fhandler_tty_slave::fixup_after_exec): Define new function. (fhandler_pty_master::setup): New function, derived from tty::common_init. (fhandler_pty_master::fixup_after_fork): New function. (shared_info.h): Reset SHARED_INFO_CB to reflect new tty size. * tty.cc (tty_list::terminate): Close individual handles from tty_master. (tty::master_alive): Delete. (tty::make_pipes): Ditto. (tty::common_init): Ditto. * tty.h (tty::from_slave): Delete. (tty::to_slave): Ditto. (tty::common_init): Delete declaration. (tty::make_pipes): Ditto. (tty::master_pid): Define as pid_t since it is now a cygwin pid. --- winsup/cygwin/ChangeLog | 59 ++++++ winsup/cygwin/fhandler.cc | 6 + winsup/cygwin/fhandler.h | 19 +- winsup/cygwin/fhandler_termios.cc | 14 -- winsup/cygwin/fhandler_tty.cc | 412 +++++++++++++++++++++----------------- winsup/cygwin/shared_info.h | 2 +- winsup/cygwin/tty.cc | 124 +----------- winsup/cygwin/tty.h | 8 +- 8 files changed, 311 insertions(+), 333 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c9acb7ec8..dc49607a9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,62 @@ +2006-06-02 Christopher Faylor + + * fhandler.cc (fhandler_base::fixup_after_exec): Declare here. + * fhandler.h (fhandler_base::fixup_after_exec): Make non-inline. + (fhandler_termios::fixup_after_fork): Delete declaration. + (fhandler_termios::fixup_after_exec): Ditto. + (fhandler_tty_common::inuse): Remove. + (fhandler_tty_common::dup): Delete declaration. + (fhandler_tty_common::fixup_after_fork): Ditto. + (fhandler_tty_slave::fixup_after_exec): Declare new function. + (fhandler_pty_master::dwProcessId): New variable. + (fhandler_pty_master::from_master): Ditto. + (fhandler_pty_master::to_master): Ditto. + (fhandler_pty_master::setup): New function. + (fhandler_pty_master::fixup_after_fork): Ditto. + (fhandler_pty_master::fixup_after_exec): Ditto. + * fhandler_termios.cc (fhandler_termios::fixup_after_exec): Delete + definition. + (fhandler_termios::fixup_after_fork): Ditto. + * fhandler_tty.cc (fhandler_tty_master::init): Use fhandler_pty_master + setup function rather than obsolete tty::common_init. Delete obsolete + inuse setting. + (fhandler_tty_slave::fhandler_tty_slave): Set inuse to NULL here. + (fhandler_tty_slave::open): Change debugging output for clarity. Check + for different things when doing a sanity check on the tty. Reflect the + fact that master_pid now is the cygwin pid rather than the windows pid. + Use "arch" rather than "archetype" for consistency. + (fhandler_tty_slave::close): Close inuse here. + (fhandler_tty_slave::dup): Remove old if 0'ed code. + (fhandler_pty_master::dup): New function. Handles pty master + archetype. + (fhandler_pty_master::fhandler_pty_master): Zero pty_master specific + fields. + (fhandler_pty_master::open): Implement using archetypes, similar to + slave. Use fhandler_pty_master setup function rather than obsolete + tty::common_init. Don't set inuse. + (fhandler_tty_common::close): Don't deal with inuse. Delete old if + 0'ed code. + (fhandler_pty_master::close): Implement using archetypes. Close + from_master and to_master. + (fhandler_tty_common::set_close_on_exec): Just set close_on_exec flag + here since everything uses archetypes now. + (fhandler_tty_common::fixup_after_fork): Delete definition. + (fhandler_tty_slave::fixup_after_exec): Define new function. + (fhandler_pty_master::setup): New function, derived from + tty::common_init. + (fhandler_pty_master::fixup_after_fork): New function. + (shared_info.h): Reset SHARED_INFO_CB to reflect new tty size. + * tty.cc (tty_list::terminate): Close individual handles from + tty_master. + (tty::master_alive): Delete. + (tty::make_pipes): Ditto. + (tty::common_init): Ditto. + * tty.h (tty::from_slave): Delete. + (tty::to_slave): Ditto. + (tty::common_init): Delete declaration. + (tty::make_pipes): Ditto. + (tty::master_pid): Define as pid_t since it is now a cygwin pid. + 2006-06-01 Christopher Faylor * cygheap.cc (cygheap_fixup_in_child): Don't close parent handle here. diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index bd91551d6..a48f3d91a 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1500,6 +1500,12 @@ fhandler_base::fixup_after_fork (HANDLE parent) fork_fixup (parent, io_handle, "io_handle"); } +void +fhandler_base::fixup_after_exec () +{ + debug_printf ("here for '%s'", get_name ()); +} + bool fhandler_base::is_nonblocking () { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 61b10caab..86b0feb5e 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -208,7 +208,7 @@ class fhandler_base virtual void fixup_before_fork_exec (DWORD) {} virtual void fixup_after_fork (HANDLE); - virtual void fixup_after_exec () {} + virtual void fixup_after_exec (); void create_read_state (LONG n) { read_state = CreateSemaphore (&sec_none_nih, 0, n, NULL); @@ -785,8 +785,6 @@ class fhandler_termios: public fhandler_base bg_check_types bg_check (int sig); virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;} virtual void __release_output_mutex (const char *fn, int ln) {} - void fixup_after_fork (HANDLE); - void fixup_after_exec (); void echo_erase (int force = 0); virtual _off64_t lseek (_off64_t, int); }; @@ -938,7 +936,7 @@ class fhandler_tty_common: public fhandler_termios fhandler_tty_common () : fhandler_termios (), output_done_event (NULL), ioctl_request_event (NULL), ioctl_done_event (NULL), output_mutex (NULL), - input_mutex (NULL), input_available_event (NULL), inuse (NULL) + input_mutex (NULL), input_available_event (NULL) { // nothing to do } @@ -950,19 +948,15 @@ class fhandler_tty_common: public fhandler_termios // Ioctl() status in tty::ioctl_retval. HANDLE output_mutex, input_mutex; HANDLE input_available_event; - HANDLE inuse; // used to indicate that a tty is in use DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms); void __release_output_mutex (const char *fn, int ln); - virtual int dup (fhandler_base *child); - tty *get_ttyp () { return (tty *) tc; } int close (); _off64_t lseek (_off64_t, int); void set_close_on_exec (bool val); - void fixup_after_fork (HANDLE parent); select_record *select_read (select_record *s); select_record *select_write (select_record *s); select_record *select_except (select_record *s); @@ -971,6 +965,7 @@ class fhandler_tty_common: public fhandler_termios class fhandler_tty_slave: public fhandler_tty_common { + HANDLE inuse; // used to indicate that a tty is in use public: /* Constructor */ fhandler_tty_slave (); @@ -987,6 +982,7 @@ class fhandler_tty_slave: public fhandler_tty_common int close (); int dup (fhandler_base *child); void fixup_after_fork (HANDLE parent); + void fixup_after_exec (); select_record *select_read (select_record *s); int cygserver_attach_tty (HANDLE*, HANDLE*); @@ -1001,6 +997,7 @@ protected: device slave; // device type of slave public: int need_nl; // Next read should start with \n + DWORD dwProcessId; // Owner of master handles /* Constructor */ fhandler_pty_master (); @@ -1020,9 +1017,13 @@ public: char *ptsname (); - void set_close_on_exec (bool val); + HANDLE from_master, to_master; bool hit_eof (); int get_unit () const { return slave.minor; } + bool setup (tty&); + int dup (fhandler_base *); + void fixup_after_fork (HANDLE parent); + void fixup_after_exec (); }; class fhandler_tty_master: public fhandler_pty_master diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 9b8d3597e..bd0386cf4 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -355,20 +355,6 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti) return ret; } -void -fhandler_termios::fixup_after_exec () -{ - if (!close_on_exec ()) - fixup_after_fork (NULL); -} - -void -fhandler_termios::fixup_after_fork (HANDLE parent) -{ - fhandler_base::fixup_after_fork (parent); - fork_fixup (parent, get_output_handle (), "output_handle"); -} - _off64_t fhandler_termios::lseek (_off64_t, int) { diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 39691c629..46ee8bc2f 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -28,8 +28,9 @@ details. */ #include "shared_info.h" #include "cygserver.h" #include "cygthread.h" +#include "child_info.h" -/* Tty master stuff */ +/* tty master stuff */ fhandler_tty_master NO_COPY *tty_master; @@ -74,11 +75,11 @@ fhandler_tty_master::init () memset (&ti, 0, sizeof (ti)); console->tcsetattr (0, &ti); - cygwin_shared->tty[get_unit ()]->common_init (this); + if (!setup (*cygwin_shared->tty[get_unit ()])) + return 1; set_winsize (false); - inuse = get_ttyp ()->create_inuse (TTY_MASTER_ALIVE); set_close_on_exec (true); cygthread *h; @@ -446,7 +447,7 @@ process_ioctl (void *) /* Tty slave stuff */ fhandler_tty_slave::fhandler_tty_slave () - : fhandler_tty_common () + : fhandler_tty_common (), inuse (NULL) { uninterruptible_io (true); } @@ -462,7 +463,7 @@ fhandler_tty_slave::open (int flags, mode_t) if (arch) { *this = *(fhandler_tty_slave *) arch; - termios_printf ("copied tty fhandler archetype"); + termios_printf ("copied fhandler_tty_slave archetype"); set_flags ((flags & ~O_TEXT) | O_BINARY); cygheap->manage_console_count ("fhandler_tty_slave::open", 1); goto out; @@ -521,7 +522,7 @@ fhandler_tty_slave::open (int flags, mode_t) /* Duplicate tty handles. */ - if (!get_ttyp ()->from_slave || !get_ttyp ()->to_slave) + if (!get_ttyp ()->from_master || !get_ttyp ()->to_master) { termios_printf ("tty handles have been closed"); set_errno (EACCES); @@ -538,12 +539,18 @@ fhandler_tty_slave::open (int flags, mode_t) || !cygserver_attach_tty (&from_master_local, &to_master_local)) #endif { + pinfo p (get_ttyp ()->master_pid); + if (!p) + { + set_errno (EAGAIN); + termios_printf ("*** couldn't find tty master"); + return 0; + } #ifdef USE_SERVER termios_printf ("cannot dup handles via server. using old method."); #endif HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, - get_ttyp ()->master_pid); - termios_printf ("tty own handle %p",tty_owner); + p->dwProcessId); if (tty_owner == NULL) { termios_printf ("can't open tty (%d) handle process %d", @@ -595,7 +602,7 @@ fhandler_tty_slave::open (int flags, mode_t) out: usecount = 0; - archetype->usecount++; + arch->usecount++; report_tty_counts (this, "opened", ""); myself->set_ctty (get_ttyp (), flags, arch); @@ -626,6 +633,8 @@ fhandler_tty_slave::close () } termios_printf ("closing last open %s handle", ttyname ()); + if (inuse && !CloseHandle (inuse)) + termios_printf ("CloseHandle (inuse), %E"); return fhandler_tty_common::close (); } @@ -917,106 +926,18 @@ fhandler_tty_slave::dup (fhandler_base *child) arch->usecount++; cygheap->manage_console_count ("fhandler_tty_slave::dup", 1); report_tty_counts (child, "duped", ""); -#if 0 // CGF: Remove this again as it screws up expect - myself->set_ctty (get_ttyp (), openflags, arch); -#endif return 0; } int -fhandler_tty_common::dup (fhandler_base *child) +fhandler_pty_master::dup (fhandler_base *child) { - fhandler_tty_slave *fts = (fhandler_tty_slave *) child; - int errind; - - fts->tcinit (get_ttyp ()); - - attach_tty (get_unit ()); - - HANDLE nh; - - if (output_done_event == NULL) - fts->output_done_event = NULL; - else if (!DuplicateHandle (hMainProc, output_done_event, hMainProc, - &fts->output_done_event, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 1; - goto err; - } - if (ioctl_request_event == NULL) - fts->ioctl_request_event = NULL; - else if (!DuplicateHandle (hMainProc, ioctl_request_event, hMainProc, - &fts->ioctl_request_event, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 2; - goto err; - } - if (ioctl_done_event == NULL) - fts->ioctl_done_event = NULL; - else if (!DuplicateHandle (hMainProc, ioctl_done_event, hMainProc, - &fts->ioctl_done_event, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 3; - goto err; - } - if (!DuplicateHandle (hMainProc, input_available_event, hMainProc, - &fts->input_available_event, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 4; - goto err; - } - if (!DuplicateHandle (hMainProc, output_mutex, hMainProc, - &fts->output_mutex, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 5; - goto err; - } - if (!DuplicateHandle (hMainProc, input_mutex, hMainProc, - &fts->input_mutex, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 6; - goto err; - } - if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, - &nh, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 7; - goto err; - } - fts->set_io_handle (nh); - - if (!DuplicateHandle (hMainProc, get_output_handle (), hMainProc, - &nh, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 8; - goto err; - } - fts->set_output_handle (nh); - - if (inuse == NULL) - fts->inuse = NULL; - else if (!DuplicateHandle (hMainProc, inuse, hMainProc, - &fts->inuse, 0, 1, - DUPLICATE_SAME_ACCESS)) - { - errind = 9; - goto err; - } - + fhandler_tty_master *arch = (fhandler_tty_master *) archetype; + *(fhandler_tty_master *) child = *arch; + child->usecount = 0; + arch->usecount++; + report_tty_counts (child, "duped master", ""); return 0; - -err: - __seterrno (); - termios_printf ("dup %d failed in DuplicateHandle, %E", errind); - return -1; } int @@ -1152,25 +1073,48 @@ out: fhandler_pty_master */ fhandler_pty_master::fhandler_pty_master () - : fhandler_tty_common () + : fhandler_tty_common (), pktmode (0), need_nl (0), dwProcessId (0) { } int fhandler_pty_master::open (int flags, mode_t) { + fhandler_pty_master *arch = (fhandler_tty_master *) cygheap->fdtab.find_archetype (pc.dev); + if (arch) + { + *this = *(fhandler_pty_master *) arch; + termios_printf ("copied fhandler_pty_master archetype"); + set_flags ((flags & ~O_TEXT) | O_BINARY); + goto out; + } + int ntty = cygwin_shared->tty.allocate_tty (false); if (ntty < 0) return 0; slave = *ttys_dev; slave.setunit (ntty); - cygwin_shared->tty[ntty]->common_init (this); + if (!setup (*cygwin_shared->tty[ntty])) + { + ReleaseMutex (tty_mutex); // lock was set in allocate_tty + return 0; + } ReleaseMutex (tty_mutex); // lock was set in allocate_tty - inuse = get_ttyp ()->create_inuse (TTY_MASTER_ALIVE); set_flags ((flags & ~O_TEXT) | O_BINARY); set_open_status (); + // + // FIXME: Do this better someday + arch = (fhandler_tty_master *) cmalloc (HEAP_ARCHETYPES, sizeof (*this)); + *((fhandler_pty_master **) cygheap->fdtab.add_archetype ()) = arch; + archetype = arch; + *arch = *this; + arch->dwProcessId = GetCurrentProcessId (); +out: + usecount = 0; + arch->usecount++; + report_tty_counts (this, "opened master", ""); termios_printf ("opened pty master tty%d", get_unit ()); return 1; } @@ -1192,8 +1136,6 @@ fhandler_tty_common::close () termios_printf ("CloseHandle (ioctl_done_event), %E"); if (ioctl_request_event && !CloseHandle (ioctl_request_event)) termios_printf ("CloseHandle (ioctl_request_event), %E"); - if (inuse && !CloseHandle (inuse)) - termios_printf ("CloseHandle (inuse), %E"); if (!ForceCloseHandle (input_mutex)) termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex); if (!ForceCloseHandle (output_mutex)) @@ -1203,21 +1145,18 @@ fhandler_tty_common::close () if (!ForceCloseHandle1 (get_output_handle (), to_pty)) termios_printf ("CloseHandle (get_output_handle ()<%p>), %E", get_output_handle ()); +#if 0 // CGF - DELETME /* Send EOF to slaves if master side is closed */ if (!get_ttyp ()->master_alive ()) { termios_printf ("no more masters left. sending EOF"); SetEvent (input_available_event); } +#endif if (!ForceCloseHandle (input_available_event)) termios_printf ("CloseHandle (input_available_event<%p>), %E", input_available_event); - if (!hExeced) - { - inuse = NULL; - set_io_handle (NULL); - } return 0; } @@ -1228,28 +1167,28 @@ fhandler_pty_master::close () while (accept_input () > 0) continue; #endif + archetype->usecount--; + report_tty_counts (this, "closing master", ""); - if (get_ttyp ()->master_alive ()) - fhandler_tty_common::close (); - else + if (archetype->usecount) { - termios_printf ("freeing tty%d (%d)", get_unit (), get_ttyp ()->ntty); -#if 0 - if (get_ttyp ()->to_slave) - ForceCloseHandle1 (get_ttyp ()->to_slave, to_slave); - if (get_ttyp ()->from_slave) - ForceCloseHandle1 (get_ttyp ()->from_slave, from_slave); +#ifdef DEBUGGING + if (archetype->usecount < 0) + system_printf ("error: usecount %d", archetype->usecount); #endif - if (get_ttyp ()->from_master) - CloseHandle (get_ttyp ()->from_master); - if (get_ttyp ()->to_master) - CloseHandle (get_ttyp ()->to_master); + termios_printf ("just returning because archetype usecount is != 0"); + return 0; + } - fhandler_tty_common::close (); + fhandler_tty_master *arch = (fhandler_tty_master *) archetype; + 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); + fhandler_tty_common::close (); - if (!hExeced) - get_ttyp ()->init (); - } + if (!hExeced && get_ttyp ()->master_pid == myself->pid) + get_ttyp ()->init (); return 0; } @@ -1353,73 +1292,25 @@ fhandler_pty_master::ptsname () void fhandler_tty_common::set_close_on_exec (bool val) { - if (archetype) - close_on_exec (val); - else - { - if (output_done_event) - set_no_inheritance (output_done_event, val); - if (ioctl_request_event) - set_no_inheritance (ioctl_request_event, val); - if (ioctl_done_event) - set_no_inheritance (ioctl_done_event, val); - if (inuse) - set_no_inheritance (inuse, val); - set_no_inheritance (output_mutex, val); - set_no_inheritance (input_mutex, val); - set_no_inheritance (input_available_event, val); - set_no_inheritance (output_handle, val); -#ifndef DEBUGGING - fhandler_base::set_close_on_exec (val); -#else - /* FIXME: This is a duplication from fhandler_base::set_close_on_exec. - It is here because we need to specify the "from_pty" stuff here or - we'll get warnings from ForceCloseHandle when debugging. */ - set_no_inheritance (get_io_handle (), val); - close_on_exec (val); -#endif - } + // Cygwin processes will handle this specially on exec. + close_on_exec (val); } void fhandler_tty_slave::fixup_after_fork (HANDLE parent) { + // fork_fixup (parent, inuse, "inuse"); // fhandler_tty_common::fixup_after_fork (parent); report_tty_counts (this, "inherited", ""); } void -fhandler_tty_common::fixup_after_fork (HANDLE parent) +fhandler_tty_slave::fixup_after_exec () { - fhandler_termios::fixup_after_fork (parent); - if (output_done_event) - fork_fixup (parent, output_done_event, "output_done_event"); - if (ioctl_request_event) - fork_fixup (parent, ioctl_request_event, "ioctl_request_event"); - if (ioctl_done_event) - fork_fixup (parent, ioctl_done_event, "ioctl_done_event"); - if (output_mutex) - fork_fixup (parent, output_mutex, "output_mutex"); - if (input_mutex) - fork_fixup (parent, input_mutex, "input_mutex"); - if (input_available_event) - fork_fixup (parent, input_available_event, "input_available_event"); - fork_fixup (parent, inuse, "inuse"); -} - -void -fhandler_pty_master::set_close_on_exec (bool val) -{ - fhandler_tty_common::set_close_on_exec (val); - - /* FIXME: There is a console handle leak here. */ - if (get_ttyp ()->master_pid == GetCurrentProcessId ()) - { - get_ttyp ()->from_slave = get_handle (); - get_ttyp ()->to_slave = get_output_handle (); - termios_printf ("from_slave %p, to_slave %p", get_handle (), - get_output_handle ()); - } + if (close_on_exec ()) + close (); + else + fixup_after_fork (NULL); } int @@ -1434,3 +1325,152 @@ fhandler_tty_master::init_console () console->uninterruptible_io (true); return 0; } + +#define close_maybe(h) \ + do { \ + if (h) \ + CloseHandle (h); \ + } while (0) + +bool +fhandler_pty_master::setup (tty& t) +{ + tcinit (&t, true); /* Set termios information. Force initialization. */ + + const char *errstr = NULL; + DWORD pipe_mode = PIPE_NOWAIT; + + /* Create communication pipes */ + +#if 0 // CGF: don't think this is needed since it is handled by the constructor + input_handle = io_handle = output_done_event = ioctl_done_event = + ioctl_request_event = input_available_event = output_mutex = input_mutex NULL; +#endif + + /* FIXME: should this be sec_none_nih? */ + if (!CreatePipe (&from_master, &get_output_handle (), &sec_all, 128 * 1024)) + { + errstr = "input pipe"; + goto err; + } + + if (!CreatePipe (&get_io_handle (), &to_master, &sec_all, 128 * 1024)) + { + errstr = "output pipe"; + goto err; + } + + if (!SetNamedPipeHandleState (&get_output_handle (), &pipe_mode, NULL, NULL)) + termios_printf ("can't set output_handle(%p) to non-blocking mode", + get_output_handle ()); + + need_nl = 0; + + /* We do not open allow the others to open us (for handle duplication) + but rely on cygheap->inherited_ctty for descendant processes. + In the future the cygserver may allow access by others. */ + +#ifdef USE_SERVER + if (wincap.has_security ()) + { + if (cygserver_running == CYGSERVER_UNKNOWN) + cygserver_init (); + } +#endif + + /* Create synchronisation events */ + + if (get_major () == DEV_TTYM_MAJOR) + { + if (!(output_done_event = t.get_event (errstr = OUTPUT_DONE_EVENT))) + goto err; + if (!(ioctl_done_event = t.get_event (errstr = IOCTL_DONE_EVENT))) + goto err; + if (!(ioctl_request_event = t.get_event (errstr = IOCTL_REQUEST_EVENT))) + goto err; + } + + if (!(input_available_event = t.get_event (errstr = INPUT_AVAILABLE_EVENT, TRUE))) + goto err; + + char buf[CYG_MAX_PATH]; + errstr = shared_name (buf, OUTPUT_MUTEX, t.ntty); + if (!(output_mutex = CreateMutex (&sec_all, FALSE, buf))) + goto err; + + errstr = shared_name (buf, INPUT_MUTEX, t.ntty); + if (!(input_mutex = CreateMutex (&sec_all, FALSE, buf))) + goto err; + + if (!DuplicateHandle (hMainProc, from_master, hMainProc, &from_master, 0, false, + DUPLICATE_SAME_ACCESS)) + { + errstr = "non-inheritable from_master"; + goto err; + } + + if (!DuplicateHandle (hMainProc, to_master, hMainProc, &to_master, 0, false, + DUPLICATE_SAME_ACCESS)) + { + errstr = "non-inheritable to_master"; + goto err; + } + + t.from_master = from_master; + t.to_master = to_master; + // /* screws up tty master */ ProtectHandle1INH (output_mutex, output_mutex); + // /* screws up tty master */ ProtectHandle1INH (input_mutex, input_mutex); + t.winsize.ws_col = 80; + t.winsize.ws_row = 25; + t.master_pid = myself->pid; + + termios_printf ("tty%d opened - from_slave %p, to_slave %p", t.ntty, + get_io_handle (), get_output_handle ()); + return true; + +err: + __seterrno (); + close_maybe (get_io_handle ()); + close_maybe (get_output_handle ()); + close_maybe (output_done_event); + close_maybe (ioctl_done_event); + close_maybe (ioctl_request_event); + close_maybe (input_available_event); + close_maybe (output_mutex); + close_maybe (input_mutex); + termios_printf ("tty%d open failed - failed to create %s", errstr); + return false; +} + +void +fhandler_pty_master::fixup_after_fork (HANDLE parent) +{ + DWORD wpid = GetCurrentProcessId (); + fhandler_tty_master *arch = (fhandler_tty_master *) archetype; + if (arch->dwProcessId != wpid) + { + tty& t = *get_ttyp (); + if (!DuplicateHandle (parent, arch->from_master, hMainProc, + &arch->from_master, 0, false, DUPLICATE_SAME_ACCESS)) + system_printf ("couldn't duplicate from_parent(%p), %E", arch->from_master); + if (!DuplicateHandle (parent, arch->to_master, hMainProc, + &arch->to_master, 0, false, DUPLICATE_SAME_ACCESS)) + system_printf ("couldn't duplicate to_parent(%p), %E", arch->from_master); + if (myself->pid == t.master_pid) + { + t.from_master = arch->from_master; + t.to_master = arch->to_master; + } + arch->dwProcessId = wpid; + } + report_tty_counts (this, "inherited master", ""); +} + +void +fhandler_pty_master::fixup_after_exec () +{ + if (close_on_exec ()) + close (); + else + fixup_after_fork (spawn_info->parent); +} diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index f0c037f61..821807641 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -142,7 +142,7 @@ public: cygwin_version.api_minor) #define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION) -#define SHARED_INFO_CB 21008 +#define SHARED_INFO_CB 19984 #define CURR_SHARED_MAGIC 0x818f75beU diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index bbc6f21e7..69d6a9b34 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -130,11 +130,11 @@ tty_list::terminate () int ttynum = myself->ctty; /* Keep master running till there are connected clients */ - if (ttynum != -1 && ttys[ttynum].master_pid == GetCurrentProcessId ()) + if (ttynum != -1 && ttys[ttynum].master_pid == myself->pid) { tty *t = ttys + ttynum; - CloseHandle (t->from_master); - CloseHandle (t->to_master); + CloseHandle (tty_master->from_master); + CloseHandle (tty_master->to_master); /* Wait for children which rely on tty handling in this process to go away */ for (int i = 0; ; i++) @@ -155,9 +155,9 @@ tty_list::terminate () termios_printf ("WFSO for tty_mutex %p failed, %E", tty_mutex); termios_printf ("tty %d master about to finish", ttynum); - ForceCloseHandle1 (t->to_slave, to_pty); - ForceCloseHandle1 (t->from_slave, from_pty); - CloseHandle (tty_master->inuse); + CloseHandle (tty_master->get_io_handle ()); + CloseHandle (tty_master->get_output_handle ()); + t->init (); char buf[20]; @@ -312,12 +312,6 @@ tty::slave_alive () return alive (TTY_SLAVE_ALIVE); } -bool -tty::master_alive () -{ - return alive (TTY_MASTER_ALIVE); -} - bool tty::alive (const char *fmt) { @@ -371,8 +365,6 @@ tty::init () setsid (0); pgid = 0; hwnd = NULL; - to_slave = NULL; - from_slave = NULL; was_opened = 0; master_pid = 0; } @@ -394,107 +386,3 @@ tty::get_event (const char *fmt, BOOL manual_reset) termios_printf ("created event %s", buf); return hev; } - -bool -tty::make_pipes (fhandler_pty_master *ptym) -{ - /* Create communication pipes */ - - /* FIXME: should this be sec_none_nih? */ - if (!CreatePipe (&from_master, &to_slave, &sec_all, 128 * 1024)) - { - termios_printf ("can't create input pipe"); - set_errno (ENOENT); - return false; - } - - // ProtectHandle1INH (to_slave, to_pty); - if (!CreatePipe (&from_slave, &to_master, &sec_all, 128 * 1024)) - { - termios_printf ("can't create output pipe"); - set_errno (ENOENT); - return false; - } - // ProtectHandle1INH (from_slave, from_pty); - termios_printf ("tty%d from_slave %p, to_slave %p", ntty, from_slave, - to_slave); - - DWORD pipe_mode = PIPE_NOWAIT; - if (!SetNamedPipeHandleState (to_slave, &pipe_mode, NULL, NULL)) - termios_printf ("can't set to_slave to non-blocking mode"); - ptym->set_io_handle (from_slave); - ptym->set_output_handle (to_slave); - return true; -} - -bool -tty::common_init (fhandler_pty_master *ptym) -{ - /* Set termios information. Force initialization. */ - ptym->tcinit (this, true); - - if (!make_pipes (ptym)) - return false; - ptym->need_nl = 0; - - /* Save our pid */ - - master_pid = GetCurrentProcessId (); - - /* We do not open allow the others to open us (for handle duplication) - but rely on cygheap->inherited_ctty for descendant processes. - In the future the cygserver may allow access by others. */ - -#ifdef USE_SERVER - if (wincap.has_security ()) - { - if (cygserver_running == CYGSERVER_UNKNOWN) - cygserver_init (); - } -#endif - - /* Create synchronisation events */ - - if (ptym->get_major () != DEV_TTYM_MAJOR) - { - ptym->output_done_event = ptym->ioctl_done_event = - ptym->ioctl_request_event = NULL; - } - else - { - if (!(ptym->output_done_event = get_event (OUTPUT_DONE_EVENT))) - return false; - if (!(ptym->ioctl_done_event = get_event (IOCTL_DONE_EVENT))) - return false; - if (!(ptym->ioctl_request_event = get_event (IOCTL_REQUEST_EVENT))) - return false; - } - - if (!(ptym->input_available_event = get_event (INPUT_AVAILABLE_EVENT, TRUE))) - return false; - - char buf[CYG_MAX_PATH]; - shared_name (buf, OUTPUT_MUTEX, ntty); - if (!(ptym->output_mutex = CreateMutex (&sec_all, FALSE, buf))) - { - termios_printf ("can't create %s", buf); - set_errno (ENOENT); - return false; - } - - shared_name (buf, INPUT_MUTEX, ntty); - if (!(ptym->input_mutex = CreateMutex (&sec_all, FALSE, buf))) - { - termios_printf ("can't create %s", buf); - set_errno (ENOENT); - return false; - } - - // /* screws up tty master */ ProtectHandle1INH (ptym->output_mutex, output_mutex); - // /* screws up tty master */ ProtectHandle1INH (ptym->input_mutex, input_mutex); - winsize.ws_col = 80; - winsize.ws_row = 25; - - termios_printf ("tty%d opened", ntty); - return true; -} diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 27e517d9c..ceb265e45 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -88,21 +88,18 @@ class tty: public tty_min HANDLE get_event (const char *fmt, BOOL manual_reset = FALSE) __attribute__ ((regparm (3))); public: - DWORD master_pid; /* Win32 PID of tty master process */ + pid_t master_pid; /* PID of tty master process */ - HANDLE from_master, to_slave; - HANDLE from_slave, to_master; + HANDLE from_master, to_master; int read_retval; bool was_opened; /* True if opened at least once. */ void init (); HANDLE create_inuse (const char *); - bool common_init (fhandler_pty_master *); bool alive (const char *fmt); bool slave_alive (); bool master_alive (); - bool make_pipes (fhandler_pty_master *ptym); HANDLE open_mutex (const char *mutex); HANDLE open_output_mutex (); HANDLE open_input_mutex (); @@ -116,6 +113,7 @@ public: } return slave_alive (); } + friend class fhandler_pty_master; }; class tty_list -- cgit v1.2.3