Zig 0.17.0-dev (Split by item)

Shortcut keys
?
Show these tips
S
Focus search field
Esc
Clear focus & close tips
U
Jump to source code
↑
Move up in search results
↓
Move down in search results
↵
Go to active search result
This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig standard library. Public Struct

Child

Public Struct

Fields

id: ?Id

After wait or kill is called, this becomes null. On Windows this is the hProcess. On POSIX this is the pid.

thread_handle: if (native_os == .windows) std.os.windows.HANDLE else void
stdin: ?File

The writing end of the child process's standard input pipe. Usage requires process.SpawnOptions.StdIo.pipe.

stdout: ?File

The reading end of the child process's standard output pipe. Usage requires process.SpawnOptions.StdIo.pipe.

stderr: ?File

The reading end of the child process's standard error pipe. Usage requires process.SpawnOptions.StdIo.pipe.

resource_usage_statistics: ResourceUsageStatistics = .{}

This is available after calling wait if request_resource_usage_statistics was set to true before calling spawn. TODO move this data into Term

request_resource_usage_statistics: bool

Namespaces

Structs

Types

Values

Functions

pub fn assert(ok: bool) void

Invokes detectable illegal behavior when ok is false.

In debug and safe modes, calls to this function are always generated, and the unreachable statement triggers a panic.

In fast and small modes, calls to this function are optimized away, and in fact the optimizer is able to use the assertion in its heuristics.

Inside a test block, it is best to use the testing module rather than this function, because this function may not detect a test failure in fast and small mode. Outside of a test block, this assert function is the correct function to use.

pub fn kill(child: *Child, io: Io) void

Requests for the operating system to forcibly terminate the child process, then blocks until it terminates, then cleans up all resources.

Idempotent and does nothing after wait returns.

Uncancelable. Ignores unexpected errors from the operating system.

pub fn wait(child: *Child, io: Io) WaitError!Term

Blocks until child process terminates and then cleans up all resources.

File

process/Child.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
const Child = @This();

const builtin = @import("builtin");
const native_os = builtin.os.tag;

const std = @import("../std.zig");
const Io = std.Io;
const process = std.process;
const File = std.Io.File;
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;

pub const Id = switch (native_os) {
    .windows => std.os.windows.HANDLE,
    .wasi => void,
    else => std.posix.pid_t,
};

/// After `wait` or `kill` is called, this becomes `null`.
/// On Windows this is the hProcess.
/// On POSIX this is the pid.
id: ?Id,
thread_handle: if (native_os == .windows) std.os.windows.HANDLE else void,
/// The writing end of the child process's standard input pipe.
/// Usage requires `process.SpawnOptions.StdIo.pipe`.
stdin: ?File,
/// The reading end of the child process's standard output pipe.
/// Usage requires `process.SpawnOptions.StdIo.pipe`.
stdout: ?File,
/// The reading end of the child process's standard error pipe.
/// Usage requires `process.SpawnOptions.StdIo.pipe`.
stderr: ?File,
/// This is available after calling wait if
/// `request_resource_usage_statistics` was set to `true` before calling
/// `spawn`.
/// TODO move this data into `Term`
resource_usage_statistics: ResourceUsageStatistics = .{},
request_resource_usage_statistics: bool,

pub const ResourceUsageStatistics = struct {
    rusage: @TypeOf(rusage_init) = rusage_init,

    /// Returns the peak resident set size of the child process, in bytes,
    /// if available.
    pub inline fn getMaxRss(rus: ResourceUsageStatistics) ?usize {
        switch (native_os) {
            .dragonfly, .freebsd, .netbsd, .openbsd, .illumos, .linux, .serenity => {
                if (rus.rusage) |ru| {
                    return @as(usize, @intCast(ru.maxrss)) * 1024;
                } else {
                    return null;
                }
            },
            .windows => {
                if (rus.rusage) |ru| {
                    return ru.PeakWorkingSetSize;
                } else {
                    return null;
                }
            },
            .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
                if (rus.rusage) |ru| {
                    // Darwin oddly reports in bytes instead of kilobytes.
                    return @as(usize, @intCast(ru.maxrss));
                } else {
                    return null;
                }
            },
            else => return null,
        }
    }

    const rusage_init = switch (native_os) {
        .dragonfly,
        .freebsd,
        .netbsd,
        .openbsd,
        .illumos,
        .linux,
        .serenity,
        .driverkit,
        .ios,
        .maccatalyst,
        .macos,
        .tvos,
        .visionos,
        .watchos,
        => @as(?std.posix.rusage, null),
        .windows => @as(?std.os.windows.PROCESS.VM_COUNTERS, null),
        else => {},
    };
};

pub const Term = union(enum) {
    exited: u8,
    signal: std.posix.SIG,
    stopped: std.posix.SIG,
    unknown: u32,

    pub fn success(t: Term) bool {
        return switch (t) {
            .exited => |code| code == 0,
            else => false,
        };
    }

    pub fn format(t: Term, w: *Io.Writer) Io.Writer.Error!void {
        switch (t) {
            .exited => |code| return w.print("exited with code {d}", .{code}),
            .signal => |sig| return w.print("terminated with signal {t}", .{sig}),
            .stopped => |sig| return w.print("stopped with signal {t}", .{sig}),
            .unknown => return w.writeAll("terminated unexpectedly"),
        }
    }
};

pub const Cwd = union(enum) {
    /// CWD of the child is the same as the current CWD.
    inherit,
    /// On POSIX systems, `fchdir` is called after `fork` using this handle.
    /// On Windows, the path is inferred from the provided handle and that path is used when calling `CreateProcessW`.
    dir: Io.Dir,
    /// On POSIX systems, `chdir` is called after `fork` using this path.
    /// On Windows, this path is used when calling `CreateProcessW`.
    path: []const u8,
};

/// Requests for the operating system to forcibly terminate the child process,
/// then blocks until it terminates, then cleans up all resources.
///
/// Idempotent and does nothing after `wait` returns.
///
/// Uncancelable. Ignores unexpected errors from the operating system.
pub fn kill(child: *Child, io: Io) void {
    if (child.id == null) {
        assert(child.stdin == null);
        assert(child.stdout == null);
        assert(child.stderr == null);
        return;
    }
    io.vtable.childKill(io.userdata, child);
    assert(child.id == null);
}

pub const WaitError = error{
    AccessDenied,
} || Io.Cancelable || Io.UnexpectedError;

/// Blocks until child process terminates and then cleans up all resources.
pub fn wait(child: *Child, io: Io) WaitError!Term {
    assert(child.id != null);
    return io.vtable.childWait(io.userdata, child);
}

test {
    _ = Term;
}