mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-02-28 22:13:29 +00:00
Support Environment variables inside apps
This commit is contained in:
parent
2e7d621e12
commit
f499d25853
@ -3,20 +3,13 @@
|
|||||||
{
|
{
|
||||||
"DISPLAY":":0",
|
"DISPLAY":":0",
|
||||||
"DRI_PRIME":"1",
|
"DRI_PRIME":"1",
|
||||||
"XAUTHORITY":"/home/loki/.Xauthority"
|
"XAUTHORITY":"$(HOME)/.Xauthority",
|
||||||
|
"PATH":"$(PATH):$(HOME)/.local/bin"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"apps":[
|
"apps":[
|
||||||
{
|
|
||||||
"name":"Low Res Desktop 2",
|
|
||||||
"cmd":"sh -c \"while true; do sleep 10000; done;\"",
|
|
||||||
"prep-cmd":[
|
|
||||||
{ "do":"xrandr --output HDMI-1 --mode 1920x1080", "undo":"xrandr --output HDMI-1 --mode 1920x1200" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name":"Low Res Desktop",
|
"name":"Low Res Desktop",
|
||||||
"cmd":"sh -c \"while true; do sleep 10000; done;\"",
|
|
||||||
"prep-cmd":[
|
"prep-cmd":[
|
||||||
{ "do":"xrandr --output HDMI-1 --mode 1920x1080", "undo":"xrandr --output HDMI-1 --mode 1920x1200" }
|
{ "do":"xrandr --output HDMI-1 --mode 1920x1080", "undo":"xrandr --output HDMI-1 --mode 1920x1200" }
|
||||||
]
|
]
|
||||||
@ -26,9 +19,7 @@
|
|||||||
|
|
||||||
"output":"steam.txt",
|
"output":"steam.txt",
|
||||||
"cmd":"steam -bigpicture",
|
"cmd":"steam -bigpicture",
|
||||||
"prep-cmd":[
|
"prep-cmd":[]
|
||||||
{ "do":"sh -c \"PATH=$PATH:$HOME/.local/bin sudo freeHugePages\""},
|
|
||||||
{ "do":"sh -c \"PATH=$PATH:$HOME/.local/bin sudo claim_amdgpu\"" }]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if(argc > 1) {
|
if(argc > 1) {
|
||||||
if(!std::filesystem::exists(argv[1])) {
|
if(!std::filesystem::exists(argv[1])) {
|
||||||
|
@ -153,6 +153,66 @@ proc_t::~proc_t() {
|
|||||||
_undo_pre_cmd();
|
_undo_pre_cmd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view::iterator find_match(std::string_view::iterator begin, std::string_view::iterator end) {
|
||||||
|
int stack = 0;
|
||||||
|
|
||||||
|
--begin;
|
||||||
|
do {
|
||||||
|
++begin;
|
||||||
|
switch(*begin) {
|
||||||
|
case '(': ++stack;
|
||||||
|
break;
|
||||||
|
case ')': --stack;
|
||||||
|
}
|
||||||
|
} while(begin != end && stack != 0);
|
||||||
|
|
||||||
|
if(begin == end) {
|
||||||
|
throw std::out_of_range("Missing closing bracket \')\'");
|
||||||
|
}
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parse_env_val(bp::native_environment &env, const std::string_view &val_raw) {
|
||||||
|
auto pos = std::begin(val_raw);
|
||||||
|
auto dollar = std::find(pos, std::end(val_raw), '$');
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
while(dollar != std::end(val_raw)) {
|
||||||
|
auto next = dollar + 1;
|
||||||
|
if(next != std::end(val_raw)) {
|
||||||
|
switch(*next) {
|
||||||
|
case '(': {
|
||||||
|
ss.write(pos, (dollar - pos));
|
||||||
|
auto var_begin = next + 1;
|
||||||
|
auto var_end = find_match(next, std::end(val_raw));
|
||||||
|
|
||||||
|
ss << env[std::string { var_begin, var_end }].to_string();
|
||||||
|
|
||||||
|
pos = var_end + 1;
|
||||||
|
next = var_end;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '$':
|
||||||
|
ss.write(pos, (next - pos));
|
||||||
|
pos = next + 1;
|
||||||
|
++next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dollar = std::find(next, std::end(val_raw), '$');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dollar = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ss.write(pos, (dollar - pos));
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<proc::proc_t> parse(const std::string& file_name) {
|
std::optional<proc::proc_t> parse(const std::string& file_name) {
|
||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
|
|
||||||
@ -162,25 +222,25 @@ std::optional<proc::proc_t> parse(const std::string& file_name) {
|
|||||||
auto &apps_node = tree.get_child("apps"s);
|
auto &apps_node = tree.get_child("apps"s);
|
||||||
auto &env_vars = tree.get_child("env"s);
|
auto &env_vars = tree.get_child("env"s);
|
||||||
|
|
||||||
boost::process::environment env = boost::this_process::environment();
|
auto this_env = boost::this_process::environment();
|
||||||
|
|
||||||
std::unordered_map<std::string, proc::ctx_t> apps;
|
std::unordered_map<std::string, proc::ctx_t> apps;
|
||||||
for(auto &[_,app_node] : apps_node) {
|
for(auto &[_,app_node] : apps_node) {
|
||||||
proc::ctx_t ctx;
|
proc::ctx_t ctx;
|
||||||
|
|
||||||
auto &prep_nodes = app_node.get_child("prep-cmd"s);
|
auto &prep_nodes = app_node.get_child("prep-cmd"s);
|
||||||
auto name = app_node.get<std::string>("name"s);
|
|
||||||
auto output = app_node.get_optional<std::string>("output"s);
|
auto output = app_node.get_optional<std::string>("output"s);
|
||||||
auto cmd = app_node.get<std::string>("cmd"s);
|
auto name = parse_env_val(this_env, app_node.get<std::string>("name"s));
|
||||||
|
auto cmd = app_node.get_optional<std::string>("cmd"s);
|
||||||
|
|
||||||
std::vector<proc::cmd_t> prep_cmds;
|
std::vector<proc::cmd_t> prep_cmds;
|
||||||
prep_cmds.reserve(prep_nodes.size());
|
prep_cmds.reserve(prep_nodes.size());
|
||||||
for(auto &[_, prep_node] : prep_nodes) {
|
for(auto &[_, prep_node] : prep_nodes) {
|
||||||
auto do_cmd = prep_node.get<std::string>("do"s);
|
auto do_cmd = parse_env_val(this_env, prep_node.get<std::string>("do"s));
|
||||||
auto undo_cmd = prep_node.get_optional<std::string>("undo"s);
|
auto undo_cmd = prep_node.get_optional<std::string>("undo"s);
|
||||||
|
|
||||||
if(undo_cmd) {
|
if(undo_cmd) {
|
||||||
prep_cmds.emplace_back(std::move(do_cmd), std::move(*undo_cmd));
|
prep_cmds.emplace_back(std::move(do_cmd), parse_env_val(this_env, *undo_cmd));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prep_cmds.emplace_back(std::move(do_cmd));
|
prep_cmds.emplace_back(std::move(do_cmd));
|
||||||
@ -188,22 +248,30 @@ std::optional<proc::proc_t> parse(const std::string& file_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(output) {
|
if(output) {
|
||||||
ctx.output = std::move(*output);
|
ctx.output = parse_env_val(this_env, *output);
|
||||||
}
|
}
|
||||||
ctx.cmd = std::move(cmd);
|
|
||||||
|
if(cmd) {
|
||||||
|
ctx.cmd = parse_env_val(this_env, *cmd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctx.cmd = "sh -c \"while true; do sleep 10000; done;\"";
|
||||||
|
}
|
||||||
|
|
||||||
ctx.prep_cmds = std::move(prep_cmds);
|
ctx.prep_cmds = std::move(prep_cmds);
|
||||||
|
|
||||||
apps.emplace(std::move(name), std::move(ctx));
|
apps.emplace(std::move(name), std::move(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bp::environment env = boost::this_process::environment();
|
||||||
for(auto &[_,env_var] : env_vars) {
|
for(auto &[_,env_var] : env_vars) {
|
||||||
for(auto &[name,val] : env_var) {
|
for(auto &[name,val] : env_var) {
|
||||||
env[name] = val.get_value<std::string>();
|
this_env[name] = parse_env_val(this_env, val.get_value<std::string>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return proc::proc_t {
|
return proc::proc_t {
|
||||||
std::move(env), std::move(apps)
|
std::move(this_env), std::move(apps)
|
||||||
};
|
};
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user