| author | |
| committer | |
| log | 69d07472a12c8ec8f83a43ed63c1ab7e2ab71c14 |
| tree | 2599e7a3ffecd39f14b8c72c0e51eb29a88fa286 |
| parent | 3e6d6150d98658e6c46ad5c378f90fb628f97d2a |
8 files changed, 46 insertions(+), 55 deletions(-)
lib/std/Build/Step.zig+9-10| ... | @@ -448,7 +448,10 @@ pub fn evalZigProcess( | ... | @@ -448,7 +448,10 @@ pub fn evalZigProcess( |
| 448 | try handleChildProcUnsupported(s); | 448 | try handleChildProcUnsupported(s); |
| 449 | try handleVerbose(s.owner, null, argv); | 449 | try handleVerbose(s.owner, null, argv); |
| 450 | 450 | ||
| 451 | var child = std.process.spawn(io, .{ | 451 | const zp = try gpa.create(ZigProcess); |
| 452 | defer if (!watch) gpa.destroy(zp); | ||
| 453 | |||
| 454 | zp.child = std.process.spawn(io, .{ | ||
| 452 | .argv = argv, | 455 | .argv = argv, |
| 453 | .env_map = &b.graph.env_map, | 456 | .env_map = &b.graph.env_map, |
| 454 | .stdin = .pipe, | 457 | .stdin = .pipe, |
| ... | @@ -457,22 +460,18 @@ pub fn evalZigProcess( | ... | @@ -457,22 +460,18 @@ pub fn evalZigProcess( |
| 457 | .request_resource_usage_statistics = true, | 460 | .request_resource_usage_statistics = true, |
| 458 | .progress_node = prog_node, | 461 | .progress_node = prog_node, |
| 459 | }) catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); | 462 | }) catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); |
| 460 | defer if (!watch) child.kill(io); | 463 | defer if (!watch) zp.child.kill(io); |
| 461 | 464 | ||
| 462 | const zp = try gpa.create(ZigProcess); | ||
| 463 | zp.* = .{ | 465 | zp.* = .{ |
| 464 | .child = child, | 466 | .child = zp.child, |
| 465 | .poller = Io.poll(gpa, ZigProcess.StreamEnum, .{ | 467 | .poller = Io.poll(gpa, ZigProcess.StreamEnum, .{ |
| 466 | .stdout = child.stdout.?, | 468 | .stdout = zp.child.stdout.?, |
| 467 | .stderr = child.stderr.?, | 469 | .stderr = zp.child.stderr.?, |
| 468 | }), | 470 | }), |
| 469 | .progress_ipc_fd = if (std.Progress.have_ipc) prog_node.getIpcFd() else {}, | 471 | .progress_ipc_fd = if (std.Progress.have_ipc) prog_node.getIpcFd() else {}, |
| 470 | }; | 472 | }; |
| 471 | if (watch) s.setZigProcess(zp); | 473 | if (watch) s.setZigProcess(zp); |
| 472 | defer if (!watch) { | 474 | defer if (!watch) zp.poller.deinit(); |
| 473 | zp.poller.deinit(); | ||
| 474 | gpa.destroy(zp); | ||
| 475 | }; | ||
| 476 | 475 | ||
| 477 | const result = try zigProcessUpdate(s, zp, watch, web_server, gpa); | 476 | const result = try zigProcessUpdate(s, zp, watch, web_server, gpa); |
| 478 | 477 |
lib/std/Io.zig-5| ... | @@ -2240,8 +2240,3 @@ pub fn tryLockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancel | ... | @@ -2240,8 +2240,3 @@ pub fn tryLockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancel |
| 2240 | pub fn unlockStderr(io: Io) void { | 2240 | pub fn unlockStderr(io: Io) void { |
| 2241 | return io.vtable.unlockStderr(io.userdata); | 2241 | return io.vtable.unlockStderr(io.userdata); |
| 2242 | } | 2242 | } |
| 2243 | |||
| 2244 | pub fn environ(io: Io, name: []const u8) ?[]const u8 { | ||
| 2245 | _ = io; | ||
| 2246 | std.debug.panic("TODO: environ query: {s}", .{name}); | ||
| 2247 | } |
lib/std/Io/Threaded.zig+20-30| ... | @@ -101,6 +101,9 @@ pub const Environ = struct { | ... | @@ -101,6 +101,9 @@ pub const Environ = struct { |
| 101 | .windows, .wasi => struct {}, | 101 | .windows, .wasi => struct {}, |
| 102 | else => struct { | 102 | else => struct { |
| 103 | PATH: ?[:0]const u8 = null, | 103 | PATH: ?[:0]const u8 = null, |
| 104 | DEBUGINFOD_CACHE_PATH: ?[:0]const u8 = null, | ||
| 105 | XDG_CACHE_HOME: ?[:0]const u8 = null, | ||
| 106 | HOME: ?[:0]const u8 = null, | ||
| 104 | }, | 107 | }, |
| 105 | }; | 108 | }; |
| 106 | }; | 109 | }; |
| ... | @@ -12674,27 +12677,6 @@ fn scanEnviron(t: *Threaded) void { | ... | @@ -12674,27 +12677,6 @@ fn scanEnviron(t: *Threaded) void { |
| 12674 | } | 12677 | } |
| 12675 | comptime assert(@sizeOf(Environ.String) == 0); | 12678 | comptime assert(@sizeOf(Environ.String) == 0); |
| 12676 | } | 12679 | } |
| 12677 | } else if (builtin.link_libc) { | ||
| 12678 | var ptr = std.c.environ; | ||
| 12679 | while (ptr[0]) |line| : (ptr += 1) { | ||
| 12680 | var line_i: usize = 0; | ||
| 12681 | while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {} | ||
| 12682 | const key = line[0..line_i]; | ||
| 12683 | |||
| 12684 | var end_i: usize = line_i; | ||
| 12685 | while (line[end_i] != 0) : (end_i += 1) {} | ||
| 12686 | const value = line[line_i + 1 .. end_i :0]; | ||
| 12687 | |||
| 12688 | if (std.mem.eql(u8, key, "NO_COLOR")) { | ||
| 12689 | t.environ.exist.NO_COLOR = true; | ||
| 12690 | } else if (std.mem.eql(u8, key, "CLICOLOR_FORCE")) { | ||
| 12691 | t.environ.exist.CLICOLOR_FORCE = true; | ||
| 12692 | } else if (@hasField(Environ.String, "PATH") and std.mem.eql(u8, key, "PATH")) { | ||
| 12693 | t.environ.string.PATH = value; | ||
| 12694 | } else if (std.mem.eql(u8, key, "ZIG_PROGRESS")) { | ||
| 12695 | t.environ.zig_progress_handle = std.fmt.parseInt(u31, value, 10) catch error.UnrecognizedFormat; | ||
| 12696 | } | ||
| 12697 | } | ||
| 12698 | } else { | 12680 | } else { |
| 12699 | for (t.environ.block) |opt_line| { | 12681 | for (t.environ.block) |opt_line| { |
| 12700 | const line = opt_line.?; | 12682 | const line = opt_line.?; |
| ... | @@ -12710,10 +12692,10 @@ fn scanEnviron(t: *Threaded) void { | ... | @@ -12710,10 +12692,10 @@ fn scanEnviron(t: *Threaded) void { |
| 12710 | t.environ.exist.NO_COLOR = true; | 12692 | t.environ.exist.NO_COLOR = true; |
| 12711 | } else if (std.mem.eql(u8, key, "CLICOLOR_FORCE")) { | 12693 | } else if (std.mem.eql(u8, key, "CLICOLOR_FORCE")) { |
| 12712 | t.environ.exist.CLICOLOR_FORCE = true; | 12694 | t.environ.exist.CLICOLOR_FORCE = true; |
| 12713 | } else if (@hasField(Environ.String, "PATH") and std.mem.eql(u8, key, "PATH")) { | ||
| 12714 | t.environ.string.PATH = value; | ||
| 12715 | } else if (std.mem.eql(u8, key, "ZIG_PROGRESS")) { | 12695 | } else if (std.mem.eql(u8, key, "ZIG_PROGRESS")) { |
| 12716 | t.environ.zig_progress_handle = std.fmt.parseInt(u31, value, 10) catch error.UnrecognizedFormat; | 12696 | t.environ.zig_progress_handle = std.fmt.parseInt(u31, value, 10) catch error.UnrecognizedFormat; |
| 12697 | } else inline for (@typeInfo(Environ.String).@"struct".fields) |field| { | ||
| 12698 | if (std.mem.eql(u8, key, field.name)) @field(t.environ.string, field.name) = value; | ||
| 12717 | } | 12699 | } |
| 12718 | } | 12700 | } |
| 12719 | } | 12701 | } |
| ... | @@ -12966,12 +12948,10 @@ fn childKill(userdata: ?*anyopaque, child: *std.process.Child) void { | ... | @@ -12966,12 +12948,10 @@ fn childKill(userdata: ?*anyopaque, child: *std.process.Child) void { |
| 12966 | if (is_windows) { | 12948 | if (is_windows) { |
| 12967 | childKillWindows(t, child, 1) catch { | 12949 | childKillWindows(t, child, 1) catch { |
| 12968 | childCleanupStreams(child); | 12950 | childCleanupStreams(child); |
| 12969 | child.id = null; | ||
| 12970 | }; | 12951 | }; |
| 12971 | } else { | 12952 | } else { |
| 12972 | childKillPosix(t, child) catch { | 12953 | childKillPosix(t, child) catch { |
| 12973 | childCleanupStreams(child); | 12954 | childCleanupStreams(child); |
| 12974 | child.id = null; | ||
| 12975 | }; | 12955 | }; |
| 12976 | } | 12956 | } |
| 12977 | } | 12957 | } |
| ... | @@ -13012,7 +12992,6 @@ fn childWaitWindows(t: *Threaded, child: *process.Child) process.Child.WaitError | ... | @@ -13012,7 +12992,6 @@ fn childWaitWindows(t: *Threaded, child: *process.Child) process.Child.WaitError |
| 13012 | posix.close(child.id); | 12992 | posix.close(child.id); |
| 13013 | posix.close(child.thread_handle); | 12993 | posix.close(child.thread_handle); |
| 13014 | childCleanupStreams(child); | 12994 | childCleanupStreams(child); |
| 13015 | child.id = null; | ||
| 13016 | return term; | 12995 | return term; |
| 13017 | } | 12996 | } |
| 13018 | 12997 | ||
| ... | @@ -13028,10 +13007,8 @@ fn childWaitPosix(t: *Threaded, child: *process.Child) process.Child.WaitError!p | ... | @@ -13028,10 +13007,8 @@ fn childWaitPosix(t: *Threaded, child: *process.Child) process.Child.WaitError!p |
| 13028 | } | 13007 | } |
| 13029 | break :res posix.waitpid(pid, 0); | 13008 | break :res posix.waitpid(pid, 0); |
| 13030 | }; | 13009 | }; |
| 13031 | const status = res.status; | ||
| 13032 | childCleanupStreams(child); | 13010 | childCleanupStreams(child); |
| 13033 | child.id = null; | 13011 | return statusToTerm(res.status); |
| 13034 | return statusToTerm(status); | ||
| 13035 | } | 13012 | } |
| 13036 | 13013 | ||
| 13037 | fn statusToTerm(status: u32) process.Child.Term { | 13014 | fn statusToTerm(status: u32) process.Child.Term { |
| ... | @@ -13046,7 +13023,14 @@ fn statusToTerm(status: u32) process.Child.Term { | ... | @@ -13046,7 +13023,14 @@ fn statusToTerm(status: u32) process.Child.Term { |
| 13046 | } | 13023 | } |
| 13047 | 13024 | ||
| 13048 | fn childKillPosix(t: *Threaded, child: *process.Child) !void { | 13025 | fn childKillPosix(t: *Threaded, child: *process.Child) !void { |
| 13049 | try posix.kill(child.id.?, posix.SIG.TERM); | 13026 | while (true) switch (posix.errno(posix.system.kill(child.id.?, .TERM))) { |
| 13027 | .SUCCESS => break, | ||
| 13028 | .INTR => continue, | ||
| 13029 | .PERM => return error.PermissionDenied, | ||
| 13030 | .INVAL => |err| return errnoBug(err), | ||
| 13031 | .SRCH => |err| return errnoBug(err), | ||
| 13032 | else => |err| return posix.unexpectedErrno(err), | ||
| 13033 | }; | ||
| 13050 | _ = try childWaitPosix(t, child); | 13034 | _ = try childWaitPosix(t, child); |
| 13051 | } | 13035 | } |
| 13052 | 13036 | ||
| ... | @@ -13063,6 +13047,7 @@ fn childCleanupStreams(child: *process.Child) void { | ... | @@ -13063,6 +13047,7 @@ fn childCleanupStreams(child: *process.Child) void { |
| 13063 | posix.close(stderr.handle); | 13047 | posix.close(stderr.handle); |
| 13064 | child.stderr = null; | 13048 | child.stderr = null; |
| 13065 | } | 13049 | } |
| 13050 | child.id = null; | ||
| 13066 | } | 13051 | } |
| 13067 | 13052 | ||
| 13068 | /// Errors that can occur between fork() and execv() | 13053 | /// Errors that can occur between fork() and execv() |
| ... | @@ -14367,6 +14352,11 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File { | ... | @@ -14367,6 +14352,11 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File { |
| 14367 | } }; | 14352 | } }; |
| 14368 | } | 14353 | } |
| 14369 | 14354 | ||
| 14355 | pub fn environString(t: *Threaded, comptime name: []const u8) ?[:0]const u8 { | ||
| 14356 | t.scanEnviron(); | ||
| 14357 | return @field(t.environ.string, name); | ||
| 14358 | } | ||
| 14359 | |||
| 14370 | test { | 14360 | test { |
| 14371 | _ = @import("Threaded/test.zig"); | 14361 | _ = @import("Threaded/test.zig"); |
| 14372 | } | 14362 | } |
lib/std/debug/ElfFile.zig+7-5| ... | @@ -66,16 +66,17 @@ pub const DebugInfoSearchPaths = struct { | ... | @@ -66,16 +66,17 @@ pub const DebugInfoSearchPaths = struct { |
| 66 | .exe_dir = null, | 66 | .exe_dir = null, |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | pub fn native(exe_path: []const u8, io: Io) DebugInfoSearchPaths { | 69 | pub fn native(exe_path: []const u8) DebugInfoSearchPaths { |
| 70 | return .{ | 70 | if (std.options.elf_debug_info_search_paths) |f| return f(exe_path); |
| 71 | if (std.Options.debug_threaded_io) |t| return .{ | ||
| 71 | .debuginfod_client = p: { | 72 | .debuginfod_client = p: { |
| 72 | if (io.environ("DEBUGINFOD_CACHE_PATH")) |p| { | 73 | if (t.environString("DEBUGINFOD_CACHE_PATH")) |p| { |
| 73 | break :p .{ p, "" }; | 74 | break :p .{ p, "" }; |
| 74 | } | 75 | } |
| 75 | if (io.environ("XDG_CACHE_HOME")) |cache_path| { | 76 | if (t.environString("XDG_CACHE_HOME")) |cache_path| { |
| 76 | break :p .{ cache_path, "/debuginfod_client" }; | 77 | break :p .{ cache_path, "/debuginfod_client" }; |
| 77 | } | 78 | } |
| 78 | if (io.environ("HOME")) |home_path| { | 79 | if (t.environString("HOME")) |home_path| { |
| 79 | break :p .{ home_path, "/.cache/debuginfod_client" }; | 80 | break :p .{ home_path, "/.cache/debuginfod_client" }; |
| 80 | } | 81 | } |
| 81 | break :p null; | 82 | break :p null; |
| ... | @@ -85,6 +86,7 @@ pub const DebugInfoSearchPaths = struct { | ... | @@ -85,6 +86,7 @@ pub const DebugInfoSearchPaths = struct { |
| 85 | }, | 86 | }, |
| 86 | .exe_dir = std.fs.path.dirname(exe_path) orelse ".", | 87 | .exe_dir = std.fs.path.dirname(exe_path) orelse ".", |
| 87 | }; | 88 | }; |
| 89 | @compileError("std.Options.elf_debug_info_search_paths must be provided"); | ||
| 88 | } | 90 | } |
| 89 | }; | 91 | }; |
| 90 | 92 |
lib/std/debug/SelfInfo/Elf.zig+2-2| ... | @@ -327,7 +327,7 @@ const Module = struct { | ... | @@ -327,7 +327,7 @@ const Module = struct { |
| 327 | const load_result = if (mod.name.len > 0) res: { | 327 | const load_result = if (mod.name.len > 0) res: { |
| 328 | var file = Io.Dir.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; | 328 | var file = Io.Dir.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; |
| 329 | defer file.close(io); | 329 | defer file.close(io); |
| 330 | break :res std.debug.ElfFile.load(gpa, io, file, mod.build_id, &.native(mod.name, io)); | 330 | break :res std.debug.ElfFile.load(gpa, io, file, mod.build_id, &.native(mod.name)); |
| 331 | } else res: { | 331 | } else res: { |
| 332 | const path = std.process.executablePathAlloc(io, gpa) catch |err| switch (err) { | 332 | const path = std.process.executablePathAlloc(io, gpa) catch |err| switch (err) { |
| 333 | error.OutOfMemory => |e| return e, | 333 | error.OutOfMemory => |e| return e, |
| ... | @@ -336,7 +336,7 @@ const Module = struct { | ... | @@ -336,7 +336,7 @@ const Module = struct { |
| 336 | defer gpa.free(path); | 336 | defer gpa.free(path); |
| 337 | var file = Io.Dir.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; | 337 | var file = Io.Dir.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; |
| 338 | defer file.close(io); | 338 | defer file.close(io); |
| 339 | break :res std.debug.ElfFile.load(gpa, io, file, mod.build_id, &.native(path, io)); | 339 | break :res std.debug.ElfFile.load(gpa, io, file, mod.build_id, &.native(path)); |
| 340 | }; | 340 | }; |
| 341 | 341 | ||
| 342 | var elf_file = load_result catch |err| switch (err) { | 342 | var elf_file = load_result catch |err| switch (err) { |
lib/std/process/Child.zig+1-1| ... | @@ -106,7 +106,7 @@ pub const Term = union(enum) { | ... | @@ -106,7 +106,7 @@ pub const Term = union(enum) { |
| 106 | /// | 106 | /// |
| 107 | /// Uncancelable. Ignores unexpected errors from the operating system. | 107 | /// Uncancelable. Ignores unexpected errors from the operating system. |
| 108 | pub fn kill(child: *Child, io: Io) void { | 108 | pub fn kill(child: *Child, io: Io) void { |
| 109 | if (child.id != null) { | 109 | if (child.id == null) { |
| 110 | assert(child.stdin == null); | 110 | assert(child.stdin == null); |
| 111 | assert(child.stdout == null); | 111 | assert(child.stdout == null); |
| 112 | assert(child.stderr == null); | 112 | assert(child.stderr == null); |
lib/std/process/Environ.zig+2-2| ... | @@ -792,6 +792,6 @@ test "convert from Environ to Map and back again" { | ... | @@ -792,6 +792,6 @@ test "convert from Environ to Map and back again" { |
| 792 | var map2 = try environ.createMap(gpa); | 792 | var map2 = try environ.createMap(gpa); |
| 793 | defer map2.deinit(); | 793 | defer map2.deinit(); |
| 794 | 794 | ||
| 795 | try testing.expectEqualSlices([]const u8, map.keys(), map2.keys()); | 795 | try testing.expectEqualDeep(map.keys(), map2.keys()); |
| 796 | try testing.expectEqualSlices([]const u8, map.values(), map2.values()); | 796 | try testing.expectEqualDeep(map.values(), map2.values()); |
| 797 | } | 797 | } |
lib/std/std.zig+5| ... | @@ -173,6 +173,11 @@ pub const Options = struct { | ... | @@ -173,6 +173,11 @@ pub const Options = struct { |
| 173 | /// stack traces will just print an error to the relevant `Io.Writer` and return. | 173 | /// stack traces will just print an error to the relevant `Io.Writer` and return. |
| 174 | allow_stack_tracing: bool = !@import("builtin").strip_debug_info, | 174 | allow_stack_tracing: bool = !@import("builtin").strip_debug_info, |
| 175 | 175 | ||
| 176 | elf_debug_info_search_paths: ?fn (exe_path: []const u8) switch (@import("builtin").object_format) { | ||
| 177 | .elf => debug.ElfFile.DebugInfoSearchPaths, | ||
| 178 | else => void, | ||
| 179 | } = null, | ||
| 180 | |||
| 176 | pub const debug_threaded_io: ?*Io.Threaded = if (@hasDecl(root, "std_options_debug_threaded_io")) | 181 | pub const debug_threaded_io: ?*Io.Threaded = if (@hasDecl(root, "std_options_debug_threaded_io")) |
| 177 | root.std_options_debug_threaded_io | 182 | root.std_options_debug_threaded_io |
| 178 | else | 183 | else |