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>2007-07-07 21:00:33 +0400
committerChristopher Faylor <me@cgf.cx>2007-07-07 21:00:33 +0400
commitd9c0e3ec35b3a087ea68f528967765c2ee6a0dca (patch)
treedfbb5b49470a1683e12a1579005f99d66feb588a /winsup/cygwin/pipe.cc
parentdee55888399728d1b4652e1a369e0f62a77c1111 (diff)
Preliminary change to make fifos/pipes interruptible and fifos reliable.
* dtable.cc (dtable::find_fifo): Eliminate definition. * dtable.h (dtable::find_fifo): Ditto for declaration. * fhandler.cc (fhandler_base::raw_read): Remove pipe-specific stuff. (fhandler_base::fhandler_base): Ditto. (fhandler_base::close): Handle overlapped I/O structure if appropriate. (fhandler_base::dup): Ditto. (fhandler_base::fork_fixup): Ditto. (fhandler_base::setup_overlapped): Define new function. (fhandler_base::destroy_overlapped): Ditto. (fhandler_base::wait_overlapped): Ditto. (fhandler_base::read_overlapped): Ditto. (fhandler_base::write_overlapped): Ditto. * fhandler.h (fhandler_base::get_overlapped): Declare new function. (fhandler_base::setup_overlapped): Ditto. (fhandler_base::destroy_overlapped): Ditto. (fhandler_base::wait_overlapped): Ditto. (fhandler_base::read_overlapped): Ditto. (fhandler_base::write_overlapped): Ditto. (fhandler_base::get_guard): Eliminate. (fhandler_pipe::*): Rework to eliminate most Win9x related cruft, removing many variables and defining a new overlapped capability. (fhandler_fifo::*): Ditto. (fifo_state): Declare new enum. * fhandler_fifo.cc (fhandler_fifo::fhandler_fifo): Remove old Win9x stuff. Initialize overlapped handle to NULL. (fhandler_fifo::set_use): Eliminate. (fhandler_fifo::open_nonserver): Define. (fhandler_fifo::open): Rework to use named pipes and overlapped I/O. (fhandler_fifo::wait): Define new function to wait for named pipe connection. (fhandler_fifo::read): Rework to use wait() and new overlapped I/O functionality. (fhandler_fifo::write): Ditto. (fhandler_fifo::dup): Eliminate. * pinfo.cc (commune_process): Remove fifo handling. (_pinfo::commune_request): Ditto. * pinfo.h (picom): Ditto. * pipe.cc (fhandler_pipe::fhandler_pipe): Remove Win9x stuff. Initialize overlapped handle to NULL. (fhandler_pipe::open): Eliminate Win9x stuff. (fhandler_pipe::set_close_on_exec): Eliminate. (read_pipe): Eliminate. (fhandler_pipe::close): Ditto. (fhandler_pipe::fixup_after_exec): Ditto. (fhandler_pipe::fixup_in_child): Ditto. (fhandler_pipe::read): Rework to use overlapped I/O. (fhandler_pipe::write): New function using overlapped I/O. (fhandler_pipe::dup): Rework to eliminate Win9x stuff. (fhandler_pipe::create_selectable): Rework to eliminate Win9x and use overlapped I/O. * select.cc (peek_pipe): Rework to eliminate Win9x stuff and use overlapped I/O. (fhandler_base::ready_for_read): Ditto.
Diffstat (limited to 'winsup/cygwin/pipe.cc')
-rw-r--r--winsup/cygwin/pipe.cc157
1 files changed, 17 insertions, 140 deletions
diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc
index 59fb4c4d9..637defb16 100644
--- a/winsup/cygwin/pipe.cc
+++ b/winsup/cygwin/pipe.cc
@@ -28,8 +28,9 @@ details. */
#include "ntdll.h"
fhandler_pipe::fhandler_pipe ()
- : fhandler_base (), guard (NULL), broken_pipe (false), popen_pid (0)
+ : fhandler_base (), popen_pid (0)
{
+ get_overlapped ()->hEvent = NULL;
need_fork_fixup (true);
}
@@ -97,18 +98,6 @@ fhandler_pipe::open (int flags, mode_t mode)
__seterrno ();
goto out;
}
- if (!fh->guard)
- /* nothing to do */;
- else if (DuplicateHandle (proc, fh->guard, hMainProc, &guard,
- 0, inh, DUPLICATE_SAME_ACCESS))
- ProtectHandle (guard);
- else
- {
- __seterrno ();
- goto out;
- }
- if (fh->read_state)
- create_read_state (2);
init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY);
if (flags & O_NOINHERIT)
close_on_exec (true);
@@ -117,8 +106,6 @@ fhandler_pipe::open (int flags, mode_t mode)
CloseHandle (proc);
return 1;
out:
- if (guard)
- CloseHandle (guard);
if (nio_hdl)
CloseHandle (nio_hdl);
if (fh)
@@ -150,17 +137,6 @@ fhandler_pipe::ftruncate (_off64_t length, bool allow_truncate)
return -1;
}
-void
-fhandler_pipe::set_close_on_exec (bool val)
-{
- fhandler_base::set_close_on_exec (val);
- if (guard)
- {
- set_no_inheritance (guard, val);
- ModifyHandle (guard, !val);
- }
-}
-
char *
fhandler_pipe::get_proc_fd_name (char *buf)
{
@@ -168,120 +144,30 @@ fhandler_pipe::get_proc_fd_name (char *buf)
return buf;
}
-struct pipeargs
-{
- fhandler_base *fh;
- void *ptr;
- size_t *len;
-};
-
-static DWORD WINAPI
-read_pipe (void *arg)
-{
- pipeargs *pi = (pipeargs *) arg;
- pi->fh->fhandler_base::read (pi->ptr, *pi->len);
- return 0;
-}
-
void __stdcall
fhandler_pipe::read (void *in_ptr, size_t& in_len)
{
- if (broken_pipe)
- in_len = 0;
- else
- {
- pipeargs pi = {dynamic_cast<fhandler_base *>(this), in_ptr, &in_len};
- cygthread *th = new cygthread (read_pipe, 0, &pi, "read_pipe");
- if (th->detach (read_state) && !in_len)
- in_len = (size_t) -1; /* received a signal */
- }
- ReleaseMutex (guard);
+ return read_overlapped (in_ptr, in_len);
}
int
-fhandler_pipe::close ()
-{
- if (guard)
- ForceCloseHandle (guard);
-#ifndef NEWVFORK
- if (read_state)
-#else
- // FIXME is this vfork_cleanup test right? Is it responsible for some of
- // the strange pipe behavior that has been reported in the cygwin mailing
- // list?
- if (read_state && !cygheap->fdtab.in_vfork_cleanup ())
-#endif
- ForceCloseHandle (read_state);
- return fhandler_base::close ();
-}
-
-void
-fhandler_pipe::fixup_in_child ()
+fhandler_pipe::write (const void *ptr, size_t len)
{
- if (read_state)
- create_read_state (2);
-}
-
-void
-fhandler_pipe::fixup_after_exec ()
-{
- if (!close_on_exec ())
- fixup_in_child ();
-}
-
-void
-fhandler_pipe::fixup_after_fork (HANDLE parent)
-{
- fhandler_base::fixup_after_fork (parent);
- if (guard && fork_fixup (parent, guard, "guard"))
- ProtectHandle (guard);
- fixup_in_child ();
+ return write_overlapped (ptr, len);
}
int
fhandler_pipe::dup (fhandler_base *child)
{
- int res = -1;
fhandler_pipe *ftp = (fhandler_pipe *) child;
ftp->set_popen_pid (0);
- ftp->guard = ftp->read_state = NULL;
+ int res;
if (get_handle () && fhandler_base::dup (child))
- goto err;
-
- if (!guard)
- /* nothing to do */;
- else if (DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, true,
- DUPLICATE_SAME_ACCESS))
- ProtectHandle1 (ftp->guard, guard);
+ res = -1;
else
- {
- debug_printf ("couldn't duplicate guard %p, %E", guard);
- goto err;
- }
+ res = 0;
- if (!read_state)
- /* nothing to do */;
- else if (DuplicateHandle (hMainProc, read_state, hMainProc,
- &ftp->read_state, 0, false,
- DUPLICATE_SAME_ACCESS))
- ProtectHandle1 (ftp->read_state, read_state);
- else
- {
- debug_printf ("couldn't duplicate read_state %p, %E", read_state);
- goto err;
- }
-
- res = 0;
- goto out;
-
-err:
- if (ftp->guard)
- ForceCloseHandle1 (ftp->guard, guard);
- if (ftp->read_state)
- ForceCloseHandle1 (ftp->read_state, read_state);
-
-out:
debug_printf ("res %d", res);
return res;
}
@@ -327,7 +213,7 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r,
the pipe was not created earlier by some other process, even if
the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
because that is only available for Win2k SP2 and WinXP. */
- r = CreateNamedPipe (pipename, PIPE_ACCESS_INBOUND,
+ r = CreateNamedPipe (pipename, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, psize,
psize, NMPWAIT_USE_DEFAULT_WAIT, sa_ptr);
@@ -352,19 +238,11 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r,
debug_printf ("pipe access denied, retrying");
break;
default:
- /* CreateNamePipe failed. Maybe we are on an older Win9x platform without
- named pipes. Return an anonymous pipe as the best approximation. */
- debug_printf ("CreateNamedPipe failed, resorting to CreatePipe size %lu",
- psize);
- if (CreatePipe (&r, &w, sa_ptr, psize))
- {
- debug_printf ("pipe read handle %p", r);
- debug_printf ("pipe write handle %p", w);
- return 0;
- }
- err = GetLastError ();
- debug_printf ("CreatePipe failed, %E");
- return err;
+ {
+ err = GetLastError ();
+ debug_printf ("CreatePipe failed, %E");
+ return err;
+ }
}
}
@@ -373,7 +251,7 @@ fhandler_pipe::create_selectable (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE& r,
/* 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, 0, 0);
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (!w || w == INVALID_HANDLE_VALUE)
{
@@ -414,10 +292,9 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fif
fhs[1]->close_on_exec (true);
}
- fhs[0]->create_read_state (2);
-
+ fhs[0]->setup_overlapped ();
+ fhs[1]->setup_overlapped ();
res = 0;
- fhs[0]->create_guard (sa);
}
syscall_printf ("%d = pipe ([%p, %p], %d, %p)", res, fhs[0], fhs[1], psize, mode);