diff options
Diffstat (limited to 'winsup/cygwin/fhandler_fifo.cc')
-rw-r--r-- | winsup/cygwin/fhandler_fifo.cc | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc deleted file mode 100644 index 8c0fbc9b0..000000000 --- a/winsup/cygwin/fhandler_fifo.cc +++ /dev/null @@ -1,333 +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 - 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" - -fhandler_fifo::fhandler_fifo (): - fhandler_base_overlapped (), wait_state (fifo_unknown), dummy_client (NULL) -{ - max_atomic_write = DEFAULT_PIPEBUFSIZE; - need_fork_fixup (true); -} - -HANDLE -fhandler_fifo::open_nonserver (const char *npname, unsigned low_flags, - LPSECURITY_ATTRIBUTES sa_buf) -{ - DWORD mode = 0; - if (low_flags == O_RDONLY) - mode = GENERIC_READ; - else if (low_flags == O_WRONLY) - mode = GENERIC_WRITE; - else - mode = GENERIC_READ | GENERIC_WRITE; - while (1) - { - HANDLE h = CreateFile (npname, mode, 0, sa_buf, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); - if (h != INVALID_HANDLE_VALUE || GetLastError () != ERROR_PIPE_NOT_CONNECTED) - return h; - if (IsEventSignalled (signal_arrived)) - { - set_errno (EINTR); - return NULL; - } - } -} - -char * -fhandler_fifo::fifo_name (char *buf) -{ - /* Generate a semi-unique name to associate with this fifo. */ - __small_sprintf (buf, "\\\\.\\pipe\\__cygfifo__%S_%08x_%016X", - &installation_key, get_dev (), get_ino ()); - return buf; -} - -#define FIFO_PIPE_MODE (PIPE_TYPE_BYTE | PIPE_READMODE_BYTE) -#define FIFO_BUF_SIZE 4096 -#define cnp(m, s) CreateNamedPipe(npname, (m), FIFO_PIPE_MODE, \ - PIPE_UNLIMITED_INSTANCES, (s), (s), \ - NMPWAIT_WAIT_FOREVER, sa_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); -} - -int -fhandler_fifo::open (int flags, mode_t) -{ - int res = 1; - char npname[MAX_PATH]; - - fifo_name (npname); - unsigned low_flags = flags & O_ACCMODE; - DWORD mode = 0; - if (low_flags == O_WRONLY) - mode = PIPE_ACCESS_OUTBOUND; - else if (low_flags == O_RDONLY || low_flags == O_RDWR) - mode = PIPE_ACCESS_DUPLEX; - else - { - set_errno (EINVAL); - res = 0; - } - - if (res) - { - char char_sa_buf[1024]; - LPSECURITY_ATTRIBUTES sa_buf = - sec_user_cloexec (flags & O_CLOEXEC, (PSECURITY_ATTRIBUTES) char_sa_buf, - cygheap->user.sid()); - bool do_seterrno = true; - - HANDLE h; - bool nonblocking_write = !!((flags & (O_WRONLY | O_NONBLOCK)) == (O_WRONLY | O_NONBLOCK)); - wait_state = fifo_unknown; - if (mode != PIPE_ACCESS_OUTBOUND) - { - h = cnp (mode | FILE_FLAG_OVERLAPPED, FIFO_BUF_SIZE); - wait_state = fifo_wait_for_client; - } - else - { - h = open_nonserver (npname, low_flags, sa_buf); - if (h != INVALID_HANDLE_VALUE) - wait_state = fifo_ok; - else if (nonblocking_write) - { - set_errno (ENXIO); - do_seterrno = false; - } - else if ((h = cnp (PIPE_ACCESS_DUPLEX, 1)) != INVALID_HANDLE_VALUE) - { - if ((dummy_client = open_nonserver (npname, low_flags, sa_buf)) - != INVALID_HANDLE_VALUE) - { - wait_state = fifo_wait_for_server; - ProtectHandle (dummy_client); - } - else - { - DWORD saveerr = GetLastError (); - CloseHandle (h); - h = INVALID_HANDLE_VALUE; - SetLastError (saveerr); - } - } - } - if (h == INVALID_HANDLE_VALUE) - { - if (do_seterrno) - __seterrno (); - res = 0; - } - else if (setup_overlapped ()) - { - CloseHandle (h); - __seterrno (); - res = 0; - } - else - { - set_io_handle (h); - set_flags (flags); - res = 1; - } - } - - debug_printf ("returning %d, errno %d", res, get_errno ()); - return res; -} - -bool -fhandler_fifo::wait (bool iswrite) -{ - DWORD ninstances; - switch (wait_state) - { - case fifo_wait_for_next_client: - DisconnectNamedPipe (get_handle ()); - if (!GetNamedPipeHandleState (get_handle (), NULL, &ninstances, NULL, NULL, NULL, 0)) - { - __seterrno (); - wait_state = fifo_error; - return false; - } - if (ninstances <= 1) - { - wait_state = fifo_eof; - return false; - } - case fifo_wait_for_client: - { - DWORD dummy_bytes; - while (1) - { - int res = ConnectNamedPipe (get_handle (), get_overlapped ()); - if (GetLastError () != ERROR_NO_DATA && GetLastError () != ERROR_PIPE_CONNECTED) - { - res = wait_overlapped (res, iswrite, &dummy_bytes, false); - if (!res) - { - if (get_errno () != EINTR) - wait_state = fifo_error; - else if (!_my_tls.call_signal_handler ()) - wait_state = fifo_eintr; - else - continue; - return false; - } - } - wait_state = fifo_ok; - break; - } - } - break; - case fifo_wait_for_server: - char npname[MAX_PATH]; - fifo_name (npname); - char char_sa_buf[1024]; - LPSECURITY_ATTRIBUTES sa_buf; - sa_buf = sec_user_cloexec (close_on_exec (), - (PSECURITY_ATTRIBUTES) char_sa_buf, - cygheap->user.sid()); - while (1) - { - if (WaitNamedPipe (npname, 10)) - /* connected, maybe */; - else if (GetLastError () != ERROR_SEM_TIMEOUT) - { - __seterrno (); - return false; - } - else if (!IsEventSignalled (signal_arrived)) - continue; - else if (_my_tls.call_signal_handler ()) - continue; - else - { - set_errno (EINTR); - return false; - } - HANDLE h = open_nonserver (npname, get_flags () & O_ACCMODE, sa_buf); - if (h != INVALID_HANDLE_VALUE) - { - ForceCloseHandle (get_handle ()); - ForceCloseHandle (dummy_client); - dummy_client = NULL; - wait_state = fifo_ok; - set_io_handle (h); - break; - } - if (GetLastError () == ERROR_PIPE_LISTENING) - continue; - else - { - __seterrno (); - return false; - } - } - default: - break; - } - return true; -} - -void __stdcall -fhandler_fifo::raw_read (void *in_ptr, size_t& len) -{ - while (wait_state != fifo_eof && wait_state != fifo_error && wait_state != fifo_eintr) - if (!wait (false)) - len = (wait_state == fifo_error || wait_state == fifo_eintr) ? (size_t) -1 : 0; - else - { - size_t prev_len = len; - fhandler_base_overlapped::raw_read (in_ptr, len); - if (len) - break; - wait_state = fifo_wait_for_next_client; - len = prev_len; - } - if (wait_state == fifo_eintr) - wait_state = fifo_wait_for_client; - debug_printf ("returning %d, mode %d, %E\n", len, get_errno ()); -} - -ssize_t __stdcall -fhandler_fifo::raw_write (const void *ptr, size_t len) -{ - return wait (true) ? fhandler_base_overlapped::raw_write (ptr, 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 () -{ - wait_state = fifo_eof; - if (dummy_client) - { - ForceCloseHandle (dummy_client); - dummy_client = NULL; - } - return fhandler_base::close (); -} - -int -fhandler_fifo::dup (fhandler_base *child) -{ - int res = fhandler_base_overlapped::dup (child); - fhandler_fifo *fifo_child = (fhandler_fifo *) child; - if (res == 0 && dummy_client) - { - bool dres = DuplicateHandle (GetCurrentProcess (), dummy_client, - GetCurrentProcess (), - &fifo_child->dummy_client, 0, - TRUE, DUPLICATE_SAME_ACCESS); - if (!dres) - { - fifo_child->dummy_client = NULL; - child->close (); - __seterrno (); - res = -1; - } - } - return res; -} - -void -fhandler_fifo::set_close_on_exec (bool val) -{ - fhandler_base::set_close_on_exec (val); - if (dummy_client) - set_no_inheritance (dummy_client, val); -} |