Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Execution::ProcessRunner Class Reference

Run the given command, and optionally support stdin/stdout/stderr as streams (either sync with Run, RunInBackground) More...

#include <ProcessRunner.h>

Classes

class  BackgroundProcess
 
class  Exception
 
struct  ProcessResultType
 
struct  StringOptions
 Run () options for mapping Strings - what code page converters to use. More...
 

Public Member Functions

 ProcessRunner ()=delete
 Construct ProcessRunner with a CommandLine to run (doesn't actually RUN til you call Run or RunInBackground).
 
nonvirtual void Run (const Streams::InputStream::Ptr< byte > &in, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=nullptr, ProgressMonitor::Updater progress=nullptr, Time::DurationSeconds timeout=Time::kInfinity)
 Run the given external command/process (set by constructor) - with the given arguments, and block until that completes and return the results.
 
nonvirtual BackgroundProcess RunInBackground (const Streams::InputStream::Ptr< byte > &in=nullptr, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=nullptr, ProgressMonitor::Updater progress=nullptr)
 Run the given external command/process (set by constructor) - with the given arguments in the background, and return a handle to the results.
 
Streams::InputStream::Ptr< byte > GetStdIn () const
 
Streams::OutputStream::Ptr< byte > GetStdOut () const
 
Streams::OutputStream::Ptr< byte > GetStdErr () const
 

Detailed Description

Run the given command, and optionally support stdin/stdout/stderr as streams (either sync with Run, RunInBackground)

Note
ProcessRunner searches the PATH for the given executable: it need not be a full or even relative to cwd path.
Historical Note: IDEA HERE IS FROM KDJ - Do something like python/perl stuff for managing subprocesses easily.

Look input stream, output stream(or streams - stdout/stderr) - and some kind of external process control so can say WIAT or Terminate.

Simple portable wrapper.

Could use simple singly threaded approach used in TypeNValue ReportDefinition::RunExternalProcess_ (const SDKString& cmdLine, const SDKString& currentDir, const BLOBs::BLOB& stdinBLOB, const ContentType& resultFormat, float timeout) except that code has the defect that when the input pipe is full, and there is nothing in the output pipes it busy waits. We COULD fix this by doing a select.

OR - as KDJ suggests - create 3 threads - one that just reads on stdout, one that just reads on stderr, and one that spits into stdin.

The caller of 'subprocess' then would just wait on each of the 3 subprocesses (or would implement the aforementioned looping over reads/writes/selects etc).

Example Usage
String name = get<0> (ProcessRunner{"uname"}.Run (String {})).Trim ();
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
Definition String.cpp:1592
Run the given command, and optionally support stdin/stdout/stderr as streams (either sync with Run,...
nonvirtual void Run(const Streams::InputStream::Ptr< byte > &in, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=nullptr, ProgressMonitor::Updater progress=nullptr, Time::DurationSeconds timeout=Time::kInfinity)
Run the given external command/process (set by constructor) - with the given arguments,...
Example Usage
ProcessRunner pr{"echo hi mom"};
auto [stdOutStr, stdErrStr] = pr.Run ("");
EXPECT_EQ (stdOutStr.Trim (), "hi mom");
EXPECT_EQ (stdErrStr, "");
Example Usage
ProcessRunner pr{"cat"};
Memory::BLOB kData_{ Memory::BLOB::FromRaw ("this is a test") };
Streams::MemoryStream::Ptr<byte> processStdIn = Streams::MemoryStream::New<byte> (kData_ );
Streams::MemoryStream::Ptr<byte> processStdOut = Streams::MemoryStream::New<byte> ();
pr.Run (processStdIn, processStdOut).ThrowIfFailed ();
EXPECT_EQ (processStdOut.ReadAll (), kData_);
static BLOB FromRaw(const T *s, const T *e)
Convert pointed to/referenced data to BLOB (treating the argument as raw bytes).
Definition BLOB.inl:145
nonvirtual String ReadAll(size_t upTo=numeric_limits< size_t >::max()) const

Definition at line 147 of file ProcessRunner.h.

Constructor & Destructor Documentation

◆ ProcessRunner()

Stroika::Foundation::Execution::ProcessRunner::ProcessRunner ( )
delete

Construct ProcessRunner with a CommandLine to run (doesn't actually RUN til you call Run or RunInBackground).

Note
overload with executable allows specifying an alternate executable to run, even though args[0] will be what is reported to that application (a somewhat common trick in unix-land).
overload with String commandLine: Simple commands are run directly, and strings with apparent shell-isms, like pipes and quotes etc, are run through kDefaultShell. This overload is handy, but easy to explicitly control shell used with CommandLine argument instead.

Member Function Documentation

◆ Run()

nonvirtual void Stroika::Foundation::Execution::ProcessRunner::Run ( const Streams::InputStream::Ptr< byte > &  in,
const Streams::OutputStream::Ptr< byte > &  out = nullptr,
const Streams::OutputStream::Ptr< byte > &  error = nullptr,
ProgressMonitor::Updater  progress = nullptr,
Time::DurationSeconds  timeout = Time::kInfinity 
)

Run the given external command/process (set by constructor) - with the given arguments, and block until that completes and return the results.

Run the given external command/process (set by constructor) - with the given arguments, and block until that completes and return the results.

Run STREAMS overload: This overload takes input/output/error binary streams

STDIN/STDOUT/STDERR:

  • If nullptr/not specified, will redirected to /dev/null

Run STRING overload: This is the simplest API. Just pass in a string, and get back a string (first one is stdout, second is stderr).

The cmdStdInValue is passed as stdin (stream) to the subprocess.

Run ()/0: Treat as Run("") - so stderr captured automatically and inserted into exception (and logged).

BOTH overloads will throw if there is any sort of error, including error exit from the process called. Use RunInBackground () to examine the results of the sub-process.

Note
Exceptions: A number of issues before the process is run will generate an exception. If the argument processResult is null, failure (non SUCCESS exit or signal termination) will trigger an exception, and otherwise the parameter *processResult will be filled in.
if this is called with a timeout, and it times out, the child is killed immediately upon timeout. To avoid this behavior, use RunInBackground
Example Usage (using strings in/out)
String name = get<0> (ProcessRunner{"uname"}.Run (String {})).Trim ();
Example Usage (using binary streams)
ProcessRunner pr{"cat"};
Memory::BLOB kData_{ Memory::BLOB::FromRaw ("this is a test") };
Streams::MemoryStream::Ptr<byte> processStdIn = Streams::MemoryStream::New<byte> (kData_);
Streams::MemoryStream::Ptr<byte> processStdOut = Streams::MemoryStream::New<byte> ();
pr.Run (processStdIn, processStdOut);
EXPECT_EQ (processStdOut.ReadAll (), kData_);
See also
RunInBackground

◆ RunInBackground()

nonvirtual BackgroundProcess Stroika::Foundation::Execution::ProcessRunner::RunInBackground ( const Streams::InputStream::Ptr< byte > &  in = nullptr,
const Streams::OutputStream::Ptr< byte > &  out = nullptr,
const Streams::OutputStream::Ptr< byte > &  error = nullptr,
ProgressMonitor::Updater  progress = nullptr 
)

Run the given external command/process (set by constructor) - with the given arguments in the background, and return a handle to the results.

This function is generally quick, and non-blocking - just creates a thread todo the work.

Note
it is perfectly legal to launch a subprocess, and not track it in any way, just ignoring (not saving) the BackgroundProcess object.
See also
Run

◆ GetStdIn()

Streams::InputStream::Ptr< byte > Stroika::Foundation::Execution::ProcessRunner::GetStdIn ( ) const

If empty, stdin will not be empty (redirected from /dev/null).

Otherwise, the stream will be 'read' by the ProcessRunner and 'fed' downstream to the running subprocess.

Definition at line 100 of file ProcessRunner.inl.

◆ GetStdOut()

Streams::OutputStream::Ptr< byte > Stroika::Foundation::Execution::ProcessRunner::GetStdOut ( ) const

If empty, stdout will not be captured (redirected to /dev/null)

Definition at line 110 of file ProcessRunner.inl.

◆ GetStdErr()

Streams::OutputStream::Ptr< byte > Stroika::Foundation::Execution::ProcessRunner::GetStdErr ( ) const

If empty, stderr will not be captured (redirected to /dev/null)

Definition at line 120 of file ProcessRunner.inl.


The documentation for this class was generated from the following files: