From d5c72f645d852b3280f7bba02c687eeb9f54d908 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 7 Nov 2024 21:01:11 -0600 Subject: [PATCH] fix(process): avoid leaking zombies and fds in detached processes --- src/platform/linux/misc.cpp | 8 ++++---- src/platform/macos/misc.mm | 8 ++++---- src/process.cpp | 10 ++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index b7a57c33ce2..a6953ebe9a3 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -243,18 +243,18 @@ namespace platf { run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { if (!group) { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec); } } else { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec, *group); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec, *group); } } } diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index cee850dcdf7..680ddb68ed6 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -184,18 +184,18 @@ run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { if (!group) { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec); } } else { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec, *group); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec, *group); } } } diff --git a/src/process.cpp b/src/process.cpp index 26e2c0a3588..1c78ff4d9c8 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -269,6 +269,16 @@ namespace proc { int proc_t::running() { +#ifndef _WIN32 + // On POSIX OSes, we must periodically wait for our children to avoid + // them becoming zombies. This must be synchronized carefully with + // calls to bp::wait() and platf::process_group_running() which both + // invoke waitpid() under the hood. + auto reaper = util::fail_guard([]() { + while (waitpid(-1, nullptr, WNOHANG) > 0); + }); +#endif + if (placebo) { return _app_id; }