From 9e48e582210496491ee3d5d6786dc0e03b235ac2 Mon Sep 17 00:00:00 2001 From: loki Date: Wed, 12 May 2021 23:01:30 +0200 Subject: [PATCH] Allow applications started by sunshine to be detached --- README.md | 9 +++++++-- assets/apps_linux.json | 2 +- assets/apps_windows.json | 4 +--- sunshine/process.cpp | 35 ++++++++++++++++++++++++++++++----- sunshine/process.h | 9 +++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 102a1207..12490bde 100644 --- a/README.md +++ b/README.md @@ -117,15 +117,20 @@ sunshine needs access to uinput to create mouse and gamepad events: "cmd":"command to open app", "prep-cmd":[ { - "do":"somecommand", - "undo":"undothatcommand" + "do":"some-command", + "undo":"undo-that-command" } + ], + "detached":[ + "some-command", + "another-command" ] } ``` - name: Self explanatory - output : The file where the output of the command is stored - If it is not specified, the output is ignored + - detached: A list of commands to be run and forgotten about - prep-cmd: A list of commands to be run before/after the application - If any of the prep-commands fail, starting the application is aborted - do: Run before the application diff --git a/assets/apps_linux.json b/assets/apps_linux.json index 13950778..1cfeb3d4 100644 --- a/assets/apps_linux.json +++ b/assets/apps_linux.json @@ -13,7 +13,7 @@ "name":"Steam BigPicture", "output":"steam.txt", - "cmd":"steam -bigpicture" + "detached":["setsid steam steam://open/bigpicture"] } ] } diff --git a/assets/apps_windows.json b/assets/apps_windows.json index 512fd497..f2a2a7ec 100644 --- a/assets/apps_windows.json +++ b/assets/apps_windows.json @@ -7,9 +7,7 @@ "name":"Steam BigPicture", "output":"steam.txt", - "prep-cmd":[ - {"do":"steam \"steam://open/bigpicture\""} - ] + "detached":["steam steam://open/bigpicture"] } ] } diff --git a/sunshine/process.cpp b/sunshine/process.cpp index ec2aa2fe..85767eac 100644 --- a/sunshine/process.cpp +++ b/sunshine/process.cpp @@ -80,17 +80,31 @@ int proc_t::execute(int app_id) { auto ret = exe(cmd, _env, _pipe, ec); if(ec) { - BOOST_LOG(error) << "System: "sv << ec.message(); + BOOST_LOG(error) << "Couldn't run ["sv << cmd << "]: System: "sv << ec.message(); return -1; } if(ret != 0) { - BOOST_LOG(error) << "Return code ["sv << ret << ']'; + BOOST_LOG(error) << '[' << cmd << "] failed with code ["sv << ret << ']'; return -1; } } - BOOST_LOG(debug) << "Starting ["sv << proc.cmd << ']'; + for(auto &cmd : proc.detached) { + BOOST_LOG(info) << "Spawning ["sv << cmd << ']'; + if(proc.output.empty()) { + bp::spawn(cmd, _env, bp::std_out > bp::null, bp::std_err > bp::null, ec); + } + else { + bp::spawn(cmd, _env, bp::std_out > _pipe.get(), bp::std_err > _pipe.get(), ec); + } + + if(ec) { + BOOST_LOG(warning) << "Couldn't spawn ["sv << cmd << "]: System: "sv << ec.message(); + } + } + + BOOST_LOG(info) << "Executing: ["sv << proc.cmd << ']'; if(proc.cmd.empty()) { placebo = true; } @@ -102,7 +116,7 @@ int proc_t::execute(int app_id) { } if(ec) { - BOOST_LOG(info) << "System: "sv << ec.message(); + BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message(); return -1; } @@ -251,12 +265,12 @@ std::optional parse(const std::string& file_name) { proc::ctx_t ctx; auto prep_nodes_opt = app_node.get_child_optional("prep-cmd"s); + auto detached_nodes_opt = app_node.get_child_optional("detached"s); auto output = app_node.get_optional("output"s); auto name = parse_env_val(this_env, app_node.get("name"s)); auto cmd = app_node.get_optional("cmd"s); std::vector prep_cmds; - if(prep_nodes_opt) { auto &prep_nodes = *prep_nodes_opt; @@ -274,6 +288,16 @@ std::optional parse(const std::string& file_name) { } } + std::vector detached; + if(detached_nodes_opt) { + auto &detached_nodes = *detached_nodes_opt; + + detached.reserve(detached_nodes.size()); + for(auto &[_, detached_val] : detached_nodes) { + detached.emplace_back(parse_env_val(this_env, detached_val.get_value())); + } + } + if(output) { ctx.output = parse_env_val(this_env, *output); } @@ -284,6 +308,7 @@ std::optional parse(const std::string& file_name) { ctx.name = std::move(name); ctx.prep_cmds = std::move(prep_cmds); + ctx.detached = std::move(detached); apps.emplace_back(std::move(ctx)); } diff --git a/sunshine/process.h b/sunshine/process.h index 37c17acd..e267fa44 100644 --- a/sunshine/process.h +++ b/sunshine/process.h @@ -30,6 +30,7 @@ struct cmd_t { }; /* * pre_cmds -- guaranteed to be executed unless any of the commands fail. + * detached -- commands detached from Sunshine * cmd -- Runs indefinitely until: * No session is running and a different set of commands it to be executed * Command exits @@ -41,6 +42,14 @@ struct cmd_t { struct ctx_t { std::vector prep_cmds; + /** + * Some applications, such as Steam, + * either exit quickly, or keep running indefinitely. + * Steam.exe is one such application. + * That is why some applications need be run and forgotten about + */ + std::vector detached; + std::string name; std::string cmd; std::string output;