std: restructure child process namespace

This commit is contained in:
Andrew Kelley 2024-05-23 11:25:41 -07:00
parent 793f820b39
commit f47824f24d
24 changed files with 2048 additions and 2048 deletions

View File

@ -193,100 +193,6 @@ set(ZIG_CPP_SOURCES
# Needed because we use cmake, not the zig build system, to build zig2.o.
set(ZIG_STAGE2_SOURCES
"${ZIG_CONFIG_ZIG_OUT}"
lib/std/array_hash_map.zig
lib/std/array_list.zig
lib/std/ascii.zig
lib/std/atomic.zig
lib/std/base64.zig
lib/std/BitStack.zig
lib/std/buf_map.zig
lib/std/Build.zig
lib/std/Build/Cache.zig
lib/std/Build/Cache/DepTokenizer.zig
lib/std/builtin.zig
lib/std/c.zig
lib/std/c/linux.zig
lib/std/child_process.zig
lib/std/coff.zig
lib/std/static_string_map.zig
lib/std/crypto.zig
lib/std/crypto/blake3.zig
lib/std/crypto/siphash.zig
lib/std/debug.zig
lib/std/dwarf.zig
lib/std/dwarf/AT.zig
lib/std/dwarf/ATE.zig
lib/std/dwarf/FORM.zig
lib/std/dwarf/LANG.zig
lib/std/dwarf/OP.zig
lib/std/dwarf/TAG.zig
lib/std/elf.zig
lib/std/fifo.zig
lib/std/fmt.zig
lib/std/fmt/format_float.zig
lib/std/fmt/parse_float.zig
lib/std/fs.zig
lib/std/fs/AtomicFile.zig
lib/std/fs/Dir.zig
lib/std/fs/File.zig
lib/std/fs/get_app_data_dir.zig
lib/std/fs/path.zig
lib/std/hash.zig
lib/std/hash/auto_hash.zig
lib/std/hash/wyhash.zig
lib/std/hash_map.zig
lib/std/heap.zig
lib/std/heap/arena_allocator.zig
lib/std/io.zig
lib/std/io/buffered_atomic_file.zig
lib/std/io/buffered_writer.zig
lib/std/io/change_detection_stream.zig
lib/std/io/counting_reader.zig
lib/std/io/counting_writer.zig
lib/std/io/find_byte_writer.zig
lib/std/io/fixed_buffer_stream.zig
lib/std/io/limited_reader.zig
lib/std/io/Reader.zig
lib/std/io/seekable_stream.zig
lib/std/io/Writer.zig
lib/std/json.zig
lib/std/json/stringify.zig
lib/std/leb128.zig
lib/std/linked_list.zig
lib/std/log.zig
lib/std/macho.zig
lib/std/math.zig
lib/std/math/big.zig
lib/std/math/big/int.zig
lib/std/math/float.zig
lib/std/math/frexp.zig
lib/std/math/isinf.zig
lib/std/math/isnan.zig
lib/std/math/log.zig
lib/std/math/log10.zig
lib/std/math/log2.zig
lib/std/math/signbit.zig
lib/std/math/sqrt.zig
lib/std/mem.zig
lib/std/mem/Allocator.zig
lib/std/meta.zig
lib/std/meta/trailer_flags.zig
lib/std/multi_array_list.zig
lib/std/os.zig
lib/std/os/linux.zig
lib/std/os/linux/x86_64.zig
lib/std/os/linux.zig
lib/std/os/linux/IoUring.zig
lib/std/os/linux/io_uring_sqe.zig
lib/std/os/linux/x86_64.zig
lib/std/os/windows.zig
lib/std/os/windows/ntstatus.zig
lib/std/os/windows/win32error.zig
lib/std/Progress.zig
lib/std/pdb.zig
lib/std/process.zig
lib/std/Random.zig
lib/std/sort.zig
lib/compiler_rt.zig
lib/compiler_rt/absv.zig
lib/compiler_rt/absvdi2.zig
@ -363,7 +269,7 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/fixxfdi.zig
lib/compiler_rt/fixxfsi.zig
lib/compiler_rt/fixxfti.zig
lib/compiler_rt/int_from_float.zig
lib/compiler_rt/float_from_int.zig
lib/compiler_rt/floatdidf.zig
lib/compiler_rt/floatdihf.zig
lib/compiler_rt/floatdisf.zig
@ -404,7 +310,7 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/getf2.zig
lib/compiler_rt/gexf2.zig
lib/compiler_rt/int.zig
lib/compiler_rt/float_from_int.zig
lib/compiler_rt/int_from_float.zig
lib/compiler_rt/log.zig
lib/compiler_rt/log10.zig
lib/compiler_rt/log2.zig
@ -417,7 +323,11 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/multf3.zig
lib/compiler_rt/mulxf3.zig
lib/compiler_rt/negXi2.zig
lib/compiler_rt/negdf2.zig
lib/compiler_rt/negsf2.zig
lib/compiler_rt/negtf2.zig
lib/compiler_rt/negv.zig
lib/compiler_rt/negxf2.zig
lib/compiler_rt/os_version_check.zig
lib/compiler_rt/parity.zig
lib/compiler_rt/popcount.zig
@ -430,15 +340,11 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/sincos.zig
lib/compiler_rt/sqrt.zig
lib/compiler_rt/stack_probe.zig
lib/compiler_rt/subdf3.zig
lib/compiler_rt/subo.zig
lib/compiler_rt/subsf3.zig
lib/compiler_rt/subdf3.zig
lib/compiler_rt/subtf3.zig
lib/compiler_rt/subxf3.zig
lib/compiler_rt/negsf2.zig
lib/compiler_rt/negdf2.zig
lib/compiler_rt/negtf2.zig
lib/compiler_rt/negxf2.zig
lib/compiler_rt/tan.zig
lib/compiler_rt/trig.zig
lib/compiler_rt/trunc.zig
@ -461,8 +367,12 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/unorddf2.zig
lib/compiler_rt/unordsf2.zig
lib/compiler_rt/unordtf2.zig
lib/std/start.zig
lib/std/std.zig
lib/std/BitStack.zig
lib/std/Build.zig
lib/std/Build/Cache.zig
lib/std/Build/Cache/DepTokenizer.zig
lib/std/Progress.zig
lib/std/Random.zig
lib/std/Target.zig
lib/std/Target/Query.zig
lib/std/Target/aarch64.zig
@ -476,8 +386,8 @@ set(ZIG_STAGE2_SOURCES
lib/std/Target/nvptx.zig
lib/std/Target/powerpc.zig
lib/std/Target/riscv.zig
lib/std/Target/sparc.zig
lib/std/Target/s390x.zig
lib/std/Target/sparc.zig
lib/std/Target/wasm.zig
lib/std/Target/x86.zig
lib/std/Thread.zig
@ -486,6 +396,96 @@ set(ZIG_STAGE2_SOURCES
lib/std/Thread/Pool.zig
lib/std/Thread/ResetEvent.zig
lib/std/Thread/WaitGroup.zig
lib/std/array_hash_map.zig
lib/std/array_list.zig
lib/std/ascii.zig
lib/std/atomic.zig
lib/std/base64.zig
lib/std/buf_map.zig
lib/std/builtin.zig
lib/std/c.zig
lib/std/c/linux.zig
lib/std/coff.zig
lib/std/crypto.zig
lib/std/crypto/blake3.zig
lib/std/crypto/siphash.zig
lib/std/debug.zig
lib/std/dwarf.zig
lib/std/dwarf/AT.zig
lib/std/dwarf/ATE.zig
lib/std/dwarf/FORM.zig
lib/std/dwarf/LANG.zig
lib/std/dwarf/OP.zig
lib/std/dwarf/TAG.zig
lib/std/elf.zig
lib/std/fifo.zig
lib/std/fmt.zig
lib/std/fmt/format_float.zig
lib/std/fmt/parse_float.zig
lib/std/fs.zig
lib/std/fs/AtomicFile.zig
lib/std/fs/Dir.zig
lib/std/fs/File.zig
lib/std/fs/get_app_data_dir.zig
lib/std/fs/path.zig
lib/std/hash.zig
lib/std/hash/auto_hash.zig
lib/std/hash/wyhash.zig
lib/std/hash_map.zig
lib/std/heap.zig
lib/std/heap/arena_allocator.zig
lib/std/io.zig
lib/std/io/Reader.zig
lib/std/io/Writer.zig
lib/std/io/buffered_atomic_file.zig
lib/std/io/buffered_writer.zig
lib/std/io/change_detection_stream.zig
lib/std/io/counting_reader.zig
lib/std/io/counting_writer.zig
lib/std/io/find_byte_writer.zig
lib/std/io/fixed_buffer_stream.zig
lib/std/io/limited_reader.zig
lib/std/io/seekable_stream.zig
lib/std/json.zig
lib/std/json/stringify.zig
lib/std/leb128.zig
lib/std/linked_list.zig
lib/std/log.zig
lib/std/macho.zig
lib/std/math.zig
lib/std/math/big.zig
lib/std/math/big/int.zig
lib/std/math/float.zig
lib/std/math/frexp.zig
lib/std/math/isinf.zig
lib/std/math/isnan.zig
lib/std/math/log.zig
lib/std/math/log10.zig
lib/std/math/log2.zig
lib/std/math/signbit.zig
lib/std/math/sqrt.zig
lib/std/mem.zig
lib/std/mem/Allocator.zig
lib/std/meta.zig
lib/std/meta/trailer_flags.zig
lib/std/multi_array_list.zig
lib/std/os.zig
lib/std/os/linux.zig
lib/std/os/linux.zig
lib/std/os/linux/IoUring.zig
lib/std/os/linux/io_uring_sqe.zig
lib/std/os/linux/x86_64.zig
lib/std/os/linux/x86_64.zig
lib/std/os/windows.zig
lib/std/os/windows/ntstatus.zig
lib/std/os/windows/win32error.zig
lib/std/pdb.zig
lib/std/process.zig
lib/std/process/Child.zig
lib/std/sort.zig
lib/std/start.zig
lib/std/static_string_map.zig
lib/std/std.zig
lib/std/time.zig
lib/std/treap.zig
lib/std/unicode.zig

View File

@ -803,7 +803,7 @@ pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void
return d.fatal("unable to dump linker args: {s}", .{errorDescription(er)});
};
}
var child = std.ChildProcess.init(argv.items, d.comp.gpa);
var child = std.process.Child.init(argv.items, d.comp.gpa);
// TODO handle better
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;

View File

@ -302,7 +302,7 @@ fn buildWasmBinary(
"--listen=-",
});
var child = std.ChildProcess.init(argv.items, gpa);
var child = std.process.Child.init(argv.items, gpa);
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;
@ -437,7 +437,7 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void {
.macos => "open",
else => "xdg-open",
};
var child = std.ChildProcess.init(&.{ main_exe, url }, gpa);
var child = std.process.Child.init(&.{ main_exe, url }, gpa);
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Ignore;
child.stderr_behavior = .Ignore;

View File

@ -178,7 +178,7 @@ pub const RunError = error{
ExitCodeFailure,
ProcessTerminated,
ExecNotSupported,
} || std.ChildProcess.SpawnError;
} || std.process.Child.SpawnError;
pub const PkgConfigError = error{
PkgConfigCrashed,
@ -1719,7 +1719,7 @@ pub fn runAllowFail(
b: *Build,
argv: []const []const u8,
out_code: *u8,
stderr_behavior: std.ChildProcess.StdIo,
stderr_behavior: std.process.Child.StdIo,
) RunError![]u8 {
assert(argv.len != 0);
@ -1727,7 +1727,7 @@ pub fn runAllowFail(
return error.ExecNotSupported;
const max_output_size = 400 * 1024;
var child = std.ChildProcess.init(argv, b.allocator);
var child = std.process.Child.init(argv, b.allocator);
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = stderr_behavior;

View File

@ -275,7 +275,7 @@ pub fn evalChildProcess(s: *Step, argv: []const []const u8) !void {
try handleChildProcUnsupported(s, null, argv);
try handleVerbose(s.owner, null, argv);
const result = std.ChildProcess.run(.{
const result = std.process.Child.run(.{
.allocator = arena,
.argv = argv,
}) catch |err| return s.fail("unable to spawn {s}: {s}", .{ argv[0], @errorName(err) });
@ -313,7 +313,7 @@ pub fn evalZigProcess(
try handleChildProcUnsupported(s, null, argv);
try handleVerbose(s.owner, null, argv);
var child = std.ChildProcess.init(argv, arena);
var child = std.process.Child.init(argv, arena);
child.env_map = &b.graph.env_map;
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
@ -480,7 +480,7 @@ pub inline fn handleChildProcUnsupported(
pub fn handleChildProcessTerm(
s: *Step,
term: std.ChildProcess.Term,
term: std.process.Child.Term,
opt_cwd: ?[]const u8,
argv: []const []const u8,
) error{ MakeFailed, OutOfMemory }!void {

File diff suppressed because it is too large Load Diff

View File

@ -6,12 +6,12 @@ const math = std.math;
const Allocator = mem.Allocator;
const assert = std.debug.assert;
const testing = std.testing;
const child_process = @import("child_process.zig");
const native_os = builtin.os.tag;
const posix = std.posix;
const windows = std.os.windows;
const unicode = std.unicode;
pub const Child = child_process.ChildProcess;
pub const Child = @import("process/Child.zig");
pub const abort = posix.abort;
pub const exit = posix.exit;
pub const changeCurDir = posix.chdir;
@ -86,7 +86,7 @@ pub const EnvMap = struct {
_ = self;
if (native_os == .windows) {
var h = std.hash.Wyhash.init(0);
var it = std.unicode.Wtf8View.initUnchecked(s).iterator();
var it = unicode.Wtf8View.initUnchecked(s).iterator();
while (it.nextCodepoint()) |cp| {
const cp_upper = upcase(cp);
h.update(&[_]u8{
@ -103,8 +103,8 @@ pub const EnvMap = struct {
pub fn eql(self: @This(), a: []const u8, b: []const u8) bool {
_ = self;
if (native_os == .windows) {
var it_a = std.unicode.Wtf8View.initUnchecked(a).iterator();
var it_b = std.unicode.Wtf8View.initUnchecked(b).iterator();
var it_a = unicode.Wtf8View.initUnchecked(a).iterator();
var it_b = unicode.Wtf8View.initUnchecked(b).iterator();
while (true) {
const c_a = it_a.nextCodepoint() orelse break;
const c_b = it_b.nextCodepoint() orelse return false;
@ -141,7 +141,7 @@ pub const EnvMap = struct {
/// If `putMove` fails, the ownership of key and value does not transfer.
/// On Windows `key` must be a valid [WTF-8](https://simonsapin.github.io/wtf-8/) string.
pub fn putMove(self: *EnvMap, key: []u8, value: []u8) !void {
assert(std.unicode.wtf8ValidateSlice(key));
assert(unicode.wtf8ValidateSlice(key));
const get_or_put = try self.hash_map.getOrPut(key);
if (get_or_put.found_existing) {
self.free(get_or_put.key_ptr.*);
@ -154,7 +154,7 @@ pub const EnvMap = struct {
/// `key` and `value` are copied into the EnvMap.
/// On Windows `key` must be a valid [WTF-8](https://simonsapin.github.io/wtf-8/) string.
pub fn put(self: *EnvMap, key: []const u8, value: []const u8) !void {
assert(std.unicode.wtf8ValidateSlice(key));
assert(unicode.wtf8ValidateSlice(key));
const value_copy = try self.copy(value);
errdefer self.free(value_copy);
const get_or_put = try self.hash_map.getOrPut(key);
@ -173,7 +173,7 @@ pub const EnvMap = struct {
/// The returned pointer is invalidated if the map resizes.
/// On Windows `key` must be a valid [WTF-8](https://simonsapin.github.io/wtf-8/) string.
pub fn getPtr(self: EnvMap, key: []const u8) ?*[]const u8 {
assert(std.unicode.wtf8ValidateSlice(key));
assert(unicode.wtf8ValidateSlice(key));
return self.hash_map.getPtr(key);
}
@ -182,7 +182,7 @@ pub const EnvMap = struct {
/// key is removed from the map.
/// On Windows `key` must be a valid [WTF-8](https://simonsapin.github.io/wtf-8/) string.
pub fn get(self: EnvMap, key: []const u8) ?[]const u8 {
assert(std.unicode.wtf8ValidateSlice(key));
assert(unicode.wtf8ValidateSlice(key));
return self.hash_map.get(key);
}
@ -190,7 +190,7 @@ pub const EnvMap = struct {
/// This invalidates the value returned by get() for this key.
/// On Windows `key` must be a valid [WTF-8](https://simonsapin.github.io/wtf-8/) string.
pub fn remove(self: *EnvMap, key: []const u8) void {
assert(std.unicode.wtf8ValidateSlice(key));
assert(unicode.wtf8ValidateSlice(key));
const kv = self.hash_map.fetchRemove(key) orelse return;
self.free(kv.key);
self.free(kv.value);
@ -260,7 +260,7 @@ test EnvMap {
try testing.expectEqualStrings("something else", env.get("кириллица").?);
// and WTF-8 that's not valid UTF-8
const wtf8_with_surrogate_pair = try std.unicode.wtf16LeToWtf8Alloc(testing.allocator, &[_]u16{
const wtf8_with_surrogate_pair = try unicode.wtf16LeToWtf8Alloc(testing.allocator, &[_]u16{
std.mem.nativeToLittle(u16, 0xD83D), // unpaired high surrogate
});
defer testing.allocator.free(wtf8_with_surrogate_pair);
@ -300,7 +300,7 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
const key_w = ptr[key_start..i];
const key = try std.unicode.wtf16LeToWtf8Alloc(allocator, key_w);
const key = try unicode.wtf16LeToWtf8Alloc(allocator, key_w);
errdefer allocator.free(key);
if (ptr[i] == '=') i += 1;
@ -308,7 +308,7 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
const value_start = i;
while (ptr[i] != 0) : (i += 1) {}
const value_w = ptr[value_start..i];
const value = try std.unicode.wtf16LeToWtf8Alloc(allocator, value_w);
const value = try unicode.wtf16LeToWtf8Alloc(allocator, value_w);
errdefer allocator.free(value);
i += 1; // skip over null byte
@ -401,13 +401,13 @@ pub fn getEnvVarOwned(allocator: Allocator, key: []const u8) GetEnvVarOwnedError
const result_w = blk: {
var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
const stack_allocator = stack_alloc.get();
const key_w = try std.unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
defer stack_allocator.free(key_w);
break :blk getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
};
// wtf16LeToWtf8Alloc can only fail with OutOfMemory
return std.unicode.wtf16LeToWtf8Alloc(allocator, result_w);
return unicode.wtf16LeToWtf8Alloc(allocator, result_w);
} else if (native_os == .wasi and !builtin.link_libc) {
var envmap = getEnvMap(allocator) catch return error.OutOfMemory;
defer envmap.deinit();
@ -422,7 +422,7 @@ pub fn getEnvVarOwned(allocator: Allocator, key: []const u8) GetEnvVarOwnedError
/// On Windows, `key` must be valid UTF-8.
pub fn hasEnvVarConstant(comptime key: []const u8) bool {
if (native_os == .windows) {
const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key);
const key_w = comptime unicode.utf8ToUtf16LeStringLiteral(key);
return getenvW(key_w) != null;
} else if (native_os == .wasi and !builtin.link_libc) {
@compileError("hasEnvVarConstant is not supported for WASI without libc");
@ -445,7 +445,7 @@ pub fn hasEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool {
if (native_os == .windows) {
var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
const stack_allocator = stack_alloc.get();
const key_w = try std.unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
const key_w = try unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
defer stack_allocator.free(key_w);
return getenvW(key_w) != null;
} else if (native_os == .wasi and !builtin.link_libc) {
@ -659,7 +659,7 @@ pub const ArgIteratorWindows = struct {
/// The iterator makes a copy of `cmd_line_w` converted WTF-8 and keeps it; it does *not* take
/// ownership of `cmd_line_w`.
pub fn init(allocator: Allocator, cmd_line_w: [*:0]const u16) InitError!ArgIteratorWindows {
const cmd_line = try std.unicode.wtf16LeToWtf8Alloc(allocator, mem.sliceTo(cmd_line_w, 0));
const cmd_line = try unicode.wtf16LeToWtf8Alloc(allocator, mem.sliceTo(cmd_line_w, 0));
errdefer allocator.free(cmd_line);
const buffer = try allocator.alloc(u8, cmd_line.len + 1);
@ -728,17 +728,17 @@ pub const ArgIteratorWindows = struct {
// must be 6 bytes for a surrogate pair to exist.
if (self.end - self.start >= 6) {
const window = self.buffer[self.end - 6 .. self.end];
const view = std.unicode.Wtf8View.init(window) catch return;
const view = unicode.Wtf8View.init(window) catch return;
var it = view.iterator();
var pair: [2]u16 = undefined;
pair[0] = std.mem.nativeToLittle(u16, std.math.cast(u16, it.nextCodepoint().?) orelse return);
if (!std.unicode.utf16IsHighSurrogate(std.mem.littleToNative(u16, pair[0]))) return;
if (!unicode.utf16IsHighSurrogate(std.mem.littleToNative(u16, pair[0]))) return;
pair[1] = std.mem.nativeToLittle(u16, std.math.cast(u16, it.nextCodepoint().?) orelse return);
if (!std.unicode.utf16IsLowSurrogate(std.mem.littleToNative(u16, pair[1]))) return;
if (!unicode.utf16IsLowSurrogate(std.mem.littleToNative(u16, pair[1]))) return;
// We know we have a valid surrogate pair, so convert
// it to UTF-8, overwriting the surrogate pair's bytes
// and then chop off the extra bytes.
const len = std.unicode.utf16LeToUtf8(window, &pair) catch unreachable;
const len = unicode.utf16LeToUtf8(window, &pair) catch unreachable;
const delta = 6 - len;
self.end -= delta;
}
@ -1341,7 +1341,7 @@ test ArgIteratorWindows {
}
fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u8) !void {
const cmd_line_w = try std.unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);
const cmd_line_w = try unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);
defer testing.allocator.free(cmd_line_w);
// next
@ -1642,7 +1642,7 @@ pub fn execve(
const envp = m: {
if (env_map) |m| {
const envp_buf = try child_process.createNullDelimitedEnvMap(arena, m);
const envp_buf = try createNullDelimitedEnvMap(arena, m);
break :m envp_buf.ptr;
} else if (builtin.link_libc) {
break :m std.c.environ;
@ -1789,3 +1789,90 @@ pub fn raiseFileDescriptorLimit() void {
test raiseFileDescriptorLimit {
raiseFileDescriptorLimit();
}
pub fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]u8 {
const envp_count = env_map.count();
const envp_buf = try arena.allocSentinel(?[*:0]u8, envp_count, null);
{
var it = env_map.iterator();
var i: usize = 0;
while (it.next()) |pair| : (i += 1) {
const env_buf = try arena.allocSentinel(u8, pair.key_ptr.len + pair.value_ptr.len + 1, 0);
@memcpy(env_buf[0..pair.key_ptr.len], pair.key_ptr.*);
env_buf[pair.key_ptr.len] = '=';
@memcpy(env_buf[pair.key_ptr.len + 1 ..][0..pair.value_ptr.len], pair.value_ptr.*);
envp_buf[i] = env_buf.ptr;
}
assert(i == envp_count);
}
return envp_buf;
}
test createNullDelimitedEnvMap {
const allocator = testing.allocator;
var envmap = EnvMap.init(allocator);
defer envmap.deinit();
try envmap.put("HOME", "/home/ifreund");
try envmap.put("WAYLAND_DISPLAY", "wayland-1");
try envmap.put("DISPLAY", ":1");
try envmap.put("DEBUGINFOD_URLS", " ");
try envmap.put("XCURSOR_SIZE", "24");
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
const environ = try createNullDelimitedEnvMap(arena.allocator(), &envmap);
try testing.expectEqual(@as(usize, 5), environ.len);
inline for (.{
"HOME=/home/ifreund",
"WAYLAND_DISPLAY=wayland-1",
"DISPLAY=:1",
"DEBUGINFOD_URLS= ",
"XCURSOR_SIZE=24",
}) |target| {
for (environ) |variable| {
if (mem.eql(u8, mem.span(variable orelse continue), target)) break;
} else {
try testing.expect(false); // Environment variable not found
}
}
}
/// Caller must free result.
pub fn createWindowsEnvBlock(allocator: mem.Allocator, env_map: *const EnvMap) ![]u16 {
// count bytes needed
const max_chars_needed = x: {
var max_chars_needed: usize = 4; // 4 for the final 4 null bytes
var it = env_map.iterator();
while (it.next()) |pair| {
// +1 for '='
// +1 for null byte
max_chars_needed += pair.key_ptr.len + pair.value_ptr.len + 2;
}
break :x max_chars_needed;
};
const result = try allocator.alloc(u16, max_chars_needed);
errdefer allocator.free(result);
var it = env_map.iterator();
var i: usize = 0;
while (it.next()) |pair| {
i += try unicode.wtf8ToWtf16Le(result[i..], pair.key_ptr.*);
result[i] = '=';
i += 1;
i += try unicode.wtf8ToWtf16Le(result[i..], pair.value_ptr.*);
result[i] = 0;
i += 1;
}
result[i] = 0;
i += 1;
result[i] = 0;
i += 1;
result[i] = 0;
i += 1;
result[i] = 0;
i += 1;
return try allocator.realloc(result, i);
}

1795
lib/std/process/Child.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,6 @@ pub const BoundedArrayAligned = @import("bounded_array.zig").BoundedArrayAligned
pub const Build = @import("Build.zig");
pub const BufMap = @import("buf_map.zig").BufMap;
pub const BufSet = @import("buf_set.zig").BufSet;
/// Deprecated: use `process.Child`.
pub const ChildProcess = @import("child_process.zig").ChildProcess;
pub const StaticStringMap = static_string_map.StaticStringMap;
pub const StaticStringMapWithEql = static_string_map.StaticStringMapWithEql;
pub const DoublyLinkedList = @import("linked_list.zig").DoublyLinkedList;

View File

@ -261,7 +261,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
dev_null,
});
const run_res = std.ChildProcess.run(.{
const run_res = std.process.Child.run(.{
.allocator = allocator,
.argv = argv.items,
.max_output_bytes = 1024 * 1024,
@ -588,7 +588,7 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
try appendCcExe(&argv, skip_cc_env_var);
try argv.append(arg1);
const run_res = std.ChildProcess.run(.{
const run_res = std.process.Child.run(.{
.allocator = allocator,
.argv = argv.items,
.max_output_bytes = 1024 * 1024,

View File

@ -1935,7 +1935,7 @@ pub fn getTarget(self: Compilation) Target {
pub fn hotCodeSwap(
comp: *Compilation,
prog_node: *std.Progress.Node,
pid: std.ChildProcess.Id,
pid: std.process.Child.Id,
) !void {
const lf = comp.bin_file.?;
lf.child_pid = pid;
@ -4614,7 +4614,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) });
};
if (std.process.can_spawn) {
var child = std.ChildProcess.init(argv.items, arena);
var child = std.process.Child.init(argv.items, arena);
if (comp.clang_passthrough_mode) {
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;
@ -4972,7 +4972,7 @@ fn spawnZigRc(
var node_name: std.ArrayListUnmanaged(u8) = .{};
defer node_name.deinit(arena);
var child = std.ChildProcess.init(argv, arena);
var child = std.process.Child.init(argv, arena);
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;

View File

@ -72,7 +72,7 @@ pub const File = struct {
/// Prevents other processes from clobbering files in the output directory
/// of this linking operation.
lock: ?Cache.Lock = null,
child_pid: ?std.ChildProcess.Id = null,
child_pid: ?std.process.Child.Id = null,
pub const OpenOptions = struct {
symbol_count_hint: u64 = 32,
@ -529,7 +529,7 @@ pub const File = struct {
} ||
fs.File.WriteFileError ||
fs.File.OpenError ||
std.ChildProcess.SpawnError ||
std.process.Child.SpawnError ||
fs.Dir.CopyFileError;
/// Commit pending changes and write headers. Takes into account final output mode

View File

@ -893,7 +893,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
}
}
fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
fn debugMem(allocator: Allocator, handle: std.process.Child.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
const buffer = try allocator.alloc(u8, code.len);
defer allocator.free(buffer);
const memread = try std.os.windows.ReadProcessMemory(handle, pvaddr, buffer);
@ -901,7 +901,7 @@ fn debugMem(allocator: Allocator, handle: std.ChildProcess.Id, pvaddr: std.os.wi
log.debug("in memory: {x}", .{std.fmt.fmtSliceHexLower(memread)});
}
fn writeMemProtected(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
fn writeMemProtected(handle: std.process.Child.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
const old_prot = try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, std.os.windows.PAGE_EXECUTE_WRITECOPY);
try writeMem(handle, pvaddr, code);
// TODO: We can probably just set the pages writeable and leave it at that without having to restore the attributes.
@ -909,7 +909,7 @@ fn writeMemProtected(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID,
_ = try std.os.windows.VirtualProtectEx(handle, pvaddr, code.len, old_prot);
}
fn writeMem(handle: std.ChildProcess.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
fn writeMem(handle: std.process.Child.Id, pvaddr: std.os.windows.LPVOID, code: []const u8) !void {
const amt = try std.os.windows.WriteProcessMemory(handle, pvaddr, code);
if (amt != code.len) return error.InputOutput;
}
@ -1031,7 +1031,7 @@ fn resolveRelocs(self: *Coff, atom_index: Atom.Index, relocs: []*const Relocatio
}
}
pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {
pub fn ptraceAttach(self: *Coff, handle: std.process.Child.Id) !void {
if (!is_hot_update_compatible) return;
log.debug("attaching to process with handle {*}", .{handle});
@ -1041,7 +1041,7 @@ pub fn ptraceAttach(self: *Coff, handle: std.ChildProcess.Id) !void {
};
}
pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void {
pub fn ptraceDetach(self: *Coff, handle: std.process.Child.Id) void {
if (!is_hot_update_compatible) return;
log.debug("detaching from process with handle {*}", .{handle});

View File

@ -3637,7 +3637,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo
// If possible, we run LLD as a child process because it does not always
// behave properly as a library, unfortunately.
// https://github.com/ziglang/zig/issues/3825
var child = std.ChildProcess.init(argv.items, arena);
var child = std.process.Child.init(argv.items, arena);
if (comp.clang_passthrough_mode) {
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;

View File

@ -4026,7 +4026,7 @@ fn serve(
});
defer server.deinit();
var child_pid: ?std.ChildProcess.Id = null;
var child_pid: ?std.process.Child.Id = null;
var progress: std.Progress = .{
.terminal = null,
@ -4316,7 +4316,7 @@ fn runOrTest(
const cmd = try std.mem.join(arena, " ", argv.items);
fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
} else if (process.can_spawn) {
var child = std.ChildProcess.init(argv.items, gpa);
var child = std.process.Child.init(argv.items, gpa);
child.env_map = &env_map;
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;
@ -4379,7 +4379,7 @@ fn runOrTestHotSwap(
arg_mode: ArgMode,
all_args: []const []const u8,
runtime_args_start: ?usize,
) !std.ChildProcess.Id {
) !std.process.Child.Id {
const lf = comp.bin_file.?;
const exe_path = switch (builtin.target.os.tag) {
@ -4456,7 +4456,7 @@ fn runOrTestHotSwap(
return pid;
},
else => {
var child = std.ChildProcess.init(argv.items, gpa);
var child = std.process.Child.init(argv.items, gpa);
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;
@ -5245,7 +5245,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
}
if (process.can_spawn) {
var child = std.ChildProcess.init(child_argv.items, gpa);
var child = std.process.Child.init(child_argv.items, gpa);
child.stdin_behavior = .Inherit;
child.stdout_behavior = .Inherit;
child.stderr_behavior = .Inherit;
@ -5549,7 +5549,7 @@ fn jitCmd(
});
}
var child = std.ChildProcess.init(child_argv.items, gpa);
var child = std.process.Child.init(child_argv.items, gpa);
child.stdin_behavior = .Inherit;
child.stdout_behavior = if (options.capture == null) .Inherit else .Pipe;
child.stderr_behavior = .Inherit;

View File

@ -1839,7 +1839,7 @@ fn runOneCase(
try comp.makeBinFileExecutable();
while (true) {
break :x std.ChildProcess.run(.{
break :x std.process.Child.run(.{
.allocator = allocator,
.argv = argv.items,
.cwd_dir = tmp.dir,

View File

@ -13,7 +13,7 @@ pub fn main() !void {
_ = it.next() orelse unreachable; // skip binary name
const child_path = it.next() orelse unreachable;
var child = std.ChildProcess.init(&.{ child_path, "hello arg" }, gpa);
var child = std.process.Child.init(&.{ child_path, "hello arg" }, gpa);
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Inherit;

View File

@ -87,7 +87,7 @@ fn testExecBat(allocator: std.mem.Allocator, bat: []const u8, args: []const []co
const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
const result = try std.ChildProcess.run(.{
const result = try std.process.Child.run(.{
.allocator = allocator,
.env_map = env,
.argv = argv.items,

View File

@ -109,7 +109,7 @@ fn testExecBat(allocator: std.mem.Allocator, bat: []const u8, args: []const []co
const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
const result = try std.ChildProcess.run(.{
const result = try std.process.Child.run(.{
.allocator = allocator,
.env_map = env,
.argv = argv.items,

View File

@ -158,7 +158,7 @@ fn testExec(allocator: std.mem.Allocator, command: []const u8, expected_stdout:
}
fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void {
const result = try std.ChildProcess.run(.{
const result = try std.process.Child.run(.{
.allocator = allocator,
.argv = &[_][]const u8{command},
.cwd = cwd,

View File

@ -3,7 +3,7 @@ const builtin = @import("builtin");
const io = std.io;
const fs = std.fs;
const process = std.process;
const ChildProcess = std.ChildProcess;
const ChildProcess = std.process.Child;
const Progress = std.Progress;
const print = std.debug.print;
const mem = std.mem;

View File

@ -257,7 +257,7 @@ pub fn main() !void {
"arch/arm64/include/uapi/asm/unistd.h",
};
const child_result = try std.ChildProcess.run(.{
const child_result = try std.process.Child.run(.{
.allocator = allocator,
.argv = &child_args,
.cwd = linux_path,
@ -318,7 +318,7 @@ pub fn main() !void {
"arch/riscv/include/uapi/asm/unistd.h",
};
const child_result = try std.ChildProcess.run(.{
const child_result = try std.process.Child.run(.{
.allocator = allocator,
.argv = &child_args,
.cwd = linux_path,

View File

@ -624,7 +624,7 @@ pub fn main() anyerror!void {
try std.fmt.allocPrint(allocator, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}),
};
const child_result = try std.ChildProcess.run(.{
const child_result = try std.process.Child.run(.{
.allocator = allocator,
.argv = &child_args,
.max_output_bytes = 100 * 1024 * 1024,

View File

@ -1106,7 +1106,7 @@ fn processOneTarget(job: Job) anyerror!void {
}),
};
const child_result = try std.ChildProcess.run(.{
const child_result = try std.process.Child.run(.{
.allocator = arena,
.argv = &child_args,
.max_output_bytes = 400 * 1024 * 1024,