summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_fifo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_fifo.cc')
-rw-r--r--winsup/cygwin/fhandler_fifo.cc375
1 files changed, 0 insertions, 375 deletions
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
deleted file mode 100644
index 8a021bd62..000000000
--- a/winsup/cygwin/fhandler_fifo.cc
+++ /dev/null
@@ -1,375 +0,0 @@
-/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
-
- Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Red Hat, Inc.
-
- This file is part of Cygwin.
-
- This software is a copyrighted work licensed under the terms of the
- Cygwin license. Please consult the file "CYGWIN_LICENSE" for
- details. */
-
-#include "winsup.h"
-#include "miscfuncs.h"
-
-#include "cygerrno.h"
-#include "security.h"
-#include "path.h"
-#include "fhandler.h"
-#include "dtable.h"
-#include "cygheap.h"
-#include "sigproc.h"
-#include "cygtls.h"
-#include "shared_info.h"
-#include "ntdll.h"
-#include "cygwait.h"
-
-fhandler_fifo::fhandler_fifo ():
- fhandler_base_overlapped (),
- read_ready (NULL), write_ready (NULL)
-{
- max_atomic_write = DEFAULT_PIPEBUFSIZE;
- need_fork_fixup (true);
-}
-
-#define fnevent(w) fifo_name (npbuf, w "-event")
-#define fnpipe() fifo_name (npbuf, "fifo")
-#define create_pipe(r, w) \
- fhandler_pipe::create (sa_buf, (r), (w), 0, fnpipe (), open_mode)
-
-char *
-fhandler_fifo::fifo_name (char *buf, const char *what)
-{
- /* Generate a semi-unique name to associate with this fifo. */
- __small_sprintf (buf, "%s.%08x.%016X", what, get_dev (),
- get_ino ());
- return buf;
-}
-
-inline PSECURITY_ATTRIBUTES
-sec_user_cloexec (bool cloexec, PSECURITY_ATTRIBUTES sa, PSID sid)
-{
- return cloexec ? sec_user_nih (sa, sid) : sec_user (sa, sid);
-}
-
-bool inline
-fhandler_fifo::arm (HANDLE h)
-{
-#ifdef DEBUGGING
- const char *what;
- if (h == read_ready)
- what = "reader";
- else if (h == write_ready)
- what = "writer";
- else
- what = "overlapped event";
- debug_only_printf ("arming %s", what);
-#endif
-
- bool res = SetEvent (h);
- if (!res)
-#ifdef DEBUGGING
- debug_printf ("SetEvent for %s failed, %E", what);
-#else
- debug_printf ("SetEvent failed, %E");
-#endif
- return res;
-}
-
-int
-fhandler_fifo::open (int flags, mode_t)
-{
- enum
- {
- success,
- error_errno_set,
- error_set_errno
- } res;
- bool reader, writer, duplexer;
- DWORD open_mode = FILE_FLAG_OVERLAPPED;
-
- /* Determine what we're doing with this fhandler: reading, writing, both */
- switch (flags & O_ACCMODE)
- {
- case O_RDONLY:
- reader = true;
- writer = false;
- duplexer = false;
- break;
- case O_WRONLY:
- writer = true;
- reader = false;
- duplexer = false;
- break;
- case O_RDWR:
- open_mode |= PIPE_ACCESS_DUPLEX;
- reader = true;
- writer = false;
- duplexer = true;
- break;
- default:
- set_errno (EINVAL);
- res = error_errno_set;
- goto out;
- }
-
- debug_only_printf ("reader %d, writer %d, duplexer %d", reader, writer, duplexer);
- set_flags (flags);
- char char_sa_buf[1024];
- LPSECURITY_ATTRIBUTES sa_buf;
- sa_buf = sec_user_cloexec (flags & O_CLOEXEC, (PSECURITY_ATTRIBUTES) char_sa_buf,
- cygheap->user.sid());
- char npbuf[MAX_PATH];
-
- /* Create control events for this named pipe */
- if (!(read_ready = CreateEvent (sa_buf, duplexer, false, fnevent ("r"))))
- {
- debug_printf ("CreatEvent for %s failed, %E", npbuf);
- res = error_set_errno;
- goto out;
- }
- if (!(write_ready = CreateEvent (sa_buf, false, false, fnevent ("w"))))
- {
- debug_printf ("CreatEvent for %s failed, %E", npbuf);
- res = error_set_errno;
- goto out;
- }
-
- /* If we're reading, create the pipe, signal that we're ready and wait for
- a writer.
- FIXME: Probably need to special case O_RDWR case. */
- if (!reader)
- /* We are not a reader */;
- else if (create_pipe (&get_io_handle (), NULL))
- {
- debug_printf ("create of reader failed");
- res = error_set_errno;
- goto out;
- }
- else if (!arm (read_ready))
- {
- res = error_set_errno;
- goto out;
- }
- else if (!duplexer && !wait (write_ready))
- {
- res = error_errno_set;
- goto out;
- }
-
- /* If we're writing, it's a little tricky since it is possible that
- we're attempting to open the other end of a pipe which is already
- connected. In that case, we detect ERROR_PIPE_BUSY, reset the
- read_ready event and wait for the reader to allow us to connect
- by signalling read_ready.
-
- Once the pipe has been set up, we signal write_ready. */
- if (writer)
- {
- int err;
- while (1)
- if (!wait (read_ready))
- {
- res = error_errno_set;
- goto out;
- }
- else if ((err = create_pipe (NULL, &get_io_handle ())) == 0)
- break;
- else if (err == ERROR_PIPE_BUSY)
- {
- debug_only_printf ("pipe busy");
- ResetEvent (read_ready);
- }
- else
- {
- debug_printf ("create of writer failed");
- res = error_set_errno;
- goto out;
- }
- if (!arm (write_ready))
- {
- res = error_set_errno;
- goto out;
- }
- }
-
- /* If setup_overlapped() succeeds (and why wouldn't it?) we are all set. */
- if (setup_overlapped () == 0)
- res = success;
- else
- {
- debug_printf ("setup_overlapped failed, %E");
- res = error_set_errno;
- }
-
-out:
- if (res == error_set_errno)
- __seterrno ();
- if (res != success)
- {
- if (read_ready)
- {
- CloseHandle (read_ready);
- read_ready = NULL;
- }
- if (write_ready)
- {
- CloseHandle (write_ready);
- write_ready = NULL;
- }
- if (get_io_handle ())
- CloseHandle (get_io_handle ());
- }
- debug_printf ("res %d", res);
- return res == success;
-}
-
-bool
-fhandler_fifo::wait (HANDLE h)
-{
-#ifdef DEBUGGING
- const char *what;
- if (h == read_ready)
- what = "reader";
- else if (h == write_ready)
- what = "writer";
- else
- what = "overlapped event";
-#endif
- /* Set the wait to zero for non-blocking I/O-related events. */
- DWORD wait = ((h == read_ready || h == write_ready)
- && get_flags () & O_NONBLOCK) ? 0 : INFINITE;
-
- debug_only_printf ("waiting for %s", what);
- /* Wait for the event. Set errno, as appropriate if something goes wrong. */
- switch (cygwait (h, wait))
- {
- case WAIT_OBJECT_0:
- debug_only_printf ("successfully waited for %s", what);
- return true;
- case WAIT_SIGNALED:
- debug_only_printf ("interrupted by signal while waiting for %s", what);
- set_errno (EINTR);
- return false;
- case WAIT_CANCELED:
- debug_only_printf ("cancellable interruption while waiting for %s", what);
- pthread::static_cancel_self (); /* never returns */
- break;
- case WAIT_TIMEOUT:
- if (h == write_ready)
- {
- debug_only_printf ("wait timed out waiting for write but will still open reader since non-blocking mode");
- return true;
- }
- else
- {
- set_errno (ENXIO);
- return false;
- }
- break;
- default:
- debug_only_printf ("unknown error while waiting for %s", what);
- __seterrno ();
- return false;
- }
-}
-
-void __stdcall
-fhandler_fifo::raw_read (void *in_ptr, size_t& len)
-{
- size_t orig_len = len;
- for (int i = 0; i < 2; i++)
- {
- fhandler_base_overlapped::raw_read (in_ptr, len);
- if (len || i || WaitForSingleObject (read_ready, 0) != WAIT_OBJECT_0)
- break;
- /* If we got here, then fhandler_base_overlapped::raw_read returned 0,
- indicating "EOF" and something has set read_ready to zero. That means
- we should have a client waiting to connect.
- FIXME: If the client CTRL-C's the open during this time then this
- could hang indefinitely. Maybe implement a timeout? */
- if (!DisconnectNamedPipe (get_io_handle ()))
- {
- debug_printf ("DisconnecttNamedPipe failed, %E");
- goto errno_out;
- }
- else if (!ConnectNamedPipe (get_io_handle (), get_overlapped ())
- && GetLastError () != ERROR_IO_PENDING)
- {
- debug_printf ("ConnectNamedPipe failed, %E");
- goto errno_out;
- }
- else if (!arm (read_ready))
- goto errno_out;
- else if (!wait (get_overlapped_buffer ()->hEvent))
- goto errout; /* If wait() fails, errno is set so no need to set it */
- len = orig_len; /* Reset since raw_read above set it to zero. */
- }
- return;
-
-errno_out:
- __seterrno ();
-errout:
- len = -1;
-}
-
-int __stdcall
-fhandler_fifo::fstatvfs (struct statvfs *sfs)
-{
- fhandler_disk_file fh (pc);
- fh.get_device () = FH_FS;
- return fh.fstatvfs (sfs);
-}
-
-int
-fhandler_fifo::close ()
-{
- CloseHandle (read_ready);
- CloseHandle (write_ready);
- return fhandler_base::close ();
-}
-
-int
-fhandler_fifo::dup (fhandler_base *child, int flags)
-{
- if (fhandler_base_overlapped::dup (child, flags))
- {
- __seterrno ();
- return -1;
- }
- fhandler_fifo *fhf = (fhandler_fifo *) child;
- if (!DuplicateHandle (GetCurrentProcess (), read_ready,
- GetCurrentProcess (), &fhf->read_ready,
- 0, true, DUPLICATE_SAME_ACCESS))
- {
- fhf->close ();
- __seterrno ();
- return -1;
- }
- if (!DuplicateHandle (GetCurrentProcess (), write_ready,
- GetCurrentProcess (), &fhf->write_ready,
- 0, true, DUPLICATE_SAME_ACCESS))
- {
- CloseHandle (fhf->read_ready);
- fhf->close ();
- __seterrno ();
- return -1;
- }
- return 0;
-}
-
-void
-fhandler_fifo::fixup_after_fork (HANDLE parent)
-{
- fhandler_base_overlapped::fixup_after_fork (parent);
- fork_fixup (parent, read_ready, "read_ready");
- fork_fixup (parent, write_ready, "write_ready");
-}
-
-void
-fhandler_fifo::set_close_on_exec (bool val)
-{
- fhandler_base::set_close_on_exec (val);
- set_no_inheritance (read_ready, val);
- set_no_inheritance (write_ready, val);
-}