From 8b561225429d859a38a18df0a2a0eaa0acceb9f9 Mon Sep 17 00:00:00 2001 From: loki Date: Sun, 15 Dec 2019 14:30:00 +0100 Subject: [PATCH] load apps contexts into memory from a JSON file --- assets/apps.json | 29 ++++++++++++ assets/sunshine.conf | 2 +- sunshine/config.cpp | 3 +- sunshine/main.cpp | 90 ++++++++++++++++++++++++++++++------- sunshine/platform/linux.cpp | 2 +- sunshine/process.cpp | 12 ++--- sunshine/process.h | 7 ++- 7 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 assets/apps.json diff --git a/assets/apps.json b/assets/apps.json new file mode 100644 index 00000000..1f0a4838 --- /dev/null +++ b/assets/apps.json @@ -0,0 +1,29 @@ +{ + "env":[ + { "VAR":"VAL", "VAR2":"VAL2" } + ], + "apps":[ + { + "name":"echo-1", + + "output":"output.txt", + "cmd":"sh -c \"echo $VAR\"", + "prep-cmd":[ + { "do":"echo pre-1", "undo":"echo post-1" }, + { "do":"echo pre-2" }, + { "do":"echo pre-3", "undo":"echo post-3" } + ] + }, + { + "name":"echo-2", + + "output":"output.txt", + "cmd":"sleep 10", + "prep-cmd":[ + { "do":"echo pre-1", "undo":"echo post-1" }, + { "do":"echo pre-2" }, + { "do":"echo pre-3", "undo":"echo post-3" } + ] + } + ] +} diff --git a/assets/sunshine.conf b/assets/sunshine.conf index 696a4b04..8dfc218e 100644 --- a/assets/sunshine.conf +++ b/assets/sunshine.conf @@ -12,7 +12,7 @@ unique_id = 03904e64-51da-4fb3-9afd-a9f7ff70fea4 # The file where info on paired devices is stored -file_devices = devices.xml +file_devices = devices.json # How long to wait in milliseconds for data from moonlight before shutting down the stream ping_timeout = 2000 diff --git a/sunshine/config.cpp b/sunshine/config.cpp index 2c52c141..8d6bb799 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -38,7 +37,7 @@ nvhttp_t nvhttp { CERTIFICATE_FILE, "03904e64-51da-4fb3-9afd-a9f7ff70fea4", // unique_id - "devices.xml" // file_devices + "devices.json" // file_devices }; bool whitespace(char ch) { diff --git a/sunshine/main.cpp b/sunshine/main.cpp index 12007315..a895ad72 100644 --- a/sunshine/main.cpp +++ b/sunshine/main.cpp @@ -6,38 +6,94 @@ #include #include +#include +#include + #include "nvhttp.h" #include "stream.h" +#include "config.h" +#include "process.h" extern "C" { #include } -#include "config.h" - -#include "process.h" using namespace std::literals; +namespace pt = boost::property_tree; + +std::optional parse(const std::string& file_name) { + pt::ptree tree; + + try { + pt::read_json(file_name, tree); + + auto &apps_node = tree.get_child("apps"s); + auto &env_vars = tree.get_child("env"s); + + boost::process::environment env = boost::this_process::environment(); + + std::unordered_map apps; + for(auto &[_,app_node] : apps_node) { + proc::ctx_t ctx; + + auto &prep_nodes = app_node.get_child("prep-cmd"s); + auto name = app_node.get("name"s); + auto output = app_node.get_optional("output"s); + auto cmd = app_node.get("cmd"s); + + std::vector prep_cmds; + prep_cmds.reserve(prep_nodes.size()); + for(auto &[_, prep_node] : prep_nodes) { + auto do_cmd = prep_node.get("do"s); + auto undo_cmd = prep_node.get_optional("undo"s); + + if(undo_cmd) { + prep_cmds.emplace_back(std::move(do_cmd), std::move(*undo_cmd)); + } + else { + prep_cmds.emplace_back(std::move(do_cmd)); + } + } + + if(output) { + ctx.output = std::move(*output); + } + ctx.cmd = std::move(cmd); + ctx.prep_cmds = std::move(prep_cmds); + + apps.emplace(std::move(name), std::move(ctx)); + } + + for(auto &[_,env_var] : env_vars) { + for(auto &[name,val] : env_var) { + env[name] = val.get_value(); + } + } + + return proc::proc_t { + std::move(env), std::move(apps) + }; + } catch (std::exception &e) { + std::cout << e.what() << std::endl; + } + + return std::nullopt; +} + int main(int argc, char *argv[]) { - std::vector pre_cmds { - { "echo pre-1", "echo post-1" }, - { "echo pre-2", "" }, - { "echo pre-3", "echo post-3" } - }; + auto proc_opt = parse(SUNSHINE_ASSETS_DIR "/apps.json"); - std::unordered_map map { - { "echo", { std::move(pre_cmds), R"(echo \"middle\")", "output.txt" } } - }; + if(!proc_opt) { + return 7; + } - boost::process::environment env = boost::this_process::environment(); - proc::proc_t proc(std::move(env), std::move(map)); - - proc.execute("echo"s); + auto &proc = *proc_opt; + proc.execute("echo-2"); std::this_thread::sleep_for(50ms); - proc.execute("echo"s); - + proc.execute("echo-1"); std::this_thread::sleep_for(50ms); return proc.running(); diff --git a/sunshine/platform/linux.cpp b/sunshine/platform/linux.cpp index fdaa613e..8713ab50 100644 --- a/sunshine/platform/linux.cpp +++ b/sunshine/platform/linux.cpp @@ -85,7 +85,7 @@ std::string get_local_ip(int family) { std::string get_local_ip() { return get_local_ip(AF_INET); } void interrupt_process(std::uint64_t handle) { - kill((pid_t)handle, SIGTERM); + kill((pid_t)handle, SIGINT); } struct display_attr_t { diff --git a/sunshine/process.cpp b/sunshine/process.cpp index df05fcb7..4e303440 100644 --- a/sunshine/process.cpp +++ b/sunshine/process.cpp @@ -50,11 +50,11 @@ int proc_t::execute(const std::string &name) { auto &proc = it->second; - _undo_begin = std::begin(proc.pre_cmds); + _undo_begin = std::begin(proc.prep_cmds); _undo_it = _undo_begin; - if(!proc.cmd_output.empty() && proc.cmd_output != "null"sv) { - _pipe.reset(fopen(proc.cmd_output.c_str(), "a")); + if(!proc.output.empty() && proc.output != "null"sv) { + _pipe.reset(fopen(proc.output.c_str(), "a")); } std::error_code ec; @@ -63,7 +63,7 @@ int proc_t::execute(const std::string &name) { _undo_pre_cmd(); }); - for(; _undo_it != std::end(proc.pre_cmds); ++_undo_it) { + for(; _undo_it != std::end(proc.prep_cmds); ++_undo_it) { auto &cmd = _undo_it->do_cmd; std::cout << "Executing: ["sv << cmd << ']' << std::endl; @@ -81,11 +81,11 @@ int proc_t::execute(const std::string &name) { } std::cout << "Starting ["sv << proc.cmd << ']' << std::endl; - if(proc.cmd_output.empty() || proc.cmd_output == "null"sv) { + if(proc.output.empty() || proc.output == "null"sv) { _process = bp::child(proc.cmd, _env, bp::std_out > bp::null, bp::std_err > bp::null, ec); } else { - _process = bp::child(proc.cmd, _env, bp::std_out > proc.cmd_output, bp::std_err > proc.cmd_output, ec); + _process = bp::child(proc.cmd, _env, bp::std_out > _pipe.get(), bp::std_err > _pipe.get(), ec); } if(ec) { diff --git a/sunshine/process.h b/sunshine/process.h index f0a3f114..a43360d2 100644 --- a/sunshine/process.h +++ b/sunshine/process.h @@ -14,6 +14,9 @@ namespace proc { using file_t = util::safe_ptr_v2; struct cmd_t { + cmd_t(std::string &&do_cmd, std::string &&undo_cmd) : do_cmd(std::move(do_cmd)), undo_cmd(std::move(undo_cmd)) {} + explicit cmd_t(std::string &&do_cmd) : do_cmd(std::move(do_cmd)) {} + std::string do_cmd; // Executed when proc_t has finished running, meant to reverse 'do_cmd' if applicable @@ -30,10 +33,10 @@ struct cmd_t { * filename -- The output of the commands are appended to filename */ struct ctx_t { - std::vector pre_cmds; + std::vector prep_cmds; std::string cmd; - std::string cmd_output; + std::string output; }; class proc_t {