DoxigAlpha

collectOutput

Collect the output from the process's stdout and stderr. Will return once all output has been collected. This does not mean that the process has ended. wait should still be called to wait for and clean up the process.

The process must be started with stdout_behavior and stderr_behavior == .Pipe

Function parameters

Parameters

#
allocator:Allocator
Used for `stdout` and `stderr`.
stdout:*ArrayList(u8)
stderr:*ArrayList(u8)
max_output_bytes:usize

Type definitions in this namespace

Types

#
StdIo
Behavior of the child process's standard input, output, and error
WindowsExtension
File name extensions supported natively by `CreateProcess()` on Windows.

First argument in argv is the executable.

Functions

#
init
First argument in argv is the executable.
spawn
On success must call `kill` or `wait`.
kill
Forcibly terminates child process and then cleans up all resources.
waitForSpawn
On some targets, `spawn` may not report all spawn errors, such as `error.InvalidExe`.
wait
Blocks until child process terminates and then cleans up all resources.
collectOutput
Collect the output from the process's stdout and stderr.
run
Spawns a child process, waits for it, collecting stdout and stderr, and then returns.

Error sets in this namespace

Error Sets

#

Source

Implementation

#
pub fn collectOutput(
    child: ChildProcess,
    /// Used for `stdout` and `stderr`.
    allocator: Allocator,
    stdout: *ArrayList(u8),
    stderr: *ArrayList(u8),
    max_output_bytes: usize,
) !void {
    assert(child.stdout_behavior == .Pipe);
    assert(child.stderr_behavior == .Pipe);

    var poller = std.Io.poll(allocator, enum { stdout, stderr }, .{
        .stdout = child.stdout.?,
        .stderr = child.stderr.?,
    });
    defer poller.deinit();

    const stdout_r = poller.reader(.stdout);
    stdout_r.buffer = stdout.allocatedSlice();
    stdout_r.seek = 0;
    stdout_r.end = stdout.items.len;

    const stderr_r = poller.reader(.stderr);
    stderr_r.buffer = stderr.allocatedSlice();
    stderr_r.seek = 0;
    stderr_r.end = stderr.items.len;

    defer {
        stdout.* = .{
            .items = stdout_r.buffer[0..stdout_r.end],
            .capacity = stdout_r.buffer.len,
        };
        stderr.* = .{
            .items = stderr_r.buffer[0..stderr_r.end],
            .capacity = stderr_r.buffer.len,
        };
        stdout_r.buffer = &.{};
        stderr_r.buffer = &.{};
    }

    while (try poller.poll()) {
        if (stdout_r.bufferedLen() > max_output_bytes)
            return error.StdoutStreamTooLong;
        if (stderr_r.bufferedLen() > max_output_bytes)
            return error.StderrStreamTooLong;
    }
}