dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
dfx::Subprocess::Process Class Reference

Subprocess wrapper with optional stdio piping/capture and event-driven callbacks. More...

#include <dfx-subprocess/Process.hpp>

Classes

struct  CaptureConfig
 Configuration for captured output buffering. More...
struct  Config
 Process spawn and I/O configuration. More...
struct  Exited
 Normal exit description. More...
struct  ExitStatus
 Variant describing the last known termination state. More...
struct  Signaled
 Signal termination description. More...
struct  SpawnError
 Spawn failure description. More...

Public Types

enum class  StreamMode : std::uint8_t { Forward , Close , Pipe }
 How a standard stream of the child is wired. More...
enum class  Which : std::uint8_t { Stdin , Stdout , Stderr }
 Identifies which standard stream is being referred to. More...
enum class  EnvMode : std::uint8_t { Replace , Merge }
 How the provided environment list in Config is applied. More...
enum class  ChildExecStage : std::uint32_t {
  SigmaskUnblock , SetParentDeathSignal , CheckParentAlive , ChangeWorkingDirectory ,
  DupStdin , DupStdout , DupStderr , Execve
}
 Internal stage identifiers used to report where spawn/exec failed in the child. If the child cannot be set up or exec'd, SpawnError provides both the stage and errno. More...
using NotificationCallback = std::move_only_function<void ()>
 Callback invoked for notifications (no arguments).
using ReadCallback = std::move_only_function<void (std::string)>
 Callback invoked when data is available from a piped output stream.

Public Member Functions

 Process (FdWatch::Poller &poller, Config config)
 Construct a process manager bound to an event poller.
 DFX_PRIVATE_STATE_DECLARE_RULE_OF_5 (Process)
FdWatch::BorrowedFd pidfd () const noexcept
 Return a borrowed pidfd for the child.
pid_t pid () const noexcept
 Return the child PID, or -1 if not started.
bool isRunning () const noexcept
 True if the child is currently running.
Config const & config () const noexcept
 Access the configuration used to spawn the process.
fs::path const & resolvedBinPath () const noexcept
 Resolved program path used for exec (typically absolute).
ExitStatus const & lastExitStatus () const noexcept
 Get the most recent exit status.
std::string takeStdout () noexcept
 Retrieve and clear the captured stdout buffer.
std::string takeStderr () noexcept
 Retrieve and clear the captured stderr buffer.
void start ()
 Spawn the child process and set up I/O as requested by Config.
void stop (std::chrono::milliseconds timeout=infinite)
 Request the process to stop and wait up to the given timeout.
void kill ()
 Forcefully terminate the process.
void sendSignal (int sig)
 Send a signal to the child process.
void write (std::string data, NotificationCallback onWriteFinishedCb=nullptr)
 Write data to the child's stdin when stdin is piped.
void registerReadCallback (Which stream, ReadCallback onReadyReadCb)
 Register a callback invoked when the given stream becomes readable.
void registerTerminationCallback (NotificationCallback onChildFinishedCb)
 Register a callback invoked when the child terminates or a spawn error is observed.
void close (Which stream) noexcept
 Close the host side of the specified stream (when applicable).

Static Public Member Functions

static fs::path resolveProgramPath (fs::path const &bin)
 Resolve an executable name against PATH.
static pid_t forkWithPidfd (int &pidfd) noexcept
 Fork and obtain a pidfd for the child.
static int pidfdSendSignal (int pidfd, int sig) noexcept
 Send a signal to a process referred to by pidfd.

Static Public Attributes

static constexpr auto infinite = std::chrono::milliseconds(-1)
 Convenience timeout value meaning "wait indefinitely".

Detailed Description

Subprocess wrapper with optional stdio piping/capture and event-driven callbacks.

Process spawns and manages a child process described by a Config, and integrates with an external fd event loop via dfx::FdWatch::Poller.

It supports:

  • Selecting how stdin/stdout/stderr are handled (forwarded, closed to /dev/null, or piped).
  • Capturing stdout/stderr into internal buffers when piping is enabled.
  • Registering callbacks for readability (stdout/stderr), write completion, and termination.
  • Stopping a child gracefully with a timeout and escalating if needed.

Typical usage:

  • Create with a poller and a configuration.
  • Register read/termination callbacks (optional).
  • Call start().
  • Optionally write to stdin when stdin is piped.
  • Read captured output via callbacks and/or takeStdout() / takeStderr().
  • Stop/kill as needed.
