Stroika Library 3.0d25
 
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 (const filesystem::path &executable, const CommandLine &args, const Options &o={})
 Construct ProcessRunner with a CommandLine to run (doesn't actually RUN til you call Run or RunInBackground).
 
 ProcessRunner (const CommandLine &args, const Options &o={})
 Run args, whose args[0] is the executable.
 
 ProcessRunner (const String &commandLine, const Options &o={})
 Run directly if simple, else through kDefaultShell.
 
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:1651
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.
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 ( const filesystem::path &  executable,
const CommandLine &  args,
const Options &  o = {} 
)

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.

Definition at line 41 of file ProcessRunner.inl.

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: