🟩 Create child processes and chain them (also usable with Async library)
Process allows launching, chaining input and output, setting working directory and environment variables of child processes.
Features
Class | Description |
SC::Process | Execute a child process with standard file descriptors redirection. |
SC::ProcessChain | Execute multiple child processes chaining input / output between them. |
SC::ProcessEnvironment | Reads current process environment variables. |
Status
🟩 Usable
Library is being used in SC::Plugin and in SC::Tools.
Description
The SC::Process class is used when handling a process in isolation, while the SC::ProcessChain is used when there is need to chain inputs and outputs of multiple processes together.
Videos
This is the list of videos that have been recorded showing some of the internal thoughts that have been going into this library:
Blog
Some relevant blog posts are:
Process
Execute a child process with standard file descriptors redirection.
Features:
- Redirect standard in/out/err of a child process to a Pipe
- Inherit child process file descriptors from parent process
- Ignore (silence) child process standard file descriptor
- Wait for the child process exit code
Example: execute child process (launch and wait for it to fully execute)
SC_TRY(Process().exec({
"cmd.exe",
"-h"}));
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition: Result.h:48
Example: execute child process, redirecting stdout to a string
SmallString<256> output;
SC_TRY(Process().exec({
"where.exe",
"winver"}, output));
Example: launch a child process and wait for it to finish execution
Process process;
SC_TRY(process.launch({
"ls",
"-l"}));
SC_TRY(process.waitForExitSync());
Example: execute child process, filling its stdin with a StringView
SC_TRY(Process().exec({
"grep",
"process"}, Process::StdOut::Inherit(),
"child proc"));
Example: read process output using a pipe, using launch + waitForExitSync
Process process;
PipeDescriptor outputPipe;
SC_TRY(process.launch({
"executable.exe",
"--argument1",
"--argument2"}, outputPipe));
String output = StringEncoding::Ascii;
SC_TRY(outputPipe.readPipe.readUntilEOF(output));
SC_TRY(process.waitForExitSync());
Example: Add an environment variable
Process process;
String output;
#define SC_TEST_EXPECT(e)
Records a test expectation (eventually aborting or breaking o n failed test)
Definition: Testing.h:113
Example: Redefine an environment variable
Process process;
SC_TEST_EXPECT(process.setEnvironment(
"PATH",
"/usr/sane_cpp_binaries"));
String output;
SC_TEST_EXPECT(output.view().containsString(
"PATH=/usr/sane_cpp_binaries"));
Example: Disable environment variable inheritance
Process process;
process.inheritParentEnvironmentVariables(false);
String output;
ProcessChain
Execute multiple child processes chaining input / output between them.
Chains multiple child processes together, so that the output of a process becomes input of another (similar to what happens wit the pipe (|
) operator on Posix shells).
SC::PipeDescriptor from File library is used to chain read / write endpoints of different processes together.
Example: Inherit stdout file descriptor
ProcessChain chain;
Process p1, p2;
StringView expectedOutput;
switch (HostPlatform)
{
case Platform::Windows: {
expectedOutput = "Doctori\r\n";
SC_TEST_EXPECT(chain.pipe(p1, {
"cmd",
"/C",
"echo",
"Salve",
"&",
"echo",
"Doctori"}));
}
break;
default: {
expectedOutput = "Doctori\n";
}
break;
}
String output;
Example: Read stderr and stdout into a string
ProcessChain chain;
Process p1;
StringView expectedOutput;
switch (HostPlatform)
{
case Platform::Windows: {
expectedOutput = "C:\\Windows\\System32\\where.exe\r\n";
}
break;
default: {
expectedOutput = "DOCTORI\n";
}
break;
}
String stdOut(StringEncoding::Ascii);
String stdErr(StringEncoding::Ascii);
SC_TEST_EXPECT(chain.exec(stdOut, Process::StdIn::Inherit(), stdErr));
Example: Read standard output into a string using a Pipe
ProcessChain chain;
String output(StringEncoding::Ascii);
Process p1, p2;
StringView expectedOutput;
switch (HostPlatform)
{
case Platform::Windows: {
expectedOutput = "WHERE [/R dir] [/Q] [/F] [/T] pattern...\r\n";
}
break;
default: {
expectedOutput = "sbin\n";
}
break;
}
PipeDescriptor outputPipe;
ProcessEnvironment
Reads current process environment variables. Example: Print all environment variables to stdout
for (
size_t idx = 0; idx < environment.
size(); ++idx)
{
StringView name, value;
(void)environment.
get(idx, name, value);
if (value.isEmpty())
{
report.console.printLine(name);
}
else
{
report.console.print(name);
report.console.print("=");
report.console.printLine(value);
}
}
Reads current process environment variables.
Definition: Process.h:329
bool get(size_t index, StringView &name, StringView &value) const
Get the environmnent variable at given index, returning its name and value.
size_t size() const
Returns the total number of environment variables for current process.
Definition: Process.h:339
Roadmap
🟦 Complete Features:
💡 Unplanned Features: