diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 35c1ffe25..800adbff1 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -478,33 +478,28 @@ pinfo::set_acl() debug_printf ("NtSetSecurityObject %y", status); } +void +pinfo_minimal::set_inheritance (bool inherit) +{ + DWORD i_flag = inherit ? HANDLE_FLAG_INHERIT : 0; + + SetHandleInformation (rd_proc_pipe, HANDLE_FLAG_INHERIT, i_flag); + SetHandleInformation (hProcess, HANDLE_FLAG_INHERIT, i_flag); + SetHandleInformation (h, HANDLE_FLAG_INHERIT, i_flag); +} + pinfo::pinfo (HANDLE parent, pinfo_minimal& from, pid_t pid): pinfo_minimal (), destroy (false), procinfo (NULL), waiter_ready (false), wait_thread (NULL) { - HANDLE herr; - const char *duperr = NULL; - if (!DuplicateHandle (parent, herr = from.rd_proc_pipe, GetCurrentProcess (), - &rd_proc_pipe, 0, false, DUPLICATE_SAME_ACCESS)) - duperr = "couldn't duplicate parent rd_proc_pipe handle %p for forked child %d after exec, %E"; - else if (!DuplicateHandle (parent, herr = from.hProcess, GetCurrentProcess (), - &hProcess, 0, false, DUPLICATE_SAME_ACCESS)) - duperr = "couldn't duplicate parent process handle %p for forked child %d after exec, %E"; - else - { - h = NULL; - DuplicateHandle (parent, from.h, GetCurrentProcess (), &h, 0, false, - DUPLICATE_SAME_ACCESS); - init (pid, PID_MAP_RW, h); - if (*this) - return; - } - - if (duperr) - debug_printf (duperr, herr, pid); - - /* Returning with procinfo == NULL. Any open handles will be closed by the - destructor. */ + /* cygheap_exec_info::record_children set the inheritance of the required + child handles so just copy them over... */ + rd_proc_pipe = from.rd_proc_pipe; + hProcess = from.hProcess; + h = from.h; + /* ...and reset their inheritance. */ + set_inheritance (false); + init (pid, PID_MAP_RW, h); } const char * diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 8cf1bba2e..23f308360 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -139,6 +139,7 @@ public: HANDLE rd_proc_pipe; pinfo_minimal (): h (NULL), hProcess (NULL), rd_proc_pipe (NULL) {} void set_rd_proc_pipe (HANDLE& h) {rd_proc_pipe = h;} + void set_inheritance (bool); friend class pinfo; }; diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index fb0e37215..23f752ca7 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -94,3 +94,6 @@ Bug Fixes - Make spawnvp, spawnvpe fail if the executable is not in $PATH. Addresses: https://cygwin.com/ml/cygwin/2019-10/msg00032.html + +- Fix parent/child relationship after parent dies. + Addresses: https://cygwin.com/ml/cygwin/2019-09/msg00263.html diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 91abb717c..aff1ed61b 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -949,6 +949,9 @@ cygheap_exec_info::record_children () { children[nchildren].pid = procs[nchildren]->pid; children[nchildren].p = procs[nchildren]; + /* Set inheritance of required child handles for reattach_children + in the about-to-be-execed process. */ + children[nchildren].p.set_inheritance (true); } }