aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Brown <kbrown@cornell.edu>2019-05-09 11:23:44 -0400
committerKen Brown <kbrown@cornell.edu>2019-05-09 14:41:29 -0400
commit00b2e56d3184231264005d6b1f60b1f40023907b (patch)
tree17dbe88966ede53401fa3b6398e139d22cc47d4e
parentf3d1fe2ff81ad6f5327caa9229626e39101da2c9 (diff)
downloadnewlib-00b2e56d3184231264005d6b1f60b1f40023907b.zip
newlib-00b2e56d3184231264005d6b1f60b1f40023907b.tar.gz
newlib-00b2e56d3184231264005d6b1f60b1f40023907b.tar.bz2
Cygwin: FIFO: re-implement duplexers
When opening a duplexer, open a client connection to the first client handler. Previously we gave the duplexer a bogus write handle, which was just a duplicate of the first client handler's handle. This meant that we had a pipe server with no clients connected, and all I/O attempts failed with STATUS_PIPE_LISTENING. Extend the last fcntl change to duplexers. Remove a now unused fifo_client_handler constructor, as well as the long unusued method fifo_client_handler::connect. Don't create the pipe in duplex mode; the server handle will only be used for reading.
-rw-r--r--winsup/cygwin/fhandler.h4
-rw-r--r--winsup/cygwin/fhandler_fifo.cc41
2 files changed, 11 insertions, 34 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 3b2b194..16165c4 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1251,10 +1251,6 @@ struct fifo_client_handler
fifo_client_connect_state state;
HANDLE connect_evt;
fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {}
- fifo_client_handler (fhandler_base *_fh, fifo_client_connect_state _state,
- HANDLE _connect_evt)
- : fh (_fh), state (_state), connect_evt (_connect_evt) {}
- int connect ();
int close ();
};
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 8dfe496..1a16109 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -175,8 +175,6 @@ fhandler_fifo::create_pipe_instance (bool first)
}
access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE;
- if (first && duplexer)
- access |= GENERIC_WRITE;
sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
hattr = OBJ_INHERIT;
if (first)
@@ -474,41 +472,23 @@ fhandler_fifo::open (int flags, mode_t)
/* If we're a duplexer, create the pipe and the first client handler. */
if (duplexer)
{
- HANDLE ph, connect_evt;
- fhandler_base *fh;
-
- ph = create_pipe_instance (true);
- if (!ph)
- {
- res = error_errno_set;
- goto out;
- }
- set_handle (ph);
- set_pipe_non_blocking (ph, true);
- if (!(fh = build_fh_dev (dev ())))
+ if (add_client_handler () < 0)
{
- set_errno (EMFILE);
res = error_errno_set;
goto out;
}
- if (!DuplicateHandle (GetCurrentProcess (), ph, GetCurrentProcess (),
- &fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS))
+ NTSTATUS status = open_pipe ();
+ if (NT_SUCCESS (status))
{
- res = error_set_errno;
- fh->close ();
- delete fh;
- goto out;
+ record_connection (fc_handler[0]);
+ set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK);
}
- fh->set_flags (flags);
- if (!(connect_evt = create_event ()))
+ else
{
+ __seterrno_from_nt_status (status);
res = error_errno_set;
- fh->close ();
- delete fh;
goto out;
}
- fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt);
- nconnected = nhandlers = 1;
}
/* If we're reading, start the listen_client thread (which should
@@ -889,12 +869,13 @@ fhandler_fifo::close ()
return fhandler_base::close () || ret;
}
-/* If we're a writer, keep the nonblocking state of the windows pipe
- in sync with our nonblocking state. */
+/* If we have a write handle (i.e., we're a duplexer or a writer),
+ keep the nonblocking state of the windows pipe in sync with our
+ nonblocking state. */
int
fhandler_fifo::fcntl (int cmd, intptr_t arg)
{
- if (cmd != F_SETFL || !writer)
+ if (cmd != F_SETFL || nohandle ())
return fhandler_base::fcntl (cmd, arg);
const bool was_nonblocking = is_nonblocking ();