zig icon indicating copy to clipboard operation
zig copied to clipboard

`std.process.Child` lacks a mechanism to use an existing file descriptor for stdio

Open mlugg opened this issue 11 months ago • 0 comments

Zig Version

0.15.0-dev.552+bc2f7c754

Steps to Reproduce and Observed Behavior

  • Create a std.process.Child with .init
  • Try to use its stdout_behavior/stderr_behavior/stdin_behavior to specify an existing std.fs.File as the handle to use
  • This turns out to be impossible!

The only way to currently achieve the same effect with the std.process.Child API is to use .Pipe and buffer data in the parent process, which is very complex and inefficient.

Expected Behavior

There should be a field in std.process.Child.StdIo giving the option to use an open std.fs.File. Perhaps the following program should compile and succeed:

//! This program sends the stdout of 'cat hello' directly to './out.txt'.

pub fn main() !void {
    const gpa = std.heap.smp_allocator;

    var out_file = try std.fs.cwd().createFile("out.txt", .{});
    defer out_file.close();

    var child: std.process.Child = .init(&.{ "cat", "hello" }, gpa);
    child.stdout_behavior = .{ .file = out_file };

    try child.spawn();
    const term = try child.wait();
    _ = term; // TODO: check success
}

const std = @import("std");

It might make more sense for spawn to close the FD in the parent process on spawn success, I've not thought about this. The point is just that it should be possible, and that it would probably look something like the above.

Related: #22504

mlugg avatar May 22 '25 01:05 mlugg