Fix child process spawning on linux (#773)
This commit is contained in:
@@ -33,6 +33,7 @@ class path;
|
|||||||
}
|
}
|
||||||
namespace process {
|
namespace process {
|
||||||
class child;
|
class child;
|
||||||
|
class group;
|
||||||
template<typename Char>
|
template<typename Char>
|
||||||
class basic_environment;
|
class basic_environment;
|
||||||
typedef basic_environment<char> environment;
|
typedef basic_environment<char> environment;
|
||||||
@@ -323,7 +324,7 @@ std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &
|
|||||||
// A list of names of displays accepted as display_name with the mem_type_e
|
// A list of names of displays accepted as display_name with the mem_type_e
|
||||||
std::vector<std::string> display_names(mem_type_e hwdevice_type);
|
std::vector<std::string> display_names(mem_type_e hwdevice_type);
|
||||||
|
|
||||||
boost::process::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec);
|
boost::process::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group);
|
||||||
|
|
||||||
enum class thread_priority_e : int {
|
enum class thread_priority_e : int {
|
||||||
low,
|
low,
|
||||||
|
|||||||
@@ -145,13 +145,23 @@ std::string get_mac_address(const std::string_view &address) {
|
|||||||
return "00:00:00:00:00:00"s;
|
return "00:00:00:00:00:00"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) {
|
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||||
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
|
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
|
||||||
if(!file) {
|
if(!group) {
|
||||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
if(!file) {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
if(!file) {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,13 +121,23 @@ std::string get_mac_address(const std::string_view &address) {
|
|||||||
return "00:00:00:00:00:00"s;
|
return "00:00:00:00:00:00"s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) {
|
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||||
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
|
BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
|
||||||
if(!file) {
|
if(!group) {
|
||||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
if(!file) {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
if(!file) {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ void free_proc_thread_attr_list(LPPROC_THREAD_ATTRIBUTE_LIST list) {
|
|||||||
HeapFree(GetProcessHeap(), 0, list);
|
HeapFree(GetProcessHeap(), 0, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) {
|
bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||||
HANDLE shell_token = duplicate_shell_token();
|
HANDLE shell_token = duplicate_shell_token();
|
||||||
if(!shell_token) {
|
if(!shell_token) {
|
||||||
// This can happen if the shell has crashed. Fail the launch rather than risking launching with
|
// This can happen if the shell has crashed. Fail the launch rather than risking launching with
|
||||||
@@ -490,6 +490,9 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
|
|||||||
// Since we are always spawning a process with a less privileged token than ourselves,
|
// Since we are always spawning a process with a less privileged token than ourselves,
|
||||||
// bp::child() should have no problem opening it with any access rights it wants.
|
// bp::child() should have no problem opening it with any access rights it wants.
|
||||||
auto child = bp::child((bp::pid_t)process_info.dwProcessId);
|
auto child = bp::child((bp::pid_t)process_info.dwProcessId);
|
||||||
|
if(group) {
|
||||||
|
group->add(child);
|
||||||
|
}
|
||||||
|
|
||||||
// Only close handles after bp::child() has opened the process. If the process terminates
|
// Only close handles after bp::child() has opened the process. If the process terminates
|
||||||
// quickly, the PID could be reused if we close the process handle.
|
// quickly, the PID could be reused if we close the process handle.
|
||||||
|
|||||||
+2
-4
@@ -150,7 +150,7 @@ int proc_t::execute(int app_id) {
|
|||||||
find_working_directory(cmd, _env) :
|
find_working_directory(cmd, _env) :
|
||||||
boost::filesystem::path(proc.working_dir);
|
boost::filesystem::path(proc.working_dir);
|
||||||
BOOST_LOG(info) << "Spawning ["sv << cmd << "] in ["sv << working_dir << ']';
|
BOOST_LOG(info) << "Spawning ["sv << cmd << "] in ["sv << working_dir << ']';
|
||||||
auto child = platf::run_unprivileged(cmd, working_dir, _env, _pipe.get(), ec);
|
auto child = platf::run_unprivileged(cmd, working_dir, _env, _pipe.get(), ec, nullptr);
|
||||||
if(ec) {
|
if(ec) {
|
||||||
BOOST_LOG(warning) << "Couldn't spawn ["sv << cmd << "]: System: "sv << ec.message();
|
BOOST_LOG(warning) << "Couldn't spawn ["sv << cmd << "]: System: "sv << ec.message();
|
||||||
}
|
}
|
||||||
@@ -168,13 +168,11 @@ int proc_t::execute(int app_id) {
|
|||||||
find_working_directory(proc.cmd, _env) :
|
find_working_directory(proc.cmd, _env) :
|
||||||
boost::filesystem::path(proc.working_dir);
|
boost::filesystem::path(proc.working_dir);
|
||||||
BOOST_LOG(info) << "Executing: ["sv << proc.cmd << "] in ["sv << working_dir << ']';
|
BOOST_LOG(info) << "Executing: ["sv << proc.cmd << "] in ["sv << working_dir << ']';
|
||||||
_process = platf::run_unprivileged(proc.cmd, working_dir, _env, _pipe.get(), ec);
|
_process = platf::run_unprivileged(proc.cmd, working_dir, _env, _pipe.get(), ec, &_process_handle);
|
||||||
if(ec) {
|
if(ec) {
|
||||||
BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message();
|
BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_process_handle.add(_process);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fg.disable();
|
fg.disable();
|
||||||
|
|||||||
Reference in New Issue
Block a user