aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-20 10:59:41 +0200
committerGitHub Enterprise <[email protected]>2026-04-20 10:59:41 +0200
commit38abebcb6ff417faf431dcaa103bb7f173c4b3f7 (patch)
treee03a6f63dafc3e75361f6312621c2699aebbc439 /src/zencore/include
parentzenhttp: add FollowRedirects option to HttpClient (#982) (diff)
downloadarchived-zen-38abebcb6ff417faf431dcaa103bb7f173c4b3f7.tar.xz
archived-zen-38abebcb6ff417faf431dcaa103bb7f173c4b3f7.zip
zencore: CreateProc stdin pipes + BuildArgV quote stripping (#983)
Two related improvements to `CreateProc`: ### 1. Stdin pipe support - Adds `StdinPipeHandles` + `CreateStdinPipe` alongside the existing `StdoutPipeHandles`, letting callers feed data into a child process's stdin. - Platform-agnostic RAII (Windows `HANDLE` pair / POSIX `pipe()` fd pair) with the same semantics as the stdout pipe: the inherited end goes to the child, the non-inherited end stays with the parent, destructor closes both. - `CreateProcOptions` gains a `StdinPipe*` field. - On Windows, `CreateProcNormal` is reworked so stdin/stdout redirection handles all combinations (stdin + stdout, each alone, neither) uniformly. POSIX already supported arbitrary fd redirection and just needed to honor the new option. - `zentest-appstub` gains a `-stdin_echo` mode that reads stdin to EOF and echoes it back (switching to binary mode on Windows so CRLF translation doesn't mangle bytes). - `zenserver-test` gets a `server.process` / `stdin_pipe.*` test group that exercises launching a child with a stdin pipe, writing, closing the write end, and reading back the echoed data. ### 2. Shell-style quote stripping in `BuildArgV` - Callers that build a single command-line string for `CreateProc` commonly wrap spacey paths in double quotes (e.g. `--tracefile="$path"`). The old `BuildArgV` only used quotes to suppress space-splitting and left the characters in the resulting argv element, so the spawned process saw literal `--tracefile="..."` and the value parser failed to open the quoted path. - `BuildArgV` now compacts in place, dropping quote chars as it goes, matching shell semantics for paired double quotes.
Diffstat (limited to 'src/zencore/include')
-rw-r--r--src/zencore/include/zencore/process.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/zencore/include/zencore/process.h b/src/zencore/include/zencore/process.h
index fd24a6d7d..eac226683 100644
--- a/src/zencore/include/zencore/process.h
+++ b/src/zencore/include/zencore/process.h
@@ -160,6 +160,42 @@ struct StdoutPipeHandles
// The write end is inheritable; the read end is not.
bool CreateStdoutPipe(StdoutPipeHandles& OutPipe);
+// Platform-agnostic RAII pipe handles for feeding data into a child's stdin.
+// The destructor closes any open handles/fds automatically.
+struct StdinPipeHandles
+{
+ StdinPipeHandles() = default;
+ ~StdinPipeHandles();
+
+ StdinPipeHandles(const StdinPipeHandles&) = delete;
+ StdinPipeHandles& operator=(const StdinPipeHandles&) = delete;
+
+ StdinPipeHandles(StdinPipeHandles&& Other) noexcept;
+ StdinPipeHandles& operator=(StdinPipeHandles&& Other) noexcept;
+
+ // Close only the read end (call after child is launched so parent doesn't hold it open;
+ // without this the child sees EOF only after the parent closes too).
+ void CloseReadEnd();
+
+ // Close only the write end. Signals EOF to the child once the parent is done writing.
+ void CloseWriteEnd();
+
+ // Close both ends of the pipe.
+ void Close();
+
+#if ZEN_PLATFORM_WINDOWS
+ void* ReadHandle = nullptr; // HANDLE for reading (child side)
+ void* WriteHandle = nullptr; // HANDLE for writing (parent side)
+#else
+ int ReadFd = -1;
+ int WriteFd = -1;
+#endif
+};
+
+// Create a pipe suitable for feeding data into child process stdin.
+// The read end is inheritable; the write end is not.
+bool CreateStdinPipe(StdinPipeHandles& OutPipe);
+
struct CreateProcOptions
{
enum
@@ -193,6 +229,7 @@ struct CreateProcOptions
std::filesystem::path StdoutFile;
StdoutPipeHandles* StdoutPipe = nullptr; // Mutually exclusive with StdoutFile. Parent reads from ReadHandle after launch.
StdoutPipeHandles* StderrPipe = nullptr; // Optional separate pipe for stderr. When null, stderr shares StdoutPipe.
+ StdinPipeHandles* StdinPipe = nullptr; // Optional pipe feeding child stdin. Parent writes to WriteHandle after launch.
/// Additional environment variables for the child process. These are merged
/// with the parent's environment - existing variables are inherited, and