* 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().
This commit is contained in:
Christopher Faylor
2011-05-05 22:30:53 +00:00
parent d8ff96389f
commit 92ddb74290
14 changed files with 408 additions and 406 deletions

View File

@@ -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)