-
Notifications
You must be signed in to change notification settings - Fork 0
/
CommandExecutor.cpp
70 lines (58 loc) · 1.99 KB
/
CommandExecutor.cpp
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
//
// CommandExecutor.cpp
// ncc
//
// Created by yuki on 2022/04/21.
//
#include "CommandExecutor.hpp"
#include <iterator>
#include <iostream>
#include <chrono>
#include <thread>
auto CommandExecutor::shared() -> shared_ptr<CommandExecutor> {
static auto shared_instance = make_shared<CommandExecutor>(false);
return shared_instance;
}
auto CommandExecutor::silent() -> shared_ptr<CommandExecutor> {
static auto shared_instance = make_shared<CommandExecutor>(true);
return shared_instance;
}
auto CommandExecutor::execute(const string command, const vector<string> arguments) const -> shared_ptr<CommandResult> {
const auto commandline = this->build_commandline(command, arguments);
auto exit_code = -1;
auto pipe = shared_ptr<FILE>(popen(commandline.data(), "r"), [&exit_code](auto _) {
exit_code = pclose(_);
});
if (!pipe) throw CommandError::childNotCreated();
auto std_output = this->read_pipe(pipe);
pipe.reset();
if (exit_code > 0) {
return CommandResult::failure(std_output, exit_code);
} else {
return CommandResult::success(std_output);
}
}
auto CommandExecutor::read_pipe(const shared_ptr<FILE> pipe) const -> string {
auto output = ""s;
array<char, 256> buf;
while (!feof(pipe.get())) if (fgets(buf.data(), buf.size(), pipe.get())) {
if (!disable_stdout) cout << buf.data();
output += buf.data();
}
return output;
}
auto CommandExecutor::build_commandline(const string command, const vector<string> arguments) const -> string {
auto args = vector<string>();
args.push_back(command);
args.insert(args.end(), arguments.begin(), arguments.end());
auto os = ostringstream();
copy(args.begin(), args.end(), ostream_iterator<string>(os, " "));
string command_line;
for (auto s: args) {
command_line += "\"";
command_line += s;
command_line += "\" ";
}
command_line += " 2>&1";
return command_line;
}