-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathprocess.h
181 lines (150 loc) · 5.45 KB
/
process.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
* @file src/process.h
* @brief Declarations for the startup and shutdown of the apps started by a streaming Session.
*/
#pragma once
#ifndef __kernel_entry
#define __kernel_entry
#endif
// standard includes
#include <optional>
#include <unordered_map>
// lib includes
#include <boost/process/v1.hpp>
// local includes
#include "config.h"
#include "platform/common.h"
#include "rtsp.h"
#include "utility.h"
namespace proc {
using file_t = util::safe_ptr_v2<FILE, int, fclose>;
typedef config::prep_cmd_t 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
* working_dir -- the process working directory. This is required for some games to run properly.
* cmd_output --
* empty -- The output of the commands are appended to the output of sunshine
* "null" -- The output of the commands are discarded
* filename -- The output of the commands are appended to filename
*/
struct ctx_t {
std::vector<cmd_t> prep_cmds;
/**
* Some applications, such as Steam, either exit quickly, or keep running indefinitely.
*
* Apps that launch normal child processes and terminate will be handled by the process
* grouping logic (wait_all). However, apps that launch child processes indirectly or
* into another process group (such as UWP apps) can only be handled by the auto-detach
* heuristic which catches processes that exit 0 very quickly, but we won't have proper
* process tracking for those.
*
* For cases where users just want to kick off a background process and never manage the
* lifetime of that process, they can use detached commands for that.
*/
std::vector<std::string> detached;
std::string name;
std::string cmd;
std::string working_dir;
std::string output;
std::string image_path;
std::string id;
bool elevated;
bool auto_detach;
bool wait_all;
std::chrono::seconds exit_timeout;
};
class proc_t {
public:
KITTY_DEFAULT_CONSTR_MOVE_THROW(proc_t)
proc_t(
boost::process::v1::environment &&env,
std::vector<ctx_t> &&apps
):
_app_id(0),
_env(std::move(env)),
_apps(std::move(apps)) {
}
int execute(int app_id, std::shared_ptr<rtsp_stream::launch_session_t> launch_session);
/**
* @return `_app_id` if a process is running, otherwise returns `0`
*/
int running();
~proc_t();
/**
* @brief Get the list of applications.
* @return A constant reference to the vector of applications.
*/
const std::vector<ctx_t>& get_apps() const;
/**
* @brief Set the list of applications.
* @param apps The new list of applications.
* @note This will overwrite the existing list of applications.
* @see refresh(const std::string &file_name)
*/
void set_apps(std::vector<ctx_t> apps);
/**
* @brief Get the image path of the application with the given app_id.
* @param app_id The ID of the application.
* @return The image path of the application.
*/
std::string get_app_image(int app_id);
/**
* @brief Get the name of the last run application.
* @return The name of the last run application.
*/
std::string get_last_run_app_name();
/**
* @brief Get the environment variables.
* @return A constant reference to the environment variables.
*/
const boost::process::v1::environment& get_env() const;
/**
* @brief Set the environment variables.
* @param env The new environment variables.
* @note This will overwrite the existing environment variables.
*/
void set_env(boost::process::v1::environment env);
/**
* @brief Terminate the currently running process.
*/
void terminate();
private:
int _app_id;
boost::process::v1::environment _env;
std::vector<ctx_t> _apps;
ctx_t _app;
std::chrono::steady_clock::time_point _app_launch_time;
// If no command associated with _app_id, yet it's still running
bool placebo {};
boost::process::v1::child _process;
boost::process::v1::group _process_group;
file_t _pipe;
std::vector<cmd_t>::const_iterator _app_prep_it;
std::vector<cmd_t>::const_iterator _app_prep_begin;
};
/**
* @brief Calculate a stable id based on name and image data
* @return Tuple of id calculated without index (for use if no collision) and one with.
*/
std::tuple<std::string, std::string> calculate_app_id(const std::string &app_name, std::string app_image_path, int index);
std::string validate_app_image_path(std::string app_image_path);
void refresh(const std::string &file_name);
std::optional<proc::proc_t> parse(const std::string &file_name);
/**
* @brief Initialize proc functions
* @return Unique pointer to `deinit_t` to manage cleanup
*/
std::unique_ptr<platf::deinit_t> init();
/**
* @brief Terminates all child processes in a process group.
* @param proc The child process itself.
* @param group The group of all children in the process tree.
* @param exit_timeout The timeout to wait for the process group to gracefully exit.
*/
void terminate_process_group(boost::process::v1::child &proc, boost::process::v1::group &group, std::chrono::seconds exit_timeout);
extern proc_t proc;
} // namespace proc