Function run [src]

Spawns a child process, waits for it, collecting stdout and stderr, and then returns. If it succeeds, the caller owns result.stdout and result.stderr memory.

Prototype

pub fn run(args: struct { allocator: mem.Allocator, argv: []const []const u8, cwd: ?[]const u8 = null, cwd_dir: ?fs.Dir = null, env_map: ?*const EnvMap = null, max_output_bytes: usize = 50 * 1024, expand_arg0: Arg0Expand = .no_expand, progress_node: std.Progress.Node = std.Progress.Node.none, }) RunError!RunResult

Parameters

args: struct { allocator: mem.Allocator, argv: []const []const u8, cwd: ?[]const u8 = null, cwd_dir: ?fs.Dir = null, env_map: ?*const EnvMap = null, max_output_bytes: usize = 50 * 1024, expand_arg0: Arg0Expand = .no_expand, progress_node: std.Progress.Node = std.Progress.Node.none, }

Possible Errors

AccessDenied ReadError

In WASI, this error occurs when the file descriptor does not hold the required rights to read from it.

BadPathName ChangeCurDirError
BrokenPipe ReadError
Canceled ReadError

reading a timerfd with CANCEL_ON_SET will lead to this error when the clock goes through a discontinuous change

ConnectionResetByPeer ReadError
ConnectionTimedOut ReadError
CurrentWorkingDirectoryUnlinked SpawnError

Windows-only. cwd was provided, but the path did not exist when spawning the child process.

FileBusy ExecveError
FileNotFound ExecveError
FileSystem ExecveError
InputOutput ReadError
InvalidBatchScriptArg SpawnError

Windows-only. NUL (U+0000), LF (U+000A), CR (U+000D) are not allowed within arguments when executing a .bat/.cmd script.

  • NUL/LF signifiies end of arguments, so anything afterwards would be lost after execution.
  • CR is stripped by cmd.exe, so any CR codepoints would be lost after execution.
InvalidExe ExecveError
InvalidHandle GetProcessMemoryInfoError
InvalidName CreateProcessError
InvalidProcessGroupId SetPgidError
InvalidUserId SetEidError
InvalidUtf8 ChangeCurDirError

WASI-only; file paths must be valid UTF-8.

InvalidWtf8 SpawnError

Windows-only. cwd or argv was provided and it was invalid WTF-8. https://simonsapin.github.io/wtf-8/

IsDir ReadError
LockViolation ReadError

Unable to read file due to lock.

NameTooLong GetCwdError
NetworkSubsystemFailed PollError

The network subsystem has failed.

NoDevice SpawnError

POSIX-only. StdIo.Ignore was selected and opening /dev/null returned ENODEV.

NotDir ExecveError
NotOpenForReading ReadError
OperationAborted ReadError
OutOfMemory SpawnError
PermissionDenied ExecveError
ProcessAlreadyExec SetPgidError
ProcessFdQuotaExceeded ExecveError
ProcessNotFound ReadError

This error occurs in Linux if the process to be read from no longer exists.

ResourceLimitReached SetIdError
SocketNotConnected ReadError
StderrStreamTooLong
StdoutStreamTooLong
SymLinkLoop ChangeCurDirError
SystemFdQuotaExceeded ExecveError
SystemResources PollError

The kernel had no space to allocate file descriptor tables.

Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

WaitAbandoned WaitForSingleObjectError
WaitTimeOut WaitForSingleObjectError
WouldBlock ReadError

This error occurs when no global event loop is configured, and reading from the file descriptor would block.

Source

pub fn run(args: struct { allocator: mem.Allocator, argv: []const []const u8, cwd: ?[]const u8 = null, cwd_dir: ?fs.Dir = null, env_map: ?*const EnvMap = null, max_output_bytes: usize = 50 * 1024, expand_arg0: Arg0Expand = .no_expand, progress_node: std.Progress.Node = std.Progress.Node.none, }) RunError!RunResult { var child = ChildProcess.init(args.argv, args.allocator); child.stdin_behavior = .Ignore; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; child.cwd = args.cwd; child.cwd_dir = args.cwd_dir; child.env_map = args.env_map; child.expand_arg0 = args.expand_arg0; child.progress_node = args.progress_node; var stdout: std.ArrayListUnmanaged(u8) = .empty; errdefer stdout.deinit(args.allocator); var stderr: std.ArrayListUnmanaged(u8) = .empty; errdefer stderr.deinit(args.allocator); try child.spawn(); errdefer { _ = child.kill() catch {}; } try child.collectOutput(args.allocator, &stdout, &stderr, args.max_output_bytes); return RunResult{ .stdout = try stdout.toOwnedSlice(args.allocator), .stderr = try stderr.toOwnedSlice(args.allocator), .term = try child.wait(), }; }