From: Ken Brown Date: Mon, 4 May 2020 15:36:20 +0000 (-0400) Subject: Cygwin: FIFO: dup/fork/exec: make sure child starts unlocked X-Git-Tag: cygwin-3_1_5-release~49 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=13c65c43c24015f75b6488dc476b8d7b22c84f18;p=newlib-cygwin.git Cygwin: FIFO: dup/fork/exec: make sure child starts unlocked There can be deadlocks if the child starts with its fifo_client_lock in the locked state. --- diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index f61e2fe72..4904a535d 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -981,6 +981,9 @@ fhandler_fifo::dup (fhandler_base *child, int flags) } if (reader) { + /* Make sure the child starts unlocked. */ + fhf->fifo_client_unlock (); + fifo_client_lock (); for (i = 0; i < nhandlers; i++) { @@ -1025,20 +1028,32 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); - fifo_client_lock (); - for (int i = 0; i < nhandlers; i++) - fork_fixup (parent, fc_handler[i].h, "fc_handler[].h"); - fifo_client_unlock (); - if (reader && !listen_client ()) - debug_printf ("failed to start lct, %E"); + if (reader) + { + /* Make sure the child starts unlocked. */ + fifo_client_unlock (); + + fifo_client_lock (); + for (int i = 0; i < nhandlers; i++) + fork_fixup (parent, fc_handler[i].h, "fc_handler[].h"); + fifo_client_unlock (); + if (!listen_client ()) + debug_printf ("failed to start lct, %E"); + } } void fhandler_fifo::fixup_after_exec () { fhandler_base::fixup_after_exec (); - if (reader && !listen_client ()) - debug_printf ("failed to start lct, %E"); + if (reader && !close_on_exec ()) + { + /* Make sure the child starts unlocked. */ + fifo_client_unlock (); + + if (!listen_client ()) + debug_printf ("failed to start lct, %E"); + } } void