cross platform subprocess library for c++ similar to design of python subprocess. See subprocess documentation for further documentation.
supports
- very python like style of subprocess. With very nice syntax for c++20.
- Connect output of process A to input of process B. However not pretty API for this.
- Environment utilities to make it easy to get/set environment variables. as easy as
subprocess::cenv["MY_VAR"] = "value"
.
- subprocess::EnvGuard that will save the environment and reload it when scope block ends, making it easy to have a temporary environment. Obviously this is not thread safe as environment variable changes effects process wide.
- Get a copy of environment so you can modify a std::map as you please for use in a thread safe manner of environment and pass it along to subprocesses.
- cross-platform
find_program
- find_program has special handling of "python3" on windows making it easy to find python3 executable. It searches the path for python and inspects it's version so that
find_program("python3")
is cross-platform.
- Supports connecting process stdin, stdout, stderr to C++ streams making redirection convenient. stdin can be connected with a std::string too.
Shakey elements
- The os error level exceptions is still changing. I'm thinking of having an OSError subclass to abstract the OS differences.
requirements
- c++17
- linked with support for threading, filesystem
Integration
Adhoc
- copy files in src/cpp to your project.
- add the top folder as include.
- make sure cpp files are compiled.
- add
#include <subprocess.hpp>
to start using in source files.
<a href="https://bitbucket.org/benman/teaport">Teaport</a>
add this to your dependencies:
Todo add to cocoapods and perhaps others.
Examples
#include <thread>
#include <cstring>
void simple() {
RunBuilder().cout(PipeOption::pipe));
RunBuilder().cin("hello world\n"));
RunBuilder().cin("hello world").cout(PipeOption::pipe));
std::cout <<
"captured: " << process.
cout <<
'\n';
RunBuilder().cerr(PipeOption::pipe)
.cout(PipeOption::pipe)
.check(true)
);
std::cout <<
"cerr was: " << process.
cerr <<
"\n";
#if __cplusplus >= 202002L
.cout = PipeOption::pipe,
.check = false
});
std::cout <<
"captured: " << process.
cout <<
'\n';
#endif
}
void popen_examples() {
.
cout(PipeOption::pipe).popen();
char buf[1024] = {0};
std::cout << buf;
popen.close();
std::thread write_thread([&]() {
popen.close_cin();
});
for (auto& c : buf)
c = 0;
std::cout << buf;
popen.close();
if (write_thread.joinable())
write_thread.join();
}
int main(int argc, char** argv) {
std::cout << "running basic examples\n";
simple();
std::cout << "running popen_examples\n";
popen_examples();
return 0;
}
Deviations
- On windows terminating a process sends CTRL_BREAK_EVENT instead of hard termination. You can send a SIGKILL and it will do a hard termination as expected. Becareful as this may kill your process as it's sent to the process group. See send_signal for more details.
- cin, cout, cerr variable names are used instead of stdin, stdout, stderr as std* are macros and cannot be used as names in C++.
current progress
All tests pass on linux & mac. Most pass under mingw & MSVC.
Changelog
0.4.0
CTRL_BREAK_EVENT
is sent for SIGTERM & terminate() functions on windows.
- fixed invalid handles when launching a python script that then launches new processes.
- new
kIsWin32
constant to help avoid ifdef use.
- Documentation wording to be more confident as the library is looking pretty good, and I haven't felt like changing much of the API.
0.3.0
- fixed MSVC issues & compiles
- documentation should be complete. Please report any missing
0.2.0
- omg setting check=true is fixed. What a typo