Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog59
-rw-r--r--winsup/cygwin/fhandler.cc6
-rw-r--r--winsup/cygwin/fhandler.h19
-rw-r--r--winsup/cygwin/fhandler_termios.cc14
-rw-r--r--winsup/cygwin/fhandler_tty.cc412
-rw-r--r--winsup/cygwin/shared_info.h2
-rw-r--r--winsup/cygwin/tty.cc124
-rw-r--r--winsup/cygwin/tty.h8
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 <cgf@timesys.com>
+
+ * 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 <cgf@timesys.com>
* 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<arch>", 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];
@@ -313,12 +313,6 @@ tty::slave_alive ()
}
bool
-tty::master_alive ()
-{
- return alive (TTY_MASTER_ALIVE);
-}
-
-bool
tty::alive (const char *fmt)
{
HANDLE ev;
@@ -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