1
1
#include " App.h"
2
2
3
+ #include < unistdpp/pipe.h>
4
+
3
5
#include < Device.h>
4
6
7
+ #include < algorithm>
5
8
#include < csignal>
6
9
#include < fstream>
7
10
#include < iostream>
8
11
12
+ #include < sys/wait.h>
9
13
#include < unistd.h>
10
14
11
15
using namespace rmlib ;
@@ -15,6 +19,7 @@ namespace {
15
19
pid_t
16
20
runCommand (std::string_view cmd) {
17
21
pid_t pid = fork ();
22
+
18
23
if (pid == -1 ) {
19
24
perror (" Error launching" );
20
25
return -1 ;
@@ -25,21 +30,28 @@ runCommand(std::string_view cmd) {
25
30
return pid;
26
31
}
27
32
28
- std::cout << " Running: " << cmd << std::endl;
29
33
setpgid (0 , 0 );
34
+
35
+ std::cout << " Running: " << cmd << std::endl;
30
36
execlp (" /bin/sh" , " /bin/sh" , " -c" , cmd.data (), nullptr );
31
37
perror (" Error running process" );
32
38
return -1 ;
33
39
}
34
40
35
- bool
36
- endsWith (std::string_view a, std::string_view end) {
37
- if (a.size () < end.size ()) {
38
- return false ;
41
+ void
42
+ stop (std::shared_ptr<AppRunInfo> runInfo) {
43
+ const auto pid = runInfo->pid ;
44
+
45
+ if (runInfo->paused ) {
46
+ kill (-pid, SIGCONT);
39
47
}
40
48
41
- return a.substr (a.size () - end.size ()) == end;
49
+ int res = kill (-pid, SIGTERM);
50
+ if (res != 0 ) {
51
+ perror (" Error killing!" );
52
+ }
42
53
}
54
+
43
55
} // namespace
44
56
45
57
std::optional<AppDescription>
@@ -76,17 +88,22 @@ AppDescription::read(std::string_view path, std::string_view iconDir) {
76
88
}
77
89
78
90
if (!result.icon .empty ()) {
79
- auto iconPath = std::string (iconDir) + ' /' + result.icon + " .png" ;
80
- std::cout << " Parsing image from: " << iconPath << std::endl;
81
- result.iconImage = ImageCanvas::load (iconPath.c_str ());
82
- if (result.iconImage .has_value ()) {
83
- std::cout << result.iconImage ->canvas .components () << std::endl;
84
- }
91
+ result.iconPath = std::string (iconDir) + ' /' + result.icon + " .png" ;
85
92
}
86
93
87
94
return std::optional (std::move (result));
88
95
}
89
96
97
+ std::optional<ImageCanvas>
98
+ AppDescription::getIcon () const {
99
+ std::cout << " Parsing image from: " << iconPath << std::endl;
100
+ auto iconImage = ImageCanvas::load (iconPath.c_str ());
101
+ if (iconImage.has_value ()) {
102
+ std::cout << iconImage->canvas .components () << std::endl;
103
+ }
104
+ return iconImage;
105
+ }
106
+
90
107
std::vector<AppDescription>
91
108
readAppFiles (std::string_view directory) {
92
109
const auto iconPath = std::string (directory) + " /icons" ;
@@ -95,11 +112,6 @@ readAppFiles(std::string_view directory) {
95
112
std::vector<AppDescription> result;
96
113
97
114
for (const auto & path : paths) {
98
- if (!endsWith (path, " .draft" )) {
99
- std::cerr << " skipping non draft file: " << path << std::endl;
100
- continue ;
101
- }
102
-
103
115
auto appDesc = AppDescription::read (path, iconPath);
104
116
if (!appDesc.has_value ()) {
105
117
std::cerr << " error parsing file: " << path << std::endl;
@@ -112,19 +124,30 @@ readAppFiles(std::string_view directory) {
112
124
return result;
113
125
}
114
126
127
+ void
128
+ App::updateDescription (AppDescription desc) {
129
+ mDescription = std::move (desc);
130
+ iconImage = mDescription .getIcon ();
131
+ }
132
+
115
133
bool
116
134
App::launch () {
117
- if (runInfo. has_value ()) {
135
+ if (isRunning ()) {
118
136
assert (false && " Shouldn't be called if the app is already running" );
119
137
return false ;
120
138
}
121
139
122
- auto pid = runCommand (description.command );
140
+ auto pid = runCommand (description () .command );
123
141
if (pid == -1 ) {
124
142
return false ;
125
143
}
126
144
127
- runInfo = AppRunInfo{ pid };
145
+ auto runInfo = std::make_shared<AppRunInfo>();
146
+ runInfo->pid = pid;
147
+
148
+ this ->runInfo = runInfo;
149
+
150
+ AppManager::getInstance ().runInfos .emplace_back (std::move (runInfo));
128
151
129
152
return true ;
130
153
}
@@ -133,19 +156,17 @@ void
133
156
App::stop () {
134
157
assert (isRunning ());
135
158
136
- if (isPaused ()) {
137
- kill (-runInfo->pid , SIGCONT);
138
- }
139
-
140
- kill (-runInfo->pid , SIGTERM);
159
+ ::stop (runInfo.lock());
141
160
}
142
161
143
162
void
144
163
App::pause (std::optional<MemoryCanvas> screen) {
145
164
assert (isRunning () && !isPaused ());
146
165
147
- kill (-runInfo->pid , SIGSTOP);
148
- runInfo->paused = true ;
166
+ auto lockedInfo = runInfo.lock ();
167
+
168
+ kill (-lockedInfo->pid , SIGSTOP);
169
+ lockedInfo->paused = true ;
149
170
savedFb = std::move (screen);
150
171
}
151
172
@@ -160,6 +181,59 @@ App::resume(rmlib::fb::FrameBuffer* fb) {
160
181
savedFb.reset ();
161
182
}
162
183
163
- kill (-runInfo->pid , SIGCONT);
164
- runInfo->paused = false ;
184
+ auto lockedInfo = runInfo.lock ();
185
+ kill (-lockedInfo->pid , SIGCONT);
186
+ lockedInfo->paused = false ;
187
+ }
188
+
189
+ AppManager&
190
+ AppManager::getInstance () {
191
+ static AppManager instance;
192
+ return instance;
193
+ }
194
+
195
+ bool
196
+ AppManager::update () {
197
+ bool anyKilled = false ;
198
+
199
+ while (auto res = pipe.readPipe .readAll <pid_t >()) {
200
+ auto pid = *res;
201
+ anyKilled = true ;
202
+
203
+ runInfos.erase (
204
+ std::remove_if (runInfos.begin (),
205
+ runInfos.end (),
206
+ [pid](auto & info) { return info->pid == pid; }),
207
+ runInfos.end ());
208
+ }
209
+
210
+ return anyKilled;
211
+ }
212
+
213
+ void
214
+ AppManager::onSigChild (int sig) {
215
+ auto & inst = AppManager::getInstance ();
216
+
217
+ pid_t childPid = 0 ;
218
+ while ((childPid = waitpid (static_cast <pid_t >(-1 ), nullptr , WNOHANG)) > 0 ) {
219
+
220
+ std::cout << " Killed: " << childPid << " \n " ;
221
+
222
+ auto v = inst.pipe .writePipe .writeAll (childPid);
223
+
224
+ if (!v.has_value ()) {
225
+ std::cerr << " Error in writing pid: " << to_string (v.error ()) << " \n " ;
226
+ }
227
+ }
228
+ }
229
+
230
+ AppManager::AppManager () : pipe(unistdpp::fatalOnError(unistdpp::pipe())) {
231
+ unistdpp::setNonBlocking (pipe.readPipe );
232
+ std::signal (SIGCHLD, onSigChild);
233
+ }
234
+
235
+ AppManager::~AppManager () {
236
+ for (auto runInfo : runInfos) {
237
+ ::stop (runInfo);
238
+ }
165
239
}
0 commit comments