From 434bbf7ddc2bffdfddf740cee88d530d5d02a778 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 21 Feb 2008 17:37:31 +0000 Subject: * dtable.cc (dtable::init_std_file_from_handle): Try harder to make a pipe into a full-cygwin device. (handle_to_fn): Change \ to / when necessary. * fhandler.cc (fhandler_base::init): Change bin to mode. * fhandler.h (fhandler_pipe::init): Declare. * pipe.cc (fhandler_pipe::init): Define. (handler_pipe::open): Move initialization code into init. --- winsup/cygwin/ChangeLog | 10 ++++++ winsup/cygwin/dtable.cc | 88 ++++++++++++++++++++++++++++++++--------------- winsup/cygwin/fhandler.cc | 6 ++-- winsup/cygwin/fhandler.h | 3 +- winsup/cygwin/pipe.cc | 57 +++++++++++++++++++----------- 5 files changed, 112 insertions(+), 52 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f730398db63..23268473026 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2008-02-21 Christopher Faylor + + * dtable.cc (dtable::init_std_file_from_handle): Try harder to make a + pipe into a full-cygwin device. + (handle_to_fn): Change \ to / when necessary. + * fhandler.cc (fhandler_base::init): Change bin to mode. + * fhandler.h (fhandler_pipe::init): Declare. + * pipe.cc (fhandler_pipe::init): Define. + (handler_pipe::open): Move initialization code into init. + 2008-02-19 Christopher Faylor * sigproc.cc (sig_send): Use sigmask of target thread if it is diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 4523c17a46e..08180eb448e 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -1,7 +1,7 @@ /* dtable.cc: file descriptor support. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006 Red Hat, Inc. + 2005, 2006, 2007, 2008 Red Hat, Inc. This file is part of Cygwin. @@ -41,6 +41,17 @@ static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, static const char *handle_to_fn (HANDLE, char *); +#define DEVICE_PREFIX "\\device\\" +#define DEVICE_PREFIX_LEN sizeof (DEVICE_PREFIX) - 1 +#define REMOTE "\\Device\\LanmanRedirector\\" +#define REMOTE_LEN sizeof (REMOTE) - 1 +#define REMOTE1 "\\Device\\WinDfs\\Root\\" +#define REMOTE1_LEN sizeof (REMOTE1) - 1 +#define NAMED_PIPE "\\Device\\NamedPipe\\" +#define NAMED_PIPE_LEN sizeof (NAMED_PIPE) - 1 +#define POSIX_NAMED_PIPE "/Device/NamedPipe/" +#define POSIX_NAMED_PIPE_LEN sizeof (POSIX_NAMED_PIPE) - 1 + /* Set aside space for the table of fds */ void dtable_init () @@ -283,13 +294,6 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle) else dev = *console_dev; } - else if (ft == FILE_TYPE_PIPE) - { - if (fd == 0) - dev = *piper_dev; - else - dev = *pipew_dev; - } else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal) == 0) dev = *tcp_dev; else if (GetCommState (handle, &dcb)) @@ -297,7 +301,12 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle) else { name = handle_to_fn (handle, (char *) alloca (CYG_MAX_PATH + 100)); - bin = 0; + if (!strncasematch (name, POSIX_NAMED_PIPE, POSIX_NAMED_PIPE_LEN)) + /* nothing */; + else if (fd == 0) + dev = *piper_dev; + else + dev = *pipew_dev; } } @@ -308,25 +317,31 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle) fhandler_base *fh; if (dev) - fh = build_fh_dev (dev); + fh = build_fh_dev (dev, name); else fh = build_fh_name (name); if (fh) cygheap->fdtab[fd] = fh; - if (!bin) + if (name) { - bin = fh->get_default_fmode (O_RDWR); - if (bin) - /* nothing */; - else if (dev) - bin = O_BINARY; - else if (name != unknown_file) - bin = fh->pc_binmode (); + bin = fh->pc_binmode (); + if (!bin) + { + bin = fh->get_default_fmode (O_RDWR); + if (!bin && dev) + bin = O_BINARY; + } } - fh->init (handle, GENERIC_READ | GENERIC_WRITE, bin); + DWORD access; + if (fd == 0) + access = GENERIC_READ; + else + access = GENERIC_WRITE; /* Should be rdwr for stderr but not sure that's + possible for some versions of handles */ + fh->init (handle, access, bin); set_std_handle (fd); paranoid_printf ("fd %d, handle %p", fd, handle); } @@ -833,11 +848,6 @@ dtable::vfork_child_fixup () } #endif /*NEWVFORK*/ -#define DEVICE_PREFIX "\\device\\" -#define DEVICE_PREFIX_LEN sizeof (DEVICE_PREFIX) - 1 -#define REMOTE "\\Device\\LanmanRedirector\\" -#define REMOTE_LEN sizeof (REMOTE) - 1 - static const char * handle_to_fn (HANDLE h, char *posix_fn) { @@ -852,7 +862,7 @@ handle_to_fn (HANDLE h, char *posix_fn) NTSTATUS res = NtQueryObject (h, ObjectNameInformation, ntfn, sizeof (fnbuf), NULL); - if (NT_SUCCESS (res)) + if (!NT_SUCCESS (res)) { strcpy (posix_fn, unknown_file); debug_printf ("NtQueryObject failed"); @@ -909,6 +919,7 @@ handle_to_fn (HANDLE h, char *posix_fn) } char *w32 = win32_fn; + bool justslash = false; if (maxmatchlen) { n = strlen (maxmatchdos); @@ -918,15 +929,38 @@ handle_to_fn (HANDLE h, char *posix_fn) memcpy (w32, maxmatchdos, n); w32[n] = '\\'; } + else if (strncasematch (w32, NAMED_PIPE, NAMED_PIPE_LEN)) + { + debug_printf ("pipe"); + justslash = true; + } else if (strncasematch (w32, REMOTE, REMOTE_LEN)) { w32 += REMOTE_LEN - 2; *w32 = '\\'; debug_printf ("remote drive"); + justslash = true; + } + else if (strncasematch (w32, REMOTE1, REMOTE1_LEN)) + { + w32 += REMOTE1_LEN - 2; + *w32 = '\\'; + debug_printf ("remote drive"); + justslash = true; } + if (!justslash) + cygwin_conv_to_full_posix_path (w32, posix_fn); + else + { + char *s, *d; + for (s = w32, d = posix_fn; *s; s++, d++) + if (*s == '\\') + *d = '/'; + else + *d = *s; + } - debug_printf ("derived path '%s'", w32); - cygwin_conv_to_full_posix_path (w32, posix_fn); + debug_printf ("derived path '%s', posix '%s'", w32, posix_fn); return posix_fn; } diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 505c8db9ec4..bb54fe99acb 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1,7 +1,7 @@ /* fhandler.cc. See console.cc for fhandler_console functions. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Red Hat, Inc. + 2005, 2006, 2007, 2008 Red Hat, Inc. This file is part of Cygwin. @@ -1279,7 +1279,7 @@ fhandler_base::fstat (struct __stat64 *buf) } void -fhandler_base::init (HANDLE f, DWORD a, mode_t bin) +fhandler_base::init (HANDLE f, DWORD a, mode_t mode) { set_io_handle (f); access = a; @@ -1291,7 +1291,7 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin) flags = O_WRONLY; else if (a == (GENERIC_READ | GENERIC_WRITE)) flags = O_RDWR; - set_flags (flags | bin); + set_flags (flags | mode); set_open_status (); debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ()); } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index afdaf0bca01..e1381e0ea62 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1,7 +1,7 @@ /* fhandler.h Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Red Hat, Inc. + 2005, 2006, 2007, 2008 Red Hat, Inc. This file is part of Cygwin. @@ -518,6 +518,7 @@ public: char *get_proc_fd_name (char *buf); void set_close_on_exec (bool val); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); + void init (HANDLE, DWORD, mode_t); int open (int flags, mode_t mode = 0); int close (); void create_guard (SECURITY_ATTRIBUTES *sa) diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 4b98028990c..c4cdec00fb1 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -1,7 +1,7 @@ /* pipe.cc: pipe for Cygwin. - Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Hat, Inc. + Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 + Red Hat, Inc. This file is part of Cygwin. @@ -39,6 +39,39 @@ fhandler_pipe::fhandler_pipe () extern "C" int sscanf (const char *, const char *, ...); +void +fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode) +{ + bool isread = !!(a & GENERIC_READ); + SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ? &sec_none_nih : &sec_none; + if (mode & O_NOINHERIT) + close_on_exec (true); + + if (isread) + { + create_read_state (2); + create_guard (sa); + } + + if (!wincap.has_unreliable_pipes ()) + /* nothing to do */; + else if (isread) + { + orig_pid = myself->pid; + id = ++pipecount; + } + else /* NOTE: This assumes that pipecount has been incremented by a previous + init of the read end of the pipe. That isn't really true of native + pipes but, ask me if I care. */ + { + char buf[80]; + __small_sprintf (buf, pipeid_fmt, myself->pid, pipecount); + writepipe_exists = CreateEvent (sa, TRUE, FALSE, buf); + } + + fhandler_base::init (f, a, mode); +} + int fhandler_pipe::open (int flags, mode_t mode) { @@ -446,28 +479,10 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fif fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev); fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev); - int binmode = mode & O_TEXT ?: O_BINARY; + mode |= mode & O_TEXT ?: O_BINARY; fhs[0]->init (r, GENERIC_READ, binmode); fhs[1]->init (w, GENERIC_WRITE, binmode); - if (mode & O_NOINHERIT) - { - fhs[0]->close_on_exec (true); - fhs[1]->close_on_exec (true); - } - - fhs[0]->create_read_state (2); - res = 0; - fhs[0]->create_guard (sa); - if (wincap.has_unreliable_pipes ()) - { - char buf[80]; - int count = pipecount++; /* FIXME: Should this be InterlockedIncrement? */ - __small_sprintf (buf, pipeid_fmt, myself->pid, count); - fhs[1]->writepipe_exists = CreateEvent (sa, TRUE, FALSE, buf); - fhs[0]->orig_pid = myself->pid; - fhs[0]->id = count; - } } syscall_printf ("%d = pipe ([%p, %p], %d, %p)", res, fhs[0], fhs[1], psize, mode); -- cgit v1.2.1