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) -> call_result
17{
18 call_result result;
19 result.retcode = 1;
20
21 std::vector<const char*> args;
22
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
31 std::memset(&subprocess, 0, sizeof(subprocess));
32 {
33 int options = /*subprocess_option_enable_async |*/ subprocess_option_inherit_environment |
35 int op_code = subprocess_create(args.data(), options, &subprocess);
36 if(0 != op_code)
37 {
38 // an error occurred!
39 result.out_output = "Failed to create subprocess for " + args_array.front();
40 return result;
41 }
42 }
43
44 {
45 // Buffer for reading the output
46 char out_buffer[1024];
47 char err_buffer[1024];
48
49 auto read_all_stdout = [&]()
50 {
51 unsigned bytes_read;
52 while((bytes_read = subprocess_read_stdout(&subprocess, out_buffer, sizeof(out_buffer) - 1)) > 0)
53 {
54 out_buffer[bytes_read] = '\0'; // Null-terminate the buffer
55 result.out_output += out_buffer;
56 }
57 };
58
59 auto read_all_stderr = [&]()
60 {
61 unsigned bytes_read;
62 while((bytes_read = subprocess_read_stderr(&subprocess, err_buffer, sizeof(err_buffer) - 1)) > 0)
63 {
64 err_buffer[bytes_read] = '\0'; // Null-terminate the buffer
65 result.err_output += err_buffer;
66 }
67 };
68
69 // Read output from the process continuously
71 {
72 read_all_stdout();
73 read_all_stderr();
74 }
75
76 // Ensure all remaining output is drained after the process finishes
77 read_all_stdout();
78 read_all_stderr();
79 }
80
81 {
82 int op_code = subprocess_join(&subprocess, &result.retcode);
83 if(0 != op_code)
84 {
85 // an error occurred!
86 }
87 }
88
89 {
90 int op_code = subprocess_destroy(&subprocess);
91 if(0 != op_code)
92 {
93 // an error occurred!
94 }
95 }
96
97 return result;
98}
99
100inline auto call(const std::string& process, const std::vector<std::string>& args_array = {}) -> call_result
101{
102 std::vector<std::string> merged{process};
103 merged.insert(merged.end(), args_array.begin(), args_array.end());
104
105 return call(merged);
106}
107} // namespace subprocess
auto call(const std::vector< std::string > &args_array) -> call_result
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.