diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1e26c651f..aea02c2b3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1280,6 +1280,7 @@ class fhandler_fifo: public fhandler_base int disconnect_and_reconnect (int); int add_client_handler (); bool listen_client (); + int stop_listen_client (); public: fhandler_fifo (); bool hit_eof (); @@ -1326,7 +1327,12 @@ public: { void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo)); fhandler_fifo *fhf = new (ptr) fhandler_fifo (ptr); + /* We don't want our client list to change any more. */ + stop_listen_client (); copyto (fhf); + /* fhf->pipe_name_buf is a *copy* of this->pipe_name_buf, but + fhf->pipe_name.Buffer == this->pipe_name_buf. */ + fhf->pipe_name.Buffer = fhf->pipe_name_buf; for (int i = 0; i < nhandlers; i++) fhf->fc_handler[i].fh = fc_handler[i].fh->clone (); return fhf; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index d4d2b3883..a3ecbeb4a 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -812,9 +812,9 @@ fifo_client_handler::close () } int -fhandler_fifo::close () +fhandler_fifo::stop_listen_client () { - int res = 0; + int ret = 0; HANDLE evt = InterlockedExchangePointer (&lct_termination_evt, NULL); HANDLE thr = InterlockedExchangePointer (&listen_client_thr, NULL); if (thr) @@ -825,19 +825,29 @@ fhandler_fifo::close () DWORD err; GetExitCodeThread (thr, &err); if (err) - debug_printf ("listen_client_thread exited with code %d", err); + { + ret = -1; + debug_printf ("listen_client_thread exited with error, %E"); + } CloseHandle (thr); } if (evt) CloseHandle (evt); + return ret; +} + +int +fhandler_fifo::close () +{ + int ret = stop_listen_client (); if (read_ready) CloseHandle (read_ready); if (write_ready) CloseHandle (write_ready); for (int i = 0; i < nhandlers; i++) if (fc_handler[i].close () < 0) - res = -1; - return fhandler_base::close () || res; + ret = -1; + return fhandler_base::close () || ret; } int