summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_tty.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_tty.cc')
-rw-r--r--winsup/cygwin/fhandler_tty.cc115
1 files changed, 61 insertions, 54 deletions
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index d5ebec94a..aee5b806f 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -539,7 +539,7 @@ void
fhandler_pty_slave::open_setup (int flags)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
- myself->set_ctty (get_ttyp (), flags, this);
+ myself->set_ctty (this, flags);
cygheap->manage_console_count ("fhandler_pty_slave::open_setup", 1);
report_tty_counts (this, "opened", "");
}
@@ -614,7 +614,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
if (bg <= bg_eof)
return (ssize_t) bg;
- termios_printf ("tty%d, write(%x, %d)", get_unit (), ptr, len);
+ termios_printf ("pty%d, write(%x, %d)", get_unit (), ptr, len);
push_process_state process_state (PID_TTYOU);
@@ -891,15 +891,16 @@ out:
}
int
-fhandler_pty_slave::dup (fhandler_base *child)
+fhandler_pty_slave::dup (fhandler_base *child, int flags)
{
+ myself->set_ctty (this, flags);
cygheap->manage_console_count ("fhandler_pty_slave::dup", 1);
report_tty_counts (child, "duped slave", "");
return 0;
}
int
-fhandler_pty_master::dup (fhandler_base *child)
+fhandler_pty_master::dup (fhandler_base *child, int)
{
report_tty_counts (child, "duped master", "");
return 0;
@@ -947,7 +948,7 @@ int
fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
{
termios_printf ("ioctl (%x)", cmd);
- int res = ioctl_termios (cmd, (int) arg);
+ int res = fhandler_termios::ioctl (cmd, arg);
if (res <= 0)
return res;
@@ -1184,35 +1185,32 @@ errout:
/*******************************************************
fhandler_pty_master
*/
-fhandler_pty_master::fhandler_pty_master ()
- : fhandler_pty_common (), pktmode (0), need_nl (0), dwProcessId (0)
+fhandler_pty_master::fhandler_pty_master (int unit)
+ : fhandler_pty_common (), pktmode (0), master_ctl (NULL),
+ master_thread (NULL), from_master (NULL), to_master (NULL),
+ dwProcessId (0), need_nl (0)
{
+ if (unit >= 0)
+ dev ().parse (DEV_TTYM_MAJOR, unit);
+ else if (!setup ())
+ dev ().parse (FH_ERROR);
}
int
fhandler_pty_master::open (int flags, mode_t)
{
- /* Note that allocate returns with the tty lock set if it was successful. */
- int unit = cygwin_shared->tty.allocate ();
- if (unit < 0)
- return 0;
-
- dev().parse (DEV_TTYM_MAJOR, unit);
- if (!setup ())
- {
- lock_ttys::release ();
- return 0;
- }
- lock_ttys::release ();
- set_flags ((flags & ~O_TEXT) | O_BINARY);
set_open_status ();
-
dwProcessId = GetCurrentProcessId ();
+ return 1;
+}
- char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
- __small_sprintf (buf, "opened pty master for tty%d", get_unit ());
+void
+fhandler_pty_master::open_setup (int flags)
+{
+ set_flags ((flags & ~O_TEXT) | O_BINARY);
+ char buf[sizeof ("opened pty master for ptyNNNNNNNNNNN")];
+ __small_sprintf (buf, "opened pty master for pty%d", get_unit ());
report_tty_counts (this, buf, "");
- return 1;
}
_off64_t
@@ -1225,7 +1223,7 @@ fhandler_pty_common::lseek (_off64_t, int)
int
fhandler_pty_common::close ()
{
- termios_printf ("tty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
+ termios_printf ("pty%d <%p,%p> closing", get_unit (), get_handle (), get_output_handle ());
if (!ForceCloseHandle (input_mutex))
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
if (!ForceCloseHandle (output_mutex))
@@ -1245,6 +1243,8 @@ void
fhandler_pty_master::cleanup ()
{
report_tty_counts (this, "closing master", "");
+ if (archetype)
+ from_master = to_master = NULL;
}
int
@@ -1272,11 +1272,14 @@ fhandler_pty_master::close ()
CloseHandle (master_ctl);
master_thread->detach ();
}
- if (!ForceCloseHandle (from_master))
- termios_printf ("error closing from_master %p, %E", from_master);
- if (!ForceCloseHandle (to_master))
- termios_printf ("error closing from_master %p, %E", to_master);
}
+
+ if (!ForceCloseHandle (from_master))
+ termios_printf ("error closing from_master %p, %E", from_master);
+ if (!ForceCloseHandle (to_master))
+ termios_printf ("error closing from_master %p, %E", to_master);
+ from_master = to_master = NULL;
+
fhandler_pty_common::close ();
if (hExeced || get_ttyp ()->master_pid != myself->pid)
@@ -1287,6 +1290,15 @@ fhandler_pty_master::close ()
return 0;
}
+/* This is just to catch error conditions. Since the constructor
+ ctually opens some handles, and stat() does not open an fd, they need
+ to be closed when the fhandler goes away. */
+fhandler_pty_master::~fhandler_pty_master ()
+{
+ if (from_master && to_master)
+ close_with_arch ();
+}
+
ssize_t __stdcall
fhandler_pty_master::write (const void *ptr, size_t len)
{
@@ -1361,7 +1373,7 @@ fhandler_pty_master::tcflush (int queue)
int
fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
{
- int res = ioctl_termios (cmd, (int) arg);
+ int res = fhandler_termios::ioctl (cmd, arg);
if (res <= 0)
return res;
@@ -1408,7 +1420,7 @@ fhandler_pty_master::ptsname ()
{
static char buf[TTY_NAME_MAX];
- __small_sprintf (buf, "/dev/tty%d", get_unit ());
+ __small_sprintf (buf, "/dev/pty%d", get_unit ());
return buf;
}
@@ -1587,32 +1599,27 @@ fhandler_pty_master::setup ()
security_descriptor sd;
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
- tty& t = *cygwin_shared->tty[get_unit ()];
- _tc = (tty_min *)&t;
+ /* Find an unallocated pty to use. */
+ int unit = cygwin_shared->tty.allocate (from_master, get_output_handle ());
+ if (unit < 0)
+ return false;
+
+ ProtectHandle1 (get_output_handle (), to_pty);
+
+ tty& t = *cygwin_shared->tty[unit];
+ _tc = (tty_min *) &t;
tcinit (true); /* Set termios information. Force initialization. */
const char *errstr = NULL;
DWORD pipe_mode = PIPE_NOWAIT;
- /* Create communication pipes */
- char pipename[sizeof("ptyNNNN-from-master")];
- __small_sprintf (pipename, "pty%d-from-master", get_unit ());
- res = fhandler_pipe::create_selectable (&sec_none, from_master,
- get_output_handle (), 128 * 1024,
- pipename);
- if (res)
- {
- errstr = "input pipe";
- goto err;
- }
-
- ProtectHandle1 (get_output_handle (), to_pty);
if (!SetNamedPipeHandleState (get_output_handle (), &pipe_mode, NULL, NULL))
termios_printf ("can't set output_handle(%p) to non-blocking mode",
get_output_handle ());
- __small_sprintf (pipename, "pty%d-to-master", get_unit ());
+ char pipename[sizeof("ptyNNNN-from-master")];
+ __small_sprintf (pipename, "pty%d-to-master", unit);
res = fhandler_pipe::create_selectable (&sec_none, get_io_handle (),
to_master, 128 * 1024, pipename);
if (res)
@@ -1622,7 +1629,6 @@ fhandler_pty_master::setup ()
}
ProtectHandle1 (get_io_handle (), from_pty);
- need_nl = 0;
/* Create security attribute. Default permissions are 0620. */
sd.malloc (sizeof (SECURITY_DESCRIPTOR));
@@ -1642,18 +1648,18 @@ fhandler_pty_master::setup ()
goto err;
char buf[MAX_PATH];
- errstr = shared_name (buf, OUTPUT_MUTEX, t.get_unit ());
+ errstr = shared_name (buf, OUTPUT_MUTEX, unit);
if (!(output_mutex = CreateMutex (&sa, FALSE, buf)))
goto err;
- errstr = shared_name (buf, INPUT_MUTEX, t.get_unit ());
+ errstr = shared_name (buf, INPUT_MUTEX, unit);
if (!(input_mutex = CreateMutex (&sa, FALSE, buf)))
goto err;
/* Create master control pipe which allows the master to duplicate
the pty pipe handles to processes which deserve it. */
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl",
- &installation_key, get_unit ());
+ &installation_key, unit);
master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX,
PIPE_WAIT | PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE, 1, 4096, 4096,
@@ -1676,7 +1682,9 @@ fhandler_pty_master::setup ()
t.winsize.ws_row = 25;
t.master_pid = myself->pid;
- termios_printf ("tty%d opened - from_pty %p, to_pty %p", t.get_unit (),
+ dev ().parse (DEV_TTYM_MAJOR, unit);
+
+ termios_printf ("this %p, pty%d opened - from_pty %p, to_pty %p", this, unit,
get_io_handle (), get_output_handle ());
return true;
@@ -1690,8 +1698,7 @@ err:
close_maybe (from_master);
close_maybe (to_master);
close_maybe (master_ctl);
- termios_printf ("tty%d open failed - failed to create %s", t.get_unit (),
- errstr);
+ termios_printf ("pty%d open failed - failed to create %s", unit, errstr);
return false;
}