Note
By design once a Process is created you cannot change its Config. If you need to then you have to do something like p = Process(poller, newConfig);

Member Typedef Documentation

◆ NotificationCallback

using dfx::Subprocess::Process::NotificationCallback = std::move_only_function<void ()>

Callback invoked for notifications (no arguments).

◆ ReadCallback

using dfx::Subprocess::Process::ReadCallback = std::move_only_function<void (std::string)>

Callback invoked when data is available from a piped output stream.

Parameters
dataNewly read chunk of data (not necessarily line-delimited).

Member Enumeration Documentation

◆ ChildExecStage

enum class dfx::Subprocess::Process::ChildExecStage : std::uint32_t
strong

Internal stage identifiers used to report where spawn/exec failed in the child. If the child cannot be set up or exec'd, SpawnError provides both the stage and errno.

Enumerator
SigmaskUnblock 

Unblocking signals before exec.

SetParentDeathSignal 

Setting the parent-death signal (if enabled).

CheckParentAlive 

Verifying parent is still alive before continuing.

ChangeWorkingDirectory 

Applying Config::cwd.

DupStdin 

Duplicating/redirecting stdin.

DupStdout 

Duplicating/redirecting stdout.

DupStderr 

Duplicating/redirecting stderr.

Execve 

Executing the new program image.

◆ EnvMode

enum class dfx::Subprocess::Process::EnvMode : std::uint8_t
strong

How the provided environment list in Config is applied.

Enumerator
Replace 

Replace the child's environment with Config::env entirely.

Merge 

Merge Config::env into the current environment. Value provided in Config::env takes precedence.

◆ StreamMode

enum class dfx::Subprocess::Process::StreamMode : std::uint8_t
strong

How a standard stream of the child is wired.

Enumerator
Forward 

Stream is inherited/forwarded; the host does not touch the child's fds.

  • stdin, input is read from the parent’s stdin.
  • stdout/stderr, output goes to the parent’s stdout/stderr.
Close 

Stream is connected to /dev/null.

  • stdin: immediate EOF to the child.
  • stdout/stderr: discards all output.
Pipe 

Stream is connected to a pipe between host and child.

  • stdin: host can write into the child’s stdin.
  • stdout/stderr: host can read from the child’s output.

◆ Which

enum class dfx::Subprocess::Process::Which : std::uint8_t
strong

Identifies which standard stream is being referred to.

Enumerator
Stdin 

Child standard input.

Stdout 

Child standard output.

Stderr 

Child standard error.

Constructor & Destructor Documentation

◆ Process()

dfx::Subprocess::Process::Process ( FdWatch::Poller & poller,
Config config )

Construct a process manager bound to an event poller.

Parameters
pollerPoller used to watch internal fds (pipes/pidfd) and dispatch callbacks.
configSpawn configuration.
Note
The process is not started automatically; call start().

Member Function Documentation

◆ close()

void dfx::Subprocess::Process::close ( Which stream)
noexcept

Close the host side of the specified stream (when applicable).

Parameters
streamStream to close.
  • Closing stdin signals EOF to the child.
  • Closing stdout/stderr stops further reads on the host side.

This operation only make sense if the associated stream is in StreamMode::Pipe mode If not then this operation is a no-op.

◆ config()

Config const & dfx::Subprocess::Process::config ( ) const
noexcept

Access the configuration used to spawn the process.

◆ forkWithPidfd()

pid_t dfx::Subprocess::Process::forkWithPidfd ( int & pidfd)
staticnoexcept

Fork and obtain a pidfd for the child.

Parameters
[out]pidfdOn success, receives a pidfd referring to the child.
Returns
In the parent: child's PID; in the child: 0; on error: -1 (typical fork semantics).

◆ isRunning()

bool dfx::Subprocess::Process::isRunning ( ) const
noexcept

True if the child is currently running.

◆ kill()

void dfx::Subprocess::Process::kill ( )

Forcefully terminate the process.

A SIGKILL signal is immediately sent to the process which is then immediately waited for. Meaning that after this call isRunning() returns false. Calling kill on a non-running child is a no-op.

◆ lastExitStatus()

ExitStatus const & dfx::Subprocess::Process::lastExitStatus ( ) const
noexcept

Get the most recent exit status.

◆ pid()

pid_t dfx::Subprocess::Process::pid ( ) const
noexcept

Return the child PID, or -1 if not started.

◆ pidfd()

