dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
Process.hpp
1// SPDX-FileCopyrightText: 2025 Vincent Leroy
2// SPDX-License-Identifier: MIT
3//
4// This file is part of dfx.
5//
6// Licensed under the MIT License. See the LICENSE file in the project root
7// for full license information.
8
9#pragma once
10
11// Standard includes
12#include <chrono>
13#include <cstdint>
14#include <functional>
15#include <optional>
16#include <string>
17#include <sys/types.h>
18#include <variant>
19#include <vector>
20
21// Project includes
23#include <dfx-fdwatch/PollerFd.hpp>
25#include <dfx-utilities/FileSystem.hpp>
27
28namespace dfx::FdWatch
29{
30class Poller;
31} // !namespace dfx::FdWatch
32
34{
59{
60 DFX_PRIVATE_STATE(Process, DFX_SUBPROCESS_LOGGER())
61
62public:
64 enum class StreamMode : std::uint8_t
65 {
71
77
83 };
84
86 enum class Which : std::uint8_t
87 {
91 };
92
94 enum class EnvMode : std::uint8_t
95 {
98 };
99
100public:
102 using NotificationCallback = std::move_only_function<void ()>;
103
106 using ReadCallback = std::move_only_function<void (std::string)>;
107
108public:
111 {
118 std::size_t maxSize = 1 * 1024 * 1024;
119 };
120
152
153public:
167
170 {
172 int err;
173 };
174
176 struct Exited
177 {
178 int code;
179 };
180
182 struct Signaled
183 {
184 int signal;
186 };
187
195 struct ExitStatus : public std::variant<std::monostate, SpawnError, Exited, Signaled>
196 {
197 using std::variant<std::monostate, SpawnError, Exited, Signaled>::variant;
198
200 bool isSet() const noexcept { return !std::holds_alternative<std::monostate>(*this); }
202 bool isSpawnError() const noexcept { return std::holds_alternative<SpawnError>(*this); }
204 bool isExited() const noexcept { return std::holds_alternative<Exited>(*this); }
206 bool isSignaled() const noexcept { return std::holds_alternative<Signaled>(*this); }
207
209 SpawnError const & toSpawnError() const { return std::get<SpawnError>(*this); }
211 Exited const & toExited() const { return std::get<Exited>(*this); }
213 Signaled const & toSignaled() const { return std::get<Signaled>(*this); }
214 };
215
216public:
218 static constexpr auto infinite = std::chrono::milliseconds(-1);
219
220public:
229
231 FdWatch::BorrowedFd pidfd() const noexcept;
233 pid_t pid() const noexcept;
235 bool isRunning() const noexcept;
237 Config const & config() const noexcept;
240 fs::path const & resolvedBinPath() const noexcept;
241
243 ExitStatus const & lastExitStatus() const noexcept;
244
245public:
250 std::string takeStdout() noexcept;
255 std::string takeStderr() noexcept;
256
257public:
262 void start();
263
271 void stop(std::chrono::milliseconds timeout = infinite);
272
279 void kill();
280
283 void sendSignal(int sig);
284
295 void write(std::string data, NotificationCallback onWriteFinishedCb = nullptr);
296
309 void registerReadCallback(Which stream, ReadCallback onReadyReadCb);
310
314
324 void close(Which stream) noexcept;
325
326public:
344 static fs::path resolveProgramPath(fs::path const & bin);
345
346public:
352 static pid_t forkWithPidfd(int & pidfd) noexcept;
359 static int pidfdSendSignal(int pidfd, int sig) noexcept;
360};
361} // !namespace dfx::Subprocess
362
Macro-based enum <-> string utilities for dfx.
#define DECLARE_ENUM_STRING_FUNCTIONS(E)
Declare the enum string API (and std::formatter) for enum type E.
Definition EnumString.hpp:327
Event interest and trigger flags for file-descriptor watching (Linux/epoll).
Macros to implement the Private State (PIMPL-like) idiom with value semantics.
#define DFX_PRIVATE_STATE(Class, logger)
Declare a private implementation state for a class.
Definition PrivateState.hpp:52
#define DFX_PRIVATE_STATE_DECLARE_RULE_OF_5(Class)
Declare Rule-of-5 special member functions using the private state pattern.
Definition PrivateState.hpp:82
Non-owning wrapper around a file descriptor.
Definition BorrowedFd.hpp:37
Abstract interface for FD-based event polling.
Definition Poller.hpp:37
StreamMode
How a standard stream of the child is wired.
Definition Process.hpp:65
@ Pipe
Stream is connected to a pipe between host and child.
Definition Process.hpp:82
@ Forward
Stream is inherited/forwarded; the host does not touch the child's fds.
Definition Process.hpp:70
@ Close
Stream is connected to /dev/null.
Definition Process.hpp:76
Which
Identifies which standard stream is being referred to.
Definition Process.hpp:87
@ Stdout
Child standard output.
Definition Process.hpp:89
@ Stdin
Child standard input.
Definition Process.hpp:88
@ Stderr
Child standard error.
Definition Process.hpp:90
pid_t pid() const noexcept
Return the child PID, or -1 if not started.
void start()
Spawn the child process and set up I/O as requested by Config.
EnvMode
How the provided environment list in Config is applied.
Definition Process.hpp:95
@ Replace
Replace the child's environment with Config::env entirely.
Definition Process.hpp:96
@ Merge
Merge Config::env into the current environment. Value provided in Config::env takes precedence.
Definition Process.hpp:97
void registerReadCallback(Which stream, ReadCallback onReadyReadCb)
Register a callback invoked when the given stream becomes readable.
void write(std::string data, NotificationCallback onWriteFinishedCb=nullptr)
Write data to the child's stdin when stdin is piped.
std::string takeStderr() noexcept
Retrieve and clear the captured stderr buffer.
void kill()
Forcefully terminate the process.
std::move_only_function< void(std::string)> ReadCallback
Callback invoked when data is available from a piped output stream.
Definition Process.hpp:106
static constexpr auto infinite
Convenience timeout value meaning "wait indefinitely".
Definition Process.hpp:218
static int pidfdSendSignal(int pidfd, int sig) noexcept
Send a signal to a process referred to by pidfd.
std::move_only_function< void()> NotificationCallback
Callback invoked for notifications (no arguments).
Definition Process.hpp:102
void sendSignal(int sig)
Send a signal to the child process.
ChildExecStage
Internal stage identifiers used to report where spawn/exec failed in the child. If the child cannot b...
Definition Process.hpp:157
@ DupStdout
Duplicating/redirecting stdout.
Definition Process.hpp:163
@ SigmaskUnblock
Unblocking signals before exec.
Definition Process.hpp:158
@ Execve
Executing the new program image.
Definition Process.hpp:165
@ SetParentDeathSignal
Setting the parent-death signal (if enabled).
Definition Process.hpp:159
@ ChangeWorkingDirectory
Applying Config::cwd.
Definition Process.hpp:161
@ CheckParentAlive
Verifying parent is still alive before continuing.
Definition Process.hpp:160
@ DupStdin
Duplicating/redirecting stdin.
Definition Process.hpp:162
@ DupStderr
Duplicating/redirecting stderr.
Definition Process.hpp:164
ExitStatus const & lastExitStatus() const noexcept
Get the most recent exit status.
Config const & config() const noexcept
Access the configuration used to spawn the process.
FdWatch::BorrowedFd pidfd() const noexcept
Return a borrowed pidfd for the child.
fs::path const & resolvedBinPath() const noexcept
Resolved program path used for exec (typically absolute).
static fs::path resolveProgramPath(fs::path const &bin)
Resolve an executable name against PATH.
void stop(std::chrono::milliseconds timeout=infinite)
Request the process to stop and wait up to the given timeout.
static pid_t forkWithPidfd(int &pidfd) noexcept
Fork and obtain a pidfd for the child.
bool isRunning() const noexcept
True if the child is currently running.
std::string takeStdout() noexcept
Retrieve and clear the captured stdout buffer.
void registerTerminationCallback(NotificationCallback onChildFinishedCb)
Register a callback invoked when the child terminates or a spawn error is observed.
Process(FdWatch::Poller &poller, Config config)
Construct a process manager bound to an event poller.
void close(Which stream) noexcept
Close the host side of the specified stream (when applicable).
Definition SocketClient.hpp:23
Definition Process.hpp:34
Definition Message.hpp:21
STL namespace.
Configuration for captured output buffering.
Definition Process.hpp:111
std::size_t maxSize
Maximum amount of captured data kept in memory for the corresponding stream.
Definition Process.hpp:118
Process spawn and I/O configuration.
Definition Process.hpp:123
std::optional< fs::path > cwd
Optional working directory for the child process.
Definition Process.hpp:132
StreamMode stderrMode
Child stderr wiring mode.
Definition Process.hpp:142
StreamMode stdoutMode
Child stdout wiring mode.
Definition Process.hpp:140
CaptureConfig stderrCaptureConfig
Capture behavior for stderr when stderrMode is StreamMode::Pipe.
Definition Process.hpp:147
StreamMode stdinMode
Child stdin wiring mode.
Definition Process.hpp:138
std::vector< std::string > env
Environment entries, in "KEY=VALUE" form.
Definition Process.hpp:129
fs::path bin
Program path (may be absolute or resolved via PATH; see resolveProgramPath()).
Definition Process.hpp:125
bool useParentDeathSignal
Whether to set a "parent death" signal for the child. PR_SET_PDEATHSIG(2const)
Definition Process.hpp:150
EnvMode envMode
Environment application mode.
Definition Process.hpp:135
std::vector< std::string > args
Arguments passed to the program (excluding argv[0]).
Definition Process.hpp:127
CaptureConfig stdoutCaptureConfig
Capture behavior for stdout when stdoutMode is StreamMode::Pipe.
Definition Process.hpp:145
Variant describing the last known termination state.
Definition Process.hpp:196
SpawnError const & toSpawnError() const
Access the SpawnError variant. Throws std::bad_variant_access if not that alternative.
Definition Process.hpp:209
bool isSet() const noexcept
True if a non-empty status is available.
Definition Process.hpp:200
bool isSignaled() const noexcept
True if the process was terminated by a signal.
Definition Process.hpp:206
bool isSpawnError() const noexcept
True if the child failed during spawn/exec.
Definition Process.hpp:202
Exited const & toExited() const
Access the Exited variant. Throws std::bad_variant_access if not that alternative.
Definition Process.hpp:211
Signaled const & toSignaled() const
Access the Signaled variant. Throws std::bad_variant_access if not that alternative.
Definition Process.hpp:213
bool isExited() const noexcept
True if the process exited normally.
Definition Process.hpp:204
Normal exit description.
Definition Process.hpp:177
int code
Exit code returned by the process.
Definition Process.hpp:178
Signal termination description.
Definition Process.hpp:183
bool coreDumped
Whether a core dump occurred.
Definition Process.hpp:185
int signal
Signal number that terminated the process.
Definition Process.hpp:184
Spawn failure description.
Definition Process.hpp:170
ChildExecStage stage
Stage at which the spawn failed.
Definition Process.hpp:171
int err
Error code (errno of the child at the failure point).
Definition Process.hpp:172