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-10-22 20:26:30 +0400
committerChristopher Faylor <me@cgf.cx>2011-10-22 20:26:30 +0400
commit6ae28c22639d43de76a9d45362df5055cd38a867 (patch)
tree1d68d36140425f822ed1ad4485051f25b9f71114 /winsup/cygwin/dtable.cc
parentbdea9e5fe8cb19d89015d8a6543ecab4b9e76a01 (diff)
* dtable.cc (dtable::delete_archetype): Improve debugging output.
(dtable::init_std_file_from_handle): Close console handle early, before initialization. Build up openflags for passing to open_setup, just to be safe. (last_tty_dev): New variable. (fh_last_tty_dev): New macro. (fh_alloc): Try again to keep track of previously opened tty, this time by just saving the device and using that to potentially open an archetype. Avoid setting the "/dev/tty" name if the creation of the fhandler failed. (build_fh_pc): Remove unused second argument. Reorganize how and where the name is set. Set last_tty_dev as appropriate. Avoid a NULL dereference in a debug printf. * dtable.h (build_fh_pc): Reflect removal of second parameter. * fhandler.cc (fhandler_base::reset): Use new '<<' operator to copy pc since it preserves any potentially previously set name. (fhandler_base::set_name): Ditto. * fhandler.h (fhandler_*::clone): Throughout use ccalloc to allocate new fhandler, primarily to make sure that pc field is properly zeroed. (fhandler_termios::last): Eliminate. (fhandler_termios): Remove setting of last. (fhandler_base::~fhandler_termios): Ditto. * fhandler_console.cc (fhandler_console::open): Don't make decisions about opening close-on-exec handles here since it makes no sense for archetypes. (fhandler_console::init): Assume that input handle has already been opened. * fhandler_termios.cc (fhandler_termios::last): Delete. * path.h (path_conv::eq_worker): New function. Move bulk of operator = here. (operator <<): New function. (operator =): Use eq_worker to perform old functionality.
Diffstat (limited to 'winsup/cygwin/dtable.cc')
-rw-r--r--winsup/cygwin/dtable.cc132
1 files changed, 74 insertions, 58 deletions
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 67e9d8ca8..982a671c2 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -217,7 +217,8 @@ dtable::delete_archetype (fhandler_base *fh)
for (unsigned i = 0; i < farchetype; i++)
if (fh == archetypes[i])
{
- debug_printf ("deleting element %d for %s", i, fh->get_name ());
+ debug_printf ("deleting element %d for %s(%d/%d)", i, fh->get_name (),
+ fh->dev ().get_major (), fh->dev ().get_minor ());
if (i < --farchetype)
archetypes[i] = archetypes[farchetype];
break;
@@ -314,7 +315,11 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
if (myself->ctty > 0)
dev.parse (myself->ctty);
else
- dev.parse (FH_CONSOLE);
+ {
+ dev.parse (FH_CONSOLE);
+ CloseHandle (handle);
+ handle = INVALID_HANDLE_VALUE;
+ }
}
else if (GetCommState (handle, &dcb))
/* FIXME: Not right - assumes ttyS0 */
@@ -347,48 +352,48 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
IO_STATUS_BLOCK io;
FILE_ACCESS_INFORMATION fai;
+ int openflags = O_BINARY;
/* Console windows are not kernel objects, so the access mask returned
by NtQueryInformationFile is meaningless. CMD always hands down
stdin handles as R/O handles, but our tty slave sides are R/W. */
- if (dev == FH_TTY || iscons_dev (dev) || dev.get_major () == DEV_PTYS_MAJOR)
- access |= GENERIC_READ | GENERIC_WRITE;
- else if (NT_SUCCESS (NtQueryInformationFile (handle, &io, &fai,
- sizeof fai,
- FileAccessInformation)))
+ if (!iscons_dev (dev) && fh->is_tty ())
+ {
+ openflags |= O_RDWR;
+ access |= GENERIC_READ | GENERIC_WRITE;
+ }
+ else if (!iscons_dev (dev)
+ && NT_SUCCESS (NtQueryInformationFile (handle, &io, &fai,
+ sizeof fai,
+ FileAccessInformation)))
{
- if (fai.AccessFlags & FILE_READ_DATA)
- access |= GENERIC_READ;
if (fai.AccessFlags & FILE_WRITE_DATA)
- access |= GENERIC_WRITE;
+ {
+ openflags |= O_WRONLY;
+ access |= GENERIC_WRITE;
+ }
+ if (fai.AccessFlags & FILE_READ_DATA)
+ {
+ openflags |= openflags & O_WRONLY ? O_RDWR : O_RDONLY;
+ access |= GENERIC_READ;
+ }
}
else if (fd == 0)
- access |= GENERIC_READ;
+ {
+ openflags |= O_RDONLY;
+ access |= GENERIC_READ;
+ }
else
- access |= GENERIC_WRITE; /* Should be rdwr for stderr but not sure that's
- possible for some versions of handles */
- /* FIXME: Workaround Windows 7 issue. If the parent process of
- the process tree closes the original handles to the console window,
- strange problems occur when starting child processes later on if
- stdio redirection is used.
-
- CV 2009-08-08: It looks like this problem has been fixed only
- half-heartedly in RTM. Unfortunately the new implementation
- has still a problem which now also occurs on the 32 bit release
- of Windows 7. It's still not quite clear what happens but it's
- easily reproducible. Just start X via the start menu entry.
- This opens an xterm window with a shell. Exit from the shell,
- and you get a Windows error box reporting a crash in the
- Console Window Host application (conhost.exe) due to an access
- violation.
-
- This needs further investigation but the workaround not to close
- the handles will have a marginal hit of three extra handles per
- process at most. */
- if (!fh->init (iscons_dev (dev) && wincap.has_console_handle_problem ()
- ? INVALID_HANDLE_VALUE : handle, access, bin))
+ {
+ openflags |= O_WRONLY;
+ access |= GENERIC_WRITE; /* Should be rdwr for stderr but not sure that's
+ possible for some versions of handles */
+ }
+ if (!fh->init (handle, access, bin))
api_fatal ("couldn't initialize fd %d for %s", fd, fh->get_name ());
+ fh->open_setup (openflags);
+ fh->usecount = 0;
cygheap->fdtab[fd] = fh;
set_std_handle (fd);
paranoid_printf ("fd %d, handle %p", fd, handle);
@@ -435,6 +440,8 @@ build_fh_dev (const device& dev, const char *unix_name)
}
#define fh_unset ((fhandler_base *) 1)
+static device last_tty_dev;
+#define fh_last_tty_dev ((fhandler_termios *) cygheap->fdtab.find_archetype (last_tty_dev))
static fhandler_base *
fh_alloc (path_conv& pc)
@@ -555,17 +562,22 @@ fh_alloc (path_conv& pc)
break;
case FH_TTY:
if (!pc.isopen ())
- fhraw = cnew_no_ctor (fhandler_console, -1);
- else if (myself->ctty <= 0
- && !myself->set_ctty (fhandler_termios::last, 0))
- /* no tty assigned */;
- else
{
+ fhraw = cnew_no_ctor (fhandler_console, -1);
+ debug_printf ("not called from open for /dev/tty");
+ }
+ else if (myself->ctty <= 0 && last_tty_dev
+ && !myself->set_ctty (fh_last_tty_dev, 0))
+ debug_printf ("no /dev/tty assigned");
+ else if (myself->ctty > 0)
+ {
+ debug_printf ("determining /dev/tty assignment for ctty %p", myself->ctty);
if (iscons_dev (myself->ctty))
fh = cnew (fhandler_console, pc.dev);
else
fh = cnew (fhandler_pty_slave, myself->ctty);
- fh->set_name ("/dev/tty");
+ if (fh->dev () != FH_NADA)
+ fh->set_name ("/dev/tty");
}
break;
case FH_KMSG:
@@ -595,7 +607,7 @@ fh_alloc (path_conv& pc)
}
fhandler_base *
-build_fh_pc (path_conv& pc, bool set_name)
+build_fh_pc (path_conv& pc)
{
fhandler_base *fh = fh_alloc (pc);
@@ -604,35 +616,38 @@ build_fh_pc (path_conv& pc, bool set_name)
set_errno (ENXIO);
goto out;
}
- else if (fh->get_name ())
- /* already got one */;
- else if (fh->dev () != FH_NADA)
- fh->set_name (fh->dev ().name);
- else if (set_name)
- fh->set_name (pc);
if (!fh->use_archetype ())
- /* doesn't use archetypes */;
+ fh->set_name (pc);
else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ())))
- debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (),
- fh->archetype->get_io_handle ());
+ {
+ debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (),
+ fh->archetype->get_io_handle ());
+ if (!fh->get_name ())
+ fh->set_name (fh->archetype->dev ().name);
+ }
+ else if (cygwin_finished_initializing && !pc.isopen ())
+ fh->set_name (pc);
else
{
+ if (!fh->get_name ())
+ fh->set_name (fh->dev ().name);
fh->archetype = fh->clone ();
debug_printf ("created an archetype (%p) for %s(%d/%d)", fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
fh->archetype->archetype = NULL;
*cygheap->fdtab.add_archetype () = fh->archetype;
}
- /* The fhandler_termios constructor keeps track of the last tty-like thing
- opened but we're only interested in this if we don't have a controlling
- terminal since we could potentially want to open it if /dev/tty is
- referenced. */
+
+ /* Keep track of the last tty-like thing opened. We could potentially want
+ to open it if /dev/tty is referenced. */
if (myself->ctty > 0 || !fh->is_tty () || !pc.isctty_capable ())
- fhandler_termios::last = NULL;
+ last_tty_dev = FH_NADA;
+ else
+ last_tty_dev = fh->dev ();
out:
- debug_printf ("fh %p, dev %p", fh, (DWORD) fh->dev ());
+ debug_printf ("fh %p, dev %p", fh, fh ? (DWORD) fh->dev () : 0);
return fh;
}
@@ -668,9 +683,10 @@ dtable::dup_worker (fhandler_base *oldfh, int flags)
debug_printf ("duped output_handles old %p, new %p",
oldfh->get_output_handle (),
newfh->get_output_handle ());
- debug_printf ("duped output_handles archetype old %p, archetype new %p",
- oldfh->archetype->get_output_handle (),
- newfh->archetype->get_output_handle ());
+ if (oldfh->archetype)
+ debug_printf ("duped output_handles archetype old %p, archetype new %p",
+ oldfh->archetype->get_output_handle (),
+ newfh->archetype->get_output_handle ());
#endif /*DEBUGGING*/
}
}