FdWatch::BorrowedFd dfx::Subprocess::Process::pidfd ( ) const
noexcept

Return a borrowed pidfd for the child.

◆ pidfdSendSignal()

int dfx::Subprocess::Process::pidfdSendSignal ( int pidfd,
int sig )
staticnoexcept

Send a signal to a process referred to by pidfd.

Parameters
pidfdProcess file descriptor.
sigSignal number.
Returns
0 on success or -1 on error (typical errno-style API).

◆ registerReadCallback()

void dfx::Subprocess::Process::registerReadCallback ( Which stream,
ReadCallback onReadyReadCb )

Register a callback invoked when the given stream becomes readable.

Parameters
streamStream to observe (Which::Stdout or Which::Stderr).
onReadyReadCbCallback receiving newly read chunks of data. Can be nullptr.

This function will throw an exception if the specified stream is Which::Stdin.

If this function is called while the child is running and the previous callback was nullptr, then all accumulated until now will be passed to the callback in accordance with the CaptureConfig::maxSize

Note
Stream must be configured as StreamMode::Pipe for readability notifications.

◆ registerTerminationCallback()

void dfx::Subprocess::Process::registerTerminationCallback ( NotificationCallback onChildFinishedCb)

Register a callback invoked when the child terminates or a spawn error is observed.

Parameters
onChildFinishedCbCallback invoked once termination is detected. Can be nullptr.

◆ resolvedBinPath()

fs::path const & dfx::Subprocess::Process::resolvedBinPath ( ) const
noexcept

Resolved program path used for exec (typically absolute).

See also
resolveProgramPath()

◆ resolveProgramPath()

fs::path dfx::Subprocess::Process::resolveProgramPath ( fs::path const & bin)
static

Resolve an executable name against PATH.

Parameters
binProgram name or path.
Returns
  • If bin contains a '/' character, returns bin unchanged (no existence/permission checks).
  • Otherwise, searches the current PATH (as returned by getPath()) for an executable regular file named bin and returns the first match.
  • If no match is found, returns an empty path ({ }).

PATH is split on ':'; per POSIX, an empty PATH element is treated as the current directory ("./").

A candidate is accepted only if:

  • faccessat(..., X_OK, AT_EACCESS) succeeds, and
  • stat() succeeds and indicates a regular file (S_ISREG).
Note
This function does not resolve symlinks or canonicalize paths; it returns the path as constructed.

◆ sendSignal()

void dfx::Subprocess::Process::sendSignal ( int sig)

Send a signal to the child process.

Parameters
sigSignal number (e.g., SIGTERM, SIGINT).

◆ start()

void dfx::Subprocess::Process::start ( )

Spawn the child process and set up I/O as requested by Config.

Note
Spawn failures happening in the child prior to exec are reported via lastExitStatus() as SpawnError.

◆ stop()

void dfx::Subprocess::Process::stop ( std::chrono::milliseconds timeout = infinite)

Request the process to stop and wait up to the given timeout.

Parameters
timeoutMaximum time to wait. Use infinite to wait indefinitely.

A SIGTERM signal is sent to the child. If after timeout the child still hasn't stop, then kill() is called. Calling stop on a non-running child is a no-op.

◆ takeStderr()

std::string dfx::Subprocess::Process::takeStderr ( )
noexcept

Retrieve and clear the captured stderr buffer.

Meaningful only when Config::stderrMode is StreamMode::Pipe and no read callback is registered. If stderr is not being captured, this returns an empty string.

◆ takeStdout()

std::string dfx::Subprocess::Process::takeStdout ( )
noexcept

Retrieve and clear the captured stdout buffer.

Meaningful only when Config::stdoutMode is StreamMode::Pipe and no read callback is registered. If stdout is not being captured, this returns an empty string.

◆ write()

void dfx::Subprocess::Process::write ( std::string data,
NotificationCallback onWriteFinishedCb = nullptr )

Write data to the child's stdin when stdin is piped.

Parameters
dataData to write (moved into internal buffers as needed).
onWriteFinishedCbOptional callback invoked once the write has completed.

It is perfectly valid to call this function before start(). In this case the data is buffered and will be sent as soon as the child is ready to receive them.

If Config::stdinMode is not StreamMode::Pipe, this function will throw an exception.

Member Data Documentation

◆ infinite

auto dfx::Subprocess::Process::infinite = std::chrono::milliseconds(-1)
staticconstexpr

Convenience timeout value meaning "wait indefinitely".


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