diff options
author | Christopher Faylor <me@cgf.cx> | 2011-10-30 04:50:36 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2011-10-30 04:50:36 +0000 |
commit | cd071d1363477d594a8c9ae9f2ca5e1357c8fe3d (patch) | |
tree | 131f42f55aa3ada545ab88f0e255b5342bdee181 /winsup/cygwin/pipe.cc | |
parent | 673a6913728d964c470470ca704d17ac74f07603 (diff) | |
download | newlib-cd071d1363477d594a8c9ae9f2ca5e1357c8fe3d.zip newlib-cd071d1363477d594a8c9ae9f2ca5e1357c8fe3d.tar.gz newlib-cd071d1363477d594a8c9ae9f2ca5e1357c8fe3d.tar.bz2 |
* fhandler.h (fhandler_pipe::create_selectable): Remove optional argument, take
an options argument for CreateNamedPipe/CreateFile. Change handle arguments to
expect pointers.
(fhandler_fifo::fifo_state): Delete.
(fhandler_fifo::dummy_client): Ditto.
(fhandler_fifo::open_nonserver): Ditto.
(fhandler_fifo::wait_state): Ditto.
(fhandler_fifo::raw_write): Ditto.
(fhandler_fifo::read_ready): New field.
(fhandler_fifo::write_ready): Ditto.
(fhandler_fifo::wait): Modify argument.
(fhandler_fifo::fifo_name): Add a new argument.
(fhandler_fifo::fixup_after_fork): New function.
* fhandler_fifo.cc (fhandler_fifo::fhandler_fifo): Remove initialization of
expunged elements. Initialize new handles to NULL.
(fhandler_fifo::open_nonserver): Delete.
(fnevent): New macro for creating a named event.
(fnpipe): New macro for creating a unique named pipe name.
(create_pipe): New macro for simplification of named pipe creation.
(fhandler_fifo::fifo_name): Use new argument when creating a shared name.
(fhandler_fifo::open): Rewrite. Use events to synchronize.
(pure_debug_printf): New macro, active only when DEBUGGING.
(fhandler_fifo::wait): Rewrite to wait for new fifo events which are supplied
as a parameter.
(fhandler_fifo::raw_read): Rewrite to use handle mechanism to detect
client-side disconnect.
(fhandler_fifo::raw_write): Delete.
(fhandler_fifo::close): Remove accommodations for expunged fields. Close event
handles.
(fhandler_fifo::dup): Remove accommodations for expunged fields. Duplicate
event handles.
(fhandler_fifo::fixup_after_fork): New function. Perform fixups on event
handles.
(fhandler_fifo::set_close_on_exec): Remove accommodations for expunged fields.
Set inheritance for new handle fields.
* miscfuncs.cc (CreatePipeOverlapped): Accommodate changes in
fhandler_pipe::create_selectable.
* tty.cc (tty::not_allocated): Ditto.
* pipe.cc (fhandler_pipe::create): Ditto.
(fhandler_pipe::create_selectable): Accept an extra open_mode argument. Pass
arguments by reference and allow opening one end of the pipe at a time.
* sys/strace.h (debug_only_printf): Define new macro which calls debug_printf
only when DEBUGGING is defined.
Diffstat (limited to 'winsup/cygwin/pipe.cc')
-rw-r--r-- | winsup/cygwin/pipe.cc | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 99c7912..7bbe96f 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -197,11 +197,14 @@ fhandler_pipe::dup (fhandler_base *child, int flags) Note that the return value is either 0 or GetLastError, unlike CreatePipe, which returns a bool for success or failure. */ int -fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r, - HANDLE& w, DWORD psize, const char *name) +fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE *r, + HANDLE *w, DWORD psize, const char *name, DWORD open_mode) { /* Default to error. */ - r = w = INVALID_HANDLE_VALUE; + if (r) + *r = NULL; + if (w) + *w = NULL; /* Ensure that there is enough pipe buffer space for atomic writes. */ if (psize < DEFAULT_PIPEBUFSIZE) @@ -210,26 +213,24 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r, char pipename[MAX_PATH]; const size_t len = __small_sprintf (pipename, PIPE_INTRO "%S-", &installation_key); + if (name) + strcpy (pipename + len, name); - /* FIXME: Eventually make ttys work with overlapped I/O. */ - DWORD overlapped = name ? 0 : FILE_FLAG_OVERLAPPED; + open_mode |= PIPE_ACCESS_INBOUND; /* Retry CreateNamedPipe as long as the pipe name is in use. Retrying will probably never be necessary, but we want to be as robust as possible. */ - DWORD err; - do + DWORD err = 0; + while (r && !*r) { static volatile ULONG pipe_unique_id; if (!name) __small_sprintf (pipename + len, "pipe-%p-%p", myself->pid, InterlockedIncrement ((LONG *) &pipe_unique_id)); - else - strcpy (pipename + len, name); debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize); - err = 0; /* Use CreateNamedPipe instead of CreatePipe, because the latter returns a write handle that does not permit FILE_READ_ATTRIBUTES access, on versions of win32 earlier than WinXP SP2. @@ -245,13 +246,14 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r, definitely required for pty handling since fhandler_pty_master writes to the pipe in chunks, terminated by newline when CANON mode is specified. */ - r = CreateNamedPipe (pipename, PIPE_ACCESS_INBOUND | overlapped, + *r = CreateNamedPipe (pipename, open_mode, PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE, 1, psize, psize, NMPWAIT_USE_DEFAULT_WAIT, sa_ptr); - if (r != INVALID_HANDLE_VALUE) + if (*r != INVALID_HANDLE_VALUE) { - debug_printf ("pipe read handle %p", r); + debug_printf ("pipe read handle %p", *r); + err = 0; break; } @@ -261,43 +263,58 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r, case ERROR_PIPE_BUSY: /* The pipe is already open with compatible parameters. Pick a new name and retry. */ - debug_printf ("pipe busy", name ? ", retrying" : ""); + debug_printf ("pipe busy", !name ? ", retrying" : ""); + if (!*name) + *r = NULL; break; case ERROR_ACCESS_DENIED: /* The pipe is already open with incompatible parameters. Pick a new name and retry. */ - debug_printf ("pipe access denied%s", name ? ", retrying" : ""); + debug_printf ("pipe access denied%s", !name ? ", retrying" : ""); + if (!*name) + *r = NULL; break; default: { err = GetLastError (); - debug_printf ("CreatePipe failed, %E"); - return err; + debug_printf ("failed, %E"); } } } - while (!name); if (err) - return err; - - debug_printf ("CreateFile: name %s", pipename); - - /* Open the named pipe for writing. - Be sure to permit FILE_READ_ATTRIBUTES access. */ - w = CreateFile (pipename, GENERIC_WRITE | FILE_READ_ATTRIBUTES, 0, sa_ptr, - OPEN_EXISTING, overlapped, 0); - - if (!w || w == INVALID_HANDLE_VALUE) { - /* Failure. */ - DWORD err = GetLastError (); - debug_printf ("CreateFile failed, %E"); - CloseHandle (r); + *r = NULL; return err; } - debug_printf ("pipe write handle %p", w); + if (!w) + debug_printf ("pipe write handle NULL"); + else + { + debug_printf ("CreateFile: name %s", pipename); + + /* Open the named pipe for writing. + Be sure to permit FILE_READ_ATTRIBUTES access. */ + DWORD access = GENERIC_WRITE | FILE_READ_ATTRIBUTES; + if ((open_mode & PIPE_ACCESS_DUPLEX) == PIPE_ACCESS_DUPLEX) + access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; + *w = CreateFile (pipename, access, 0, sa_ptr, OPEN_EXISTING, + open_mode & FILE_FLAG_OVERLAPPED, 0); + + if (!*w || *w == INVALID_HANDLE_VALUE) + { + /* Failure. */ + DWORD err = GetLastError (); + debug_printf ("CreateFile failed, %E"); + if (r) + CloseHandle (*r); + *w = NULL; + return err; + } + + debug_printf ("pipe write handle %p", *w); + } /* Success. */ return 0; @@ -310,7 +327,7 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode) SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode); int res = -1; - int ret = create_selectable (sa, r, w, psize); + int ret = create_selectable (sa, &r, &w, psize, NULL, FILE_FLAG_OVERLAPPED); if (ret) __seterrno_from_win_error (ret); else if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL) |