Skip to content

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 28 Jun 01:18
· 4 commits to main since this release
Release v2.0.0

Drain stdout/stderr eagerly to remove the pipe deadlock, and fix a
use-after-free in the variadic constructor.

- stdout and stderr were read lazily while status() (and the destructor,
  which calls status()) waited with waitpid(). A child that writes more
  than the pipe buffer (~64 KiB) blocks on write until a reader drains
  it, so waiting before reading deadlocked - and because ~process_t()
  waits, simply letting a large-output process go out of scope without
  reading it would hang. Add collect(): it closes our copy of the child's
  stdin and poll()s stdout and stderr together, draining both into
  buffers before any wait. str_out()/str_err()/status() all collect
  first, so reading, waiting and destruction can happen in any order.
- the c++20 variadic constructor built its argv from `arg.c_str()` where
  `arg` was a loop variable destroyed each iteration, so execvp() ran
  with dangling pointers. Keep the argument strings in an arg_storage
  member that the char* vector points into (both constructors).
- guard the dynamic_cast in PIPE(process_t*) so piping from a process
  with no input stream cannot dereference a null filebuffer.
- the uncallable second variadic constructor (a parameter pack followed
  by process_t* input cannot be deduced) is removed; input piping still
  works through the (cmd, args, input) constructor.

Example/build: delete the leaked process in example6 (valgrind is now
clean), `int main()`, and correct the README - process_cpp builds with
c++17, only the variadic string-argument constructor needs c++20.

Bump the throws submodule to v1.1.0 and refresh the GitHub Actions
(checkout@v5, create/upload actions @v2, push/pull_request triggers,
submodules in the release checkout).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Oskari Rauta <oskari.rauta@gmail.com>