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

Run an external command, with stdin/stdout/stderr as strings or as streams - like perl backticks. 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, Time::DurationSeconds timeout=Time::kInfinity)
 Run the command synchronously, returning its output, and THROW on any failure.
 
nonvirtual BackgroundProcess RunInBackground (const Streams::InputStream::Ptr< byte > &in=nullptr, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=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 an external command, with stdin/stdout/stderr as strings or as streams - like perl backticks.

There are two ways to run, and the difference is all you really need to know:

o   Run () is synchronous. It returns the output, and THROWS on any failure - including the
    process merely exiting non-zero. Nothing to check; if it returns, it worked.
o   RunInBackground () hands back a BackgroundProcess you wait on and interrogate - exit status,
    signal, child pid - so you can treat a failed run as data instead of as an exception.

Run () behaves as if it were RunInBackground (), then waiting, then ProcessResultType::ThrowIfFailed ().

Note
ProcessRunner searches the PATH for the given executable: it need not be a full or even relative to cwd path.
Example Usage - Run (), the simple case
String name = get<0> (ProcessRunner{"uname"}.Run (String {})).Trim ();
ProcessRunner pr{"echo hi mom"};
auto [stdOutStr, stdErrStr] = pr.Run (""); // throws if echo fails or exits non-zero
EXPECT_EQ (stdOutStr.Trim (), "hi mom");
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:1604
Run an external command, with stdin/stdout/stderr as strings or as streams - like perl backticks.
nonvirtual void Run(const Streams::InputStream::Ptr< byte > &in, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=nullptr, Time::DurationSeconds timeout=Time::kInfinity)
Run the command synchronously, returning its output, and THROW on any failure.
ProcessRunner()=delete
Construct ProcessRunner with a CommandLine to run (doesn't actually RUN til you call Run or RunInBack...
Example Usage - RunInBackground (), when the exit status is data rather than an error
// grep exits 1 for 'no match', which is an answer and not a failure
optional<ProcessRunner::ProcessResultType> r = bp.GetProcessResult ();
bool matched = r and r->fExitStatus == 0;
nonvirtual optional< ProcessResultType > GetProcessResult() const
nonvirtual void WaitForDone(Time::DurationSeconds timeout=Time::kInfinity) const
nonvirtual BackgroundProcess RunInBackground(const Streams::InputStream::Ptr< byte > &in=nullptr, const Streams::OutputStream::Ptr< byte > &out=nullptr, const Streams::OutputStream::Ptr< byte > &error=nullptr)
Run the given external command/process (set by constructor) - with the given arguments in the backgro...
Note
Historical note: the idea came from KDJ - do something like python/perl subprocess handling, as a simple portable wrapper.

Definition at line 132 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,
Time::DurationSeconds  timeout = Time::kInfinity 
)

Run the command synchronously, returning its output, and THROW on any failure.

o   STRING overload: pass stdin as a string, get back {stdout, stderr}. Run () with no
    argument means Run (""). The simplest form.
o   STREAMS overload: pass binary streams instead. Any of the three left nullptr is
    redirected to /dev/null.
Note
Exceptions - failure is ONLY reported by throwing ProcessRunner::Exception, whether that is something going wrong before the process starts, a non-zero exit (Exception::fExitStatus), or death by an uncaught signal (Exception::fTermSignal). The string overload also captures the child's stderr into Exception::fStderrFragment, usually the only thing that says WHY. To read an exit status instead of catching it, use RunInBackground ().
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_);
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:150
nonvirtual String ReadAll(size_t upTo=numeric_limits< size_t >::max()) const
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 
)

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.
if options.fDetached is true, as of Stroika v3.0d23, then we REQUIRE (in==nullptr, out==nullptr, and err==nullptr) and this means no data is written to the detached process, and no data is read from it.
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: