forked from flightlessmango/MangoHud
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.cpp
More file actions
96 lines (78 loc) · 2.46 KB
/
Copy pathshell.cpp
File metadata and controls
96 lines (78 loc) · 2.46 KB
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
#include "shell.h"
#include <thread>
#include <iostream>
#include <sys/wait.h>
#include <spdlog/spdlog.h>
#include "string_utils.h"
#include <array>
std::string Shell::readOutput() {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::array<char, 128> buffer;
std::string result;
ssize_t count;
while ((count = ::read(from_shell[0], buffer.data(), buffer.size())) > 0) {
result.append(buffer.data(), count);
}
// Split the result into lines and return the last line
std::istringstream stream(result);
std::string line;
std::string last_line;
while (std::getline(stream, line)) {
last_line = line;
}
SPDLOG_DEBUG("Shell: recieved output: {}", last_line);
return last_line;
}
Shell::Shell() {
if (stat("/run/pressure-vessel", &stat_buffer) == 0)
runtime = true;
static bool failed;
if (pipe(to_shell) == -1) {
SPDLOG_ERROR("Failed to create to_shell pipe: {}", strerror(errno));
failed = true;
}
if (pipe(from_shell) == -1) {
SPDLOG_ERROR("Failed to create from_shell pipe: {}", strerror(errno));
failed = true;
}
// if either pipe fails, there's no point in continuing.
if (failed){
SPDLOG_ERROR("Shell has failed, will not be able to use exec");
return;
}
shell_pid = fork();
if (shell_pid == 0) { // Child process
close(to_shell[1]);
close(from_shell[0]);
dup2(to_shell[0], STDIN_FILENO);
dup2(from_shell[1], STDOUT_FILENO);
dup2(from_shell[1], STDERR_FILENO);
execl("/bin/sh", "sh", "-c", "unset LD_PRELOAD; exec /bin/sh", nullptr);
exit(1); // Exit if execl fails
} else {
close(to_shell[0]);
close(from_shell[1]);
// Set the read end of the from_shell pipe to non-blocking
setNonBlocking(from_shell[0]);
}
success = true;
}
std::string Shell::exec(std::string cmd) {
if (!success)
return "";
writeCommand(cmd);
return readOutput();
}
void Shell::writeCommand(std::string command) {
if (write(to_shell[1], command.c_str(), command.length()) == -1)
SPDLOG_ERROR("Failed to write to shell");
if (runtime)
command = "steam-runtime-launch-client --alongside-steam --host -- " + command;
trim(command);
SPDLOG_DEBUG("Shell: wrote command: {}", command);
}
Shell::~Shell() {
close(to_shell[1]);
close(from_shell[0]);
waitpid(shell_pid, nullptr, 0);
}