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:
authorChristopher Faylor <me@cgf.cx>2011-05-06 02:30:53 +0400
committerChristopher Faylor <me@cgf.cx>2011-05-06 02:30:53 +0400
commit92ddb74290655b6f9394801dac4242c93e03f9ed (patch)
tree5c0055dd6ea6b04758afe3e49bf66ee39c231030 /winsup/cygwin/fhandler_tty.cc
parentd8ff96389f6beb97defd285b224fead3f37398f5 (diff)
* cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().
* debug.cc (close_handle): Call debugger on failure. * devices.in (device::tty_to_real_device): Delete. * devices.h (device::tty_to_real_device): Ditto. * devices.cc: Regenerate. * dtable.cc: Delete old ifdef'ed vfork code. (dtable::release): Don't handle archetype here. (dtable::init_std_file_from_handle): Consolidate console tests. Generate major/minor for tty ASAP. Fix incorrect setting of DEV_TTYS* for serial. (fh_alloc): New function derived from build_fh_pc. Pass current tty when building tty. (build_pc_pc): Use fh_alloc to create. Set name from fh->dev if appropriate. Generate an archetype or point to one here. (dtable::dup_worker): Deal with archetypes. Rely on = operator copying whole class rather than just fhandler_base. (dtable::fixup_after_exec): Call close_with_arch to handle closing of fhandlers with archetypes. * fhandler.cc (fhandler_base::operator =): Call memcpy with fhandler's size() rather than sizeof fhandler_base. (fhandler_base::open_with_arch): New function. Handles opening of fhandler's with archetypes, dealing with usecounts, etc. (fhandler_base::close_with_arch): Ditto for close. * fhandler.h: Many changes for archetypes. (fhandler_base::set_name): Set both normalized path and regular path. (fhandler_base::open_with_arch): New function. (fhandler_base::open_setup): Ditto. (fhandler_base::use_archetype): Ditto. (fhandler_base::_archetype_usecount): Ditto. (fhandler_*::size): Ditto. (fhandler_dev_tape::open): Remove virtual decoration. (fhandler_console::use_archetype): New function. Return true. (fhandler_console::open_setup): New function. (fhandler_console::dup): Delete. (fhandler_tty_slave::fhandler_tty_slave): Redeclare to take an argument. (fhandler_tty_slave::use_archetype): New function. Return true. (fhandler_tty_slave::cleanup): New function. (fhandler_pty_master::use_archetype): New function. Return true. (fhandler_pty_master::cleanup): New function. (fhandler_pty_master::is_tty_master): New function. Return false. (fhandler_tty_master::is_tty_master): New function. Return true. (fhandler_dev_dsp::fhandler_dev_dsp): New function. Return true. (report_tty_counts): Only report on archetype's usecount if there is one. * fhandler_console.cc (fhandler_console::get_tty_stuff): Remove handling of setsid, set_ctty, set_flags, and manage_console_count. (fhandler_console::open_setup): New function. Implement functionality removed from get_tty_stuff. (fhandler_console::dup): Delete. (fhandler_console::output_tcsetattr): Set errno on error. (fhandler_console::fhandler_console): Set device early. (fhandler_console::init): Use open_with_arch to open console handles. (fhandler_console::fixup_after_fork_exec): Nuke most of the stuff for dealing with console handles. * fhandler_dsp.cc (fhandler_dev_dsp::open): Remove archetype handling. (fhandler_dev_dsp::write): Ditto. (fhandler_dev_dsp::read): Ditto. (fhandler_dev_dsp::close): Ditto. (fhandler_dev_dsp::dup): Ditto. (fhandler_dev_dsp::ioctl): Ditto. (fhandler_dev_dsp::fixup_after_fork): Ditto. (fhandler_dev_dsp::fixup_after_exec): Ditto. * fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Add a little more debugging. (fhandler_tty_common::__release_output_mutex): Ditto. (fhandler_pty_master::process_slave_output): Ditto. Don't do signal handling or pthread_cancel handling in the tty master thread. (process_output): Minor reorg. (fhandler_tty_slave::fhandler_tty_slave): Set device based on new ntty argument. (fhandler_tty_slave::open): Remove archetype handling. Move some processing into open_setup(). (fhandler_tty_slave::open_setup): New function. (fhandler_tty_slave::cleanup): New function. (fhandler_tty_slave::close): Remove archetype handling. Move some processing into cleanup(). (fhandler_tty_slave::init): Rename argument from f to h. Open device using open_with_arch(). Remove archetype handling. (fhandler_pty_master::dup): Ditto. (fhandler_pty_master::open): Ditto. (fhandler_pty_master::close): Ditto. Move some handling to cleanup(). (fhandler_pty_master::cleanup): New function. (fhandler_tty_master::init_console): Give unique name to captive console fhandler. * pinfo.cc (_pinfo::set_ctty): Rename argument from arch to fh. Eliminate archetype assumption. * syscalls.cc (close_all_files): Use close_with_arch for closing. (open): Use open_with_arch() rather than open(). (close): Use close_with_arch() rather than close().
Diffstat (limited to 'winsup/cygwin/fhandler_tty.cc')
-rw-r--r--winsup/cygwin/fhandler_tty.cc186
1 files changed, 69 insertions, 117 deletions
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f55eab21e..42e539191 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -113,7 +113,7 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
DWORD ms)
{
if (strace.active ())
- strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: waiting %d ms", ln, ms);
+ strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex (%p): waiting %d ms", ln, output_mutex, ms);
DWORD res = WaitForSingleObject (output_mutex, ms);
if (res == WAIT_OBJECT_0)
{
@@ -138,11 +138,11 @@ fhandler_tty_common::__release_output_mutex (const char *fn, int ln)
{
#ifndef DEBUGGING
if (strace.active ())
- strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex released", ln);
+ strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex(%p) released", ln, output_mutex);
#else
if (osi > 0)
osi--;
- termios_printf ("released at %s:%d, osi %d", fn, ln, osi);
+ termios_printf ("released(%p) at %s:%d, osi %d", output_mutex, fn, ln, osi);
termios_printf (" for %s:%d (%s)", ostack[osi].fn, ostack[osi].ln, ostack[osi].tname);
ostack[osi].ln = -ln;
#endif
@@ -299,7 +299,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
while (1)
{
if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL))
- goto err;
+ {
+ termios_printf ("PeekNamedPipe failed, %E");
+ goto err;
+ }
if (n > 0)
break;
if (hit_eof ())
@@ -307,6 +310,10 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
/* DISCARD (FLUSHO) and tcflush can finish here. */
if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
goto out;
+
+ if (is_tty_master ())
+ continue;
+
if (is_nonblocking ())
{
set_errno (EAGAIN);
@@ -321,17 +328,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
rc = -1;
goto out;
}
-
}
- if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
- goto err;
+ if (!ReadFile (handle, outbuf, rlen, &n, NULL))
+ {
+ termios_printf ("ReadFile failed, %E");
+ goto err;
+ }
}
termios_printf ("bytes read %u", n);
get_ttyp ()->write_error = 0;
if (output_done_event != NULL)
- SetEvent (output_done_event);
+ SetEvent (output_done_event);
if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
continue;
@@ -420,14 +429,17 @@ process_output (void *)
for (;;)
{
int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
- if (n <= 0)
+ if (n > 0)
+ {
+ n = tty_master->console->write ((void *) buf, (size_t) n);
+ tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
+ }
+ else
{
if (n < 0)
termios_printf ("ReadFile %E");
ExitThread (0);
}
- n = tty_master->console->write ((void *) buf, (size_t) n);
- tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
}
}
@@ -454,9 +466,12 @@ process_ioctl (void *)
/**********************************************************************/
/* Tty slave stuff */
-fhandler_tty_slave::fhandler_tty_slave ()
+fhandler_tty_slave::fhandler_tty_slave (int ntty)
: fhandler_tty_common (), inuse (NULL)
-{}
+{
+ if (ntty >= 0)
+ dev ().parse (DEV_TTYS_MAJOR, ntty);
+}
/* FIXME: This function needs to close handles when it has
a failing condition. */
@@ -472,28 +487,13 @@ fhandler_tty_slave::open (int flags, mode_t)
NULL
};
- const char *errmsg = NULL;
-
for (HANDLE **h = handles; *h; h++)
**h = NULL;
- if (get_device () == FH_TTY)
- dev().tty_to_real_device ();
- fhandler_tty_slave *arch = (fhandler_tty_slave *) cygheap->fdtab.find_archetype (pc.dev);
- if (arch)
- {
- *this = *(fhandler_tty_slave *) arch;
- 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;
- }
-
tcinit (cygwin_shared->tty[get_unit ()], false);
cygwin_shared->tty.attach (get_unit ());
- set_flags ((flags & ~O_TEXT) | O_BINARY);
/* Create synchronisation events */
char buf[MAX_PATH];
@@ -505,6 +505,8 @@ fhandler_tty_slave::open (int flags, mode_t)
shared_name (buf, OUTPUT_DONE_EVENT, get_unit ());
output_done_event = OpenEvent (MAXIMUM_ALLOWED, TRUE, buf);
+ const char *errmsg = NULL;
+
if (!(output_mutex = get_ttyp ()->open_output_mutex (MAXIMUM_ALLOWED)))
{
errmsg = "open output mutex failed, %E";
@@ -646,19 +648,6 @@ fhandler_tty_slave::open (int flags, mode_t)
if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1
&& !output_done_event)
fhandler_console::need_invisible ();
-
- // FIXME: Do this better someday
- arch = (fhandler_tty_slave *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
- *((fhandler_tty_slave **) cygheap->fdtab.add_archetype ()) = arch;
- archetype = arch;
- *arch = *this;
-
-out:
- usecount = 0;
- arch->usecount++;
- report_tty_counts (this, "opened", "");
- myself->set_ctty (get_ttyp (), flags, arch);
-
return 1;
err:
@@ -672,8 +661,17 @@ err_no_msg:
return 0;
}
-int
-fhandler_tty_slave::close ()
+void
+fhandler_tty_slave::open_setup (int flags)
+{
+ set_flags ((flags & ~O_TEXT) | O_BINARY);
+ myself->set_ctty (get_ttyp (), flags, this);
+ cygheap->manage_console_count ("fhandler_tty_slave::setup", 1);
+ report_tty_counts (this, "opened", "");
+}
+
+void
+fhandler_tty_slave::cleanup ()
{
/* This used to always call fhandler_tty_common::close when hExeced but that
caused multiple closes of the handles associated with this tty. Since
@@ -681,20 +679,12 @@ fhandler_tty_slave::close ()
or before a non-cygwin process has exited, it should be safe to just
close this normally. cgf 2006-05-20 */
cygheap->manage_console_count ("fhandler_tty_slave::close", -1);
-
- archetype->usecount--;
report_tty_counts (this, "closed", "");
+}
- if (archetype->usecount)
- {
-#ifdef DEBUGGING
- if (archetype->usecount < 0)
- system_printf ("error: usecount %d", archetype->usecount);
-#endif
- termios_printf ("just returning because archetype usecount is != 0");
- return 0;
- }
-
+int
+fhandler_tty_slave::close ()
+{
termios_printf ("closing last open %s handle", ttyname ());
if (inuse && !CloseHandle (inuse))
termios_printf ("CloseHandle (inuse), %E");
@@ -702,7 +692,7 @@ fhandler_tty_slave::close ()
}
int
-fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
+fhandler_tty_slave::init (HANDLE h, DWORD a, mode_t)
{
int flags = 0;
@@ -714,7 +704,7 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
if (a == (GENERIC_READ | GENERIC_WRITE))
flags = O_RDWR;
- int ret = open (flags);
+ int ret = open_with_arch (flags);
if (ret && !cygwin_finished_initializing && !being_debugged ())
{
@@ -735,8 +725,8 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
}
}
- if (f != INVALID_HANDLE_VALUE)
- CloseHandle (f); /* Reopened by open */
+ if (h != INVALID_HANDLE_VALUE)
+ CloseHandle (h); /* Reopened by open */
return ret;
}
@@ -1037,38 +1027,14 @@ out:
int
fhandler_tty_slave::dup (fhandler_base *child)
{
- fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype;
- /* In dtable::dup_worker, the path_conv member has already been assigned
- from "this" to "child". Part of this assigment (path_conv::operator=)
- is to allocate memory for the strings "path" and "normalized_path from
- cygheap. The below `child = *arch' statement will overwrite child's
- path_conv again, this time from "*arch". By doing that, it will allocate
- new strings from cygheap, overwriting the old pointer values. Thus, the
- old allocated strings are lost, and we're leaking memory for each tty dup,
- unless we free the strings here.
- FIXME: We can't redefine path_conv::operator= so that it frees the old
- strings. Probably it would be most helpful to copy only the required
- members from *arch, rather than copying everything. */
- child->pc.free_strings ();
- *(fhandler_tty_slave *) child = *arch;
- child->set_flags (get_flags ());
- child->usecount = 0;
- arch->usecount++;
cygheap->manage_console_count ("fhandler_tty_slave::dup", 1);
- report_tty_counts (child, "duped", "");
+ report_tty_counts (child, "duped slave", "");
return 0;
}
int
fhandler_pty_master::dup (fhandler_base *child)
{
- fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
- /* See comment in fhandler_tty_slave::dup. */
- child->pc.free_strings ();
- *(fhandler_tty_master *) child = *arch;
- child->set_flags (get_flags ());
- child->usecount = 0;
- arch->usecount++;
report_tty_counts (child, "duped master", "");
return 0;
}
@@ -1435,15 +1401,8 @@ fhandler_pty_master::open (int flags, mode_t)
set_flags ((flags & ~O_TEXT) | O_BINARY);
set_open_status ();
- /* FIXME: Do this better someday */
- fhandler_pty_master *arch = (fhandler_tty_master *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
- *((fhandler_pty_master **) cygheap->fdtab.add_archetype ()) = arch;
- archetype = arch;
- *arch = *this;
- arch->dwProcessId = GetCurrentProcessId ();
+ dwProcessId = GetCurrentProcessId ();
- usecount = 0;
- arch->usecount++;
char buf[sizeof ("opened pty master for ttyNNNNNNNNNNN")];
__small_sprintf (buf, "opened pty master for tty%d", get_unit ());
report_tty_counts (this, buf, "");
@@ -1482,6 +1441,12 @@ fhandler_tty_common::close ()
return 0;
}
+void
+fhandler_pty_master::cleanup ()
+{
+ report_tty_counts (this, "closing master", "");
+}
+
int
fhandler_pty_master::close ()
{
@@ -1489,25 +1454,12 @@ fhandler_pty_master::close ()
while (accept_input () > 0)
continue;
#endif
- archetype->usecount--;
- report_tty_counts (this, "closing master", "");
- if (archetype->usecount)
- {
-#ifdef DEBUGGING
- if (archetype->usecount < 0)
- system_printf ("error: usecount %d", archetype->usecount);
-#endif
- termios_printf ("just returning because archetype usecount is != 0");
- return 0;
- }
-
- fhandler_tty_master *arch = (fhandler_tty_master *) archetype;
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
- arch->from_master, arch->to_master, arch->dwProcessId);
+ from_master, to_master, dwProcessId);
if (cygwin_finished_initializing)
{
- if (arch->master_ctl && get_ttyp ()->master_pid == myself->pid)
+ if (master_ctl && get_ttyp ()->master_pid == myself->pid)
{
char buf[MAX_PATH];
pipe_request req = { (DWORD) -1 };
@@ -1517,13 +1469,13 @@ fhandler_pty_master::close ()
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-tty%d-master-ctl",
&installation_key, get_unit ());
CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, &len, 500);
- CloseHandle (arch->master_ctl);
- arch->master_thread->detach ();
+ CloseHandle (master_ctl);
+ master_thread->detach ();
}
- 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);
+ 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);
}
fhandler_tty_common::close ();
@@ -1674,7 +1626,7 @@ fhandler_tty_slave::fixup_after_exec ()
int
fhandler_tty_master::init_console ()
{
- console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym");
+ console = (fhandler_console *) build_fh_dev (*console_dev, "/dev/ttym_console");
if (console == NULL)
return -1;
@@ -1824,10 +1776,10 @@ reply:
}
static DWORD WINAPI
-pty_master_thread (VOID *arg)
-{
+pty_master_thread (VOID *arg)
+{
return ((fhandler_pty_master *) arg)->pty_master_thread ();
-}
+}
bool
fhandler_pty_master::setup (bool ispty)