Unravel Engine C++ Reference
Loading...
Searching...
No Matches
subprocess.hpp
Go to the documentation of this file.
1#pragma once
2#include "subprocess.h"
3#include <string>
4#include <cstring>
5#include <vector>
6
7namespace subprocess
8{
10{
11 int retcode{};
12 std::string out_output;
13 std::string err_output;
14};
15
16inline auto call(const std::vector<std::string>& args_array, const std::vector<std::string>& environment_array = {}) -> call_result
17{
18 call_result result;
19 result.retcode = 1;
20
21 std::vector<const char*> args;
22 std::vector<const char*> environment;
23 args.reserve(args_array.size());
24 for(const auto& arg : args_array)
25 {
26 args.emplace_back(arg.c_str());
27 }
28 args.emplace_back(nullptr);
29
30 environment.reserve(environment_array.size());
31 for(const auto& env : environment_array)
32 {
33 environment.emplace_back(env.c_str());
34 }
35 environment.emplace_back(nullptr);
36
37
38
40 std::memset(&subprocess, 0, sizeof(subprocess));
41 {
42 int options = /*subprocess_option_enable_async |*/ subprocess_option_inherit_environment |
44 int op_code = -1;
45
46 if(environment_array.empty())
47 {
48 op_code = subprocess_create(args.data(), options, &subprocess);
49 }
50 else
51 {
52 op_code = subprocess_create_ex(args.data(), options, environment.data(), &subprocess);
53 }
54
55 if(0 != op_code)
56 {
57 // an error occurred!
58 result.out_output = "Failed to create subprocess for " + args_array.front();
59 return result;
60 }
61 }
62
63 {
64 // Buffer for reading the output
65 char out_buffer[1024];
66 char err_buffer[1024];
67
68 auto read_all_stdout = [&]()
69 {
70 unsigned bytes_read;
71 while((bytes_read = subprocess_read_stdout(&subprocess, out_buffer, sizeof(out_buffer) - 1)) > 0)
72 {
73 out_buffer[bytes_read] = '\0'; // Null-terminate the buffer
74 result.out_output += out_buffer;
75 }
76 };
77
78 auto read_all_stderr = [&]()
79 {
80 unsigned bytes_read;
81 while((bytes_read = subprocess_read_stderr(&subprocess, err_buffer, sizeof(err_buffer) - 1)) > 0)
82 {
83 err_buffer[bytes_read] = '\0'; // Null-terminate the buffer
84 result.err_output += err_buffer;
85 }
86 };
87
88 // Read output from the process continuously
90 {
91 read_all_stdout();
92 read_all_stderr();
93 }
94
95 // Ensure all remaining output is drained after the process finishes
96 read_all_stdout();
97 read_all_stderr();
98 }
99
100 {
101 int op_code = subprocess_join(&subprocess, &result.retcode);
102 if(0 != op_code)
103 {
104 // an error occurred!
105 }
106 }
107
108 {
109 int op_code = subprocess_destroy(&subprocess);
110 if(0 != op_code)
111 {
112 // an error occurred!
113 }
114 }
115
116 return result;
117}
118
119inline auto call(const std::string& process, const std::vector<std::string>& args_array = {}) -> call_result
120{
121 std::vector<std::string> merged{process};
122 merged.insert(merged.end(), args_array.begin(), args_array.end());
123
124 return call(merged);
125}
126} // namespace subprocess
auto call(const std::vector< std::string > &args_array, const std::vector< std::string > &environment_array={}) -> call_result
@ environment
Environment reflection method.
subprocess_weak unsigned subprocess_read_stdout(struct subprocess_s *const process, char *const buffer, unsigned size)
Read the standard output from the child process.
@ subprocess_option_search_user_path
Definition subprocess.h:92
@ subprocess_option_inherit_environment
Definition subprocess.h:80
@ subprocess_option_combined_stdout_stderr
Definition subprocess.h:77
subprocess_weak int subprocess_join(struct subprocess_s *const process, int *const out_return_code)
Wait for a process to finish execution.
Definition subprocess.h:944
subprocess_weak unsigned subprocess_read_stderr(struct subprocess_s *const process, char *const buffer, unsigned size)
Read the standard error from the child process.
subprocess_weak int subprocess_destroy(struct subprocess_s *const process)
Destroy a previously created process.
subprocess_weak int subprocess_create(const char *const command_line[], int options, struct subprocess_s *const out_process)
Create a process.
Definition subprocess.h:484
subprocess_weak int subprocess_alive(struct subprocess_s *const process)
Returns if the subprocess is currently still alive and executing.
subprocess_weak int subprocess_create_ex(const char *const command_line[], int options, const char *const environment[], struct subprocess_s *const out_process)
Create a process (extended create).
Definition subprocess.h:490