* 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:
@@ -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)
|
||||
|
Reference in New Issue
Block a user