From aafddc2ea13e40a8262d9378aeca2e097a37ac03 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 5 Dec 2025 19:08:37 -0800 Subject: update all occurrences of close() to close(io) --- src/Compilation.zig | 64 ++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 931a0b2d14..df64dee19f 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -721,13 +721,13 @@ pub const Directories = struct { /// This may be the same as `global_cache`. local_cache: Cache.Directory, - pub fn deinit(dirs: *Directories) void { + pub fn deinit(dirs: *Directories, io: Io) void { // The local and global caches could be the same. const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; - dirs.global_cache.handle.close(); - if (close_local) dirs.local_cache.handle.close(); - dirs.zig_lib.handle.close(); + dirs.global_cache.handle.close(io); + if (close_local) dirs.local_cache.handle.close(io); + dirs.zig_lib.handle.close(io); } /// Returns a `Directories` where `local_cache` is replaced with `global_cache`, intended for @@ -1105,7 +1105,7 @@ pub const CObject = struct { if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; - defer file.close(); + defer file.close(io); var buffer: [1024]u8 = undefined; var file_reader = file.reader(io, &buffer); file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; @@ -1180,7 +1180,7 @@ pub const CObject = struct { var buffer: [1024]u8 = undefined; const file = try fs.cwd().openFile(path, .{}); - defer file.close(); + defer file.close(io); var file_reader = file.reader(io, &buffer); var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); defer bc.deinit(); @@ -1617,13 +1617,13 @@ const CacheUse = union(CacheMode) { } }; - fn deinit(cu: CacheUse) void { + fn deinit(cu: CacheUse, io: Io) void { switch (cu) { .none => |none| { assert(none.tmp_artifact_directory == null); }, .incremental => |incremental| { - incremental.artifact_directory.handle.close(); + incremental.artifact_directory.handle.close(io); }, .whole => |whole| { assert(whole.tmp_artifact_directory == null); @@ -2113,7 +2113,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, cache.addPrefix(options.dirs.zig_lib); cache.addPrefix(options.dirs.local_cache); cache.addPrefix(options.dirs.global_cache); - errdefer cache.manifest_dir.close(); + errdefer cache.manifest_dir.close(io); // This is shared hasher state common to zig source and all C source files. cache.hash.addBytes(build_options.version); @@ -2157,7 +2157,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } }); }; - errdefer local_zir_dir.close(); + errdefer local_zir_dir.close(io); const local_zir_cache: Cache.Directory = .{ .handle = local_zir_dir, .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), @@ -2165,7 +2165,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } }); }; - errdefer global_zir_dir.close(); + errdefer global_zir_dir.close(io); const global_zir_cache: Cache.Directory = .{ .handle = global_zir_dir, .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}), @@ -2436,7 +2436,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } }); }; - errdefer artifact_dir.close(); + errdefer artifact_dir.close(io); const artifact_directory: Cache.Directory = .{ .handle = artifact_dir, .path = try options.dirs.local_cache.join(arena, &.{artifact_sub_dir}), @@ -2689,6 +2689,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, pub fn destroy(comp: *Compilation) void { const gpa = comp.gpa; + const io = comp.io; if (comp.bin_file) |lf| lf.destroy(); if (comp.zcu) |zcu| zcu.deinit(); @@ -2760,7 +2761,7 @@ pub fn destroy(comp: *Compilation) void { comp.clearMiscFailures(); - comp.cache_parent.manifest_dir.close(); + comp.cache_parent.manifest_dir.close(io); } pub fn clearMiscFailures(comp: *Compilation) void { @@ -2791,10 +2792,12 @@ pub fn hotCodeSwap( } fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { + const io = comp.io; + switch (comp.cache_use) { .none => |none| { if (none.tmp_artifact_directory) |*tmp_dir| { - tmp_dir.handle.close(); + tmp_dir.handle.close(io); none.tmp_artifact_directory = null; if (dev.env == .bootstrap) { // zig1 uses `CacheMode.none`, but it doesn't need to know how to delete @@ -2834,7 +2837,7 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { comp.bin_file = null; } if (whole.tmp_artifact_directory) |*tmp_dir| { - tmp_dir.handle.close(); + tmp_dir.handle.close(io); whole.tmp_artifact_directory = null; const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| { @@ -3152,7 +3155,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE // the file handle and re-open it in the follow up call to // `makeWritable`. if (lf.file) |f| { - f.close(); + f.close(io); lf.file = null; if (lf.closeDebugInfo()) break :w .lf_and_debug; @@ -3165,7 +3168,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE // Rename the temporary directory into place. // Close tmp dir and link.File to avoid open handle during rename. - whole.tmp_artifact_directory.?.handle.close(); + whole.tmp_artifact_directory.?.handle.close(io); whole.tmp_artifact_directory = null; const s = fs.path.sep_str; const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); @@ -5258,6 +5261,7 @@ fn workerDocsCopy(comp: *Compilation) void { fn docsCopyFallible(comp: *Compilation) anyerror!void { const zcu = comp.zcu orelse return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{}); + const io = comp.io; const docs_path = comp.resolveEmitPath(comp.emit_docs.?); var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| { @@ -5267,7 +5271,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { .{ docs_path, @errorName(err) }, ); }; - defer out_dir.close(); + defer out_dir.close(io); for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { const basename = fs.path.basename(sub_path); @@ -5287,7 +5291,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { .{ docs_path, @errorName(err) }, ); }; - defer tar_file.close(); + defer tar_file.close(io); var buffer: [1024]u8 = undefined; var tar_file_writer = tar_file.writer(&buffer); @@ -5331,7 +5335,7 @@ fn docsCopyModule( } catch |err| { return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err }); }; - defer mod_dir.close(); + defer mod_dir.close(io); var walker = try mod_dir.walk(comp.gpa); defer walker.deinit(); @@ -5355,7 +5359,7 @@ fn docsCopyModule( root.fmt(comp), entry.path, err, }); }; - defer file.close(); + defer file.close(io); const stat = try file.stat(); var file_reader: fs.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); @@ -5510,7 +5514,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU ); return error.AlreadyReported; }; - defer out_dir.close(); + defer out_dir.close(io); crt_file.full_object_path.root_dir.handle.copyFile( crt_file.full_object_path.sub_path, @@ -5693,7 +5697,7 @@ pub fn translateC( const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename; const cache_dir = comp.dirs.local_cache.handle; var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{}); - defer cache_tmp_dir.close(); + defer cache_tmp_dir.close(io); const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename }); const source_path = switch (source) { @@ -6268,7 +6272,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr // so we need a temporary filename. const out_obj_path = try comp.tmpFilePath(arena, o_basename); var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); - defer zig_cache_tmp_dir.close(); + defer zig_cache_tmp_dir.close(io); const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) null @@ -6433,7 +6437,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); - defer o_dir.close(); + defer o_dir.close(io); const tmp_basename = fs.path.basename(out_obj_path); try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); break :blk digest; @@ -6477,8 +6481,6 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const tracy_trace = trace(@src()); defer tracy_trace.end(); - const io = comp.io; - const src_path = switch (win32_resource.src) { .rc => |rc_src| rc_src.src_path, .manifest => |src_path| src_path, @@ -6487,6 +6489,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 log.debug("updating win32 resource: {s}", .{src_path}); + const io = comp.io; + var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -6522,7 +6526,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const o_sub_path = try fs.path.join(arena, &.{ "o", &digest }); var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); - defer o_dir.close(); + defer o_dir.close(io); const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ o_sub_path, rc_basename, @@ -6610,7 +6614,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const digest = if (try man.hit()) man.final() else blk: { var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); - defer zig_cache_tmp_dir.close(); + defer zig_cache_tmp_dir.close(io); const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); @@ -6681,7 +6685,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); - defer o_dir.close(); + defer o_dir.close(io); const tmp_basename = fs.path.basename(out_res_path); try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); break :blk digest; -- cgit v1.2.3 From 3204fb756980c19b7a95534acdd7a1bba837fbc3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 6 Dec 2025 17:23:07 -0800 Subject: update all occurrences of std.fs.File to std.Io.File --- lib/compiler/aro/aro/Compilation.zig | 4 +- lib/compiler/aro/aro/Driver.zig | 15 +++---- lib/compiler/aro/aro/Preprocessor.zig | 3 +- lib/compiler/aro/backend/Assembly.zig | 3 +- lib/compiler/aro/main.zig | 3 +- lib/compiler/build_runner.zig | 6 +-- lib/compiler/libc.zig | 3 +- lib/compiler/objcopy.zig | 13 +++--- lib/compiler/reduce.zig | 3 +- lib/compiler/resinator/cli.zig | 3 +- lib/compiler/resinator/errors.zig | 8 ++-- lib/compiler/resinator/main.zig | 10 ++--- lib/compiler/resinator/utils.zig | 4 +- lib/compiler/test_runner.zig | 10 ++--- lib/compiler/translate-c/main.zig | 13 +++--- lib/std/Build.zig | 6 +-- lib/std/Build/Step.zig | 2 +- lib/std/Build/Step/ObjCopy.zig | 2 +- lib/std/Build/Step/Run.zig | 21 +++++----- lib/std/Io.zig | 2 +- lib/std/Io/Writer.zig | 9 ++-- lib/std/Io/test.zig | 2 +- lib/std/Io/tty.zig | 7 ++-- lib/std/Progress.zig | 18 ++++---- lib/std/Random/benchmark.zig | 6 ++- lib/std/Thread.zig | 4 +- lib/std/crypto/Certificate/Bundle.zig | 8 ++-- lib/std/crypto/Certificate/Bundle/macos.zig | 2 +- lib/std/crypto/benchmark.zig | 8 ++-- lib/std/debug.zig | 6 +-- lib/std/debug/ElfFile.zig | 4 +- lib/std/debug/Info.zig | 2 +- lib/std/debug/Pdb.zig | 2 +- lib/std/debug/SelfInfo/Windows.zig | 2 +- lib/std/debug/simple_panic.zig | 2 +- lib/std/dynamic_library.zig | 2 +- lib/std/fs/test.zig | 8 ++-- lib/std/hash/benchmark.zig | 5 ++- lib/std/http.zig | 2 +- lib/std/pdb.zig | 2 +- lib/std/posix/test.zig | 18 ++++---- lib/std/process/Child.zig | 4 +- lib/std/unicode/throughput_test.zig | 6 +-- lib/std/zig/Zir.zig | 8 ++-- lib/std/zig/Zoir.zig | 15 +++---- lib/std/zig/llvm/Builder.zig | 4 +- lib/std/zig/perf_test.zig | 3 +- lib/std/zip.zig | 5 ++- src/Compilation.zig | 4 +- src/Package/Fetch.zig | 16 +++---- src/Package/Fetch/git.zig | 22 +++++----- src/Zcu.zig | 8 ++-- src/Zcu/PerThread.zig | 6 +-- src/fmt.zig | 16 +++---- src/link.zig | 20 ++++----- src/link/Dwarf.zig | 53 ++++++++++++----------- src/link/Elf.zig | 5 ++- src/link/Elf/Object.zig | 65 +++++++++++++++-------------- src/link/Elf/SharedObject.zig | 37 ++++++++-------- src/link/Elf/file.zig | 35 ++++++++-------- src/link/Elf2.zig | 46 ++++++++++---------- src/link/MachO.zig | 23 +++++----- src/link/MachO/CodeSignature.zig | 8 ++-- src/link/MachO/fat.zig | 12 +++--- src/link/MachO/file.zig | 3 +- src/link/MachO/hasher.zig | 22 +++++----- src/link/MachO/uuid.zig | 19 ++++----- src/link/MappedFile.zig | 25 ++++++----- src/link/Wasm.zig | 5 ++- src/link/tapi.zig | 10 ++--- 70 files changed, 399 insertions(+), 359 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index 9fb8123146..06b27c33bb 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -1646,7 +1646,7 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin return comp.addSourceFromFile(file, path, kind); } -pub fn addSourceFromFile(comp: *Compilation, file: std.fs.File, path: []const u8, kind: Source.Kind) !Source { +pub fn addSourceFromFile(comp: *Compilation, file: Io.File, path: []const u8, kind: Source.Kind) !Source { const contents = try comp.getFileContents(file, .unlimited); errdefer comp.gpa.free(contents); return comp.addSourceFromOwnedBuffer(path, contents, kind); @@ -1980,7 +1980,7 @@ fn getPathContents(comp: *Compilation, path: []const u8, limit: Io.Limit) ![]u8 return comp.getFileContents(file, limit); } -fn getFileContents(comp: *Compilation, file: std.fs.File, limit: Io.Limit) ![]u8 { +fn getFileContents(comp: *Compilation, file: Io.File, limit: Io.Limit) ![]u8 { var file_buf: [4096]u8 = undefined; var file_reader = file.reader(comp.io, &file_buf); diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index 888ade2be4..f933e3ce52 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Allocator = mem.Allocator; const process = std.process; @@ -1061,7 +1062,7 @@ pub fn printDiagnosticsStats(d: *Driver) void { } } -pub fn detectConfig(d: *Driver, file: std.fs.File) std.Io.tty.Config { +pub fn detectConfig(d: *Driver, file: Io.File) std.Io.tty.Config { if (d.diagnostics.color == false) return .no_color; const force_color = d.diagnostics.color == true; @@ -1109,7 +1110,7 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_ defer macro_buf.deinit(d.comp.gpa); var stdout_buf: [256]u8 = undefined; - var stdout = std.fs.File.stdout().writer(&stdout_buf); + var stdout = Io.File.stdout().writer(&stdout_buf); if (parseArgs(d, &stdout.interface, ¯o_buf, args) catch |er| switch (er) { error.WriteFailed => return d.fatal("failed to write to stdout: {s}", .{errorDescription(er)}), error.OutOfMemory => return error.OutOfMemory, @@ -1329,7 +1330,7 @@ fn processSource( d.comp.cwd.createFile(path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) }) else - std.fs.File.stdout(); + Io.File.stdout(); defer if (dep_file_name != null) file.close(io); var file_writer = file.writer(&writer_buf); @@ -1354,7 +1355,7 @@ fn processSource( d.comp.cwd.createFile(some, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) else - std.fs.File.stdout(); + Io.File.stdout(); defer if (d.output_name != null) file.close(io); var file_writer = file.writer(&writer_buf); @@ -1369,7 +1370,7 @@ fn processSource( defer tree.deinit(); if (d.verbose_ast) { - var stdout = std.fs.File.stdout().writer(&writer_buf); + var stdout = Io.File.stdout().writer(&writer_buf); tree.dump(d.detectConfig(stdout.file), &stdout.interface) catch {}; } @@ -1433,7 +1434,7 @@ fn processSource( defer ir.deinit(gpa); if (d.verbose_ir) { - var stdout = std.fs.File.stdout().writer(&writer_buf); + var stdout = Io.File.stdout().writer(&writer_buf); ir.dump(gpa, d.detectConfig(stdout.file), &stdout.interface) catch {}; } @@ -1499,7 +1500,7 @@ pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) Compil if (d.verbose_linker_args) { var stdout_buf: [4096]u8 = undefined; - var stdout = std.fs.File.stdout().writer(&stdout_buf); + var stdout = Io.File.stdout().writer(&stdout_buf); dumpLinkerArgs(&stdout.interface, argv.items) catch { return d.fatal("unable to dump linker args: {s}", .{errorDescription(stdout.err.?)}); }; diff --git a/lib/compiler/aro/aro/Preprocessor.zig b/lib/compiler/aro/aro/Preprocessor.zig index 6bd1206aff..d47727cbf0 100644 --- a/lib/compiler/aro/aro/Preprocessor.zig +++ b/lib/compiler/aro/aro/Preprocessor.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Allocator = mem.Allocator; const assert = std.debug.assert; @@ -1068,7 +1069,7 @@ fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start }); var stderr_buf: [4096]u8 = undefined; - var stderr = std.fs.File.stderr().writer(&stderr_buf); + var stderr = Io.File.stderr().writer(&stderr_buf); const w = &stderr.interface; w.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return; diff --git a/lib/compiler/aro/backend/Assembly.zig b/lib/compiler/aro/backend/Assembly.zig index d0d14bdd77..80143bf97f 100644 --- a/lib/compiler/aro/backend/Assembly.zig +++ b/lib/compiler/aro/backend/Assembly.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; data: []const u8, @@ -11,7 +12,7 @@ pub fn deinit(self: *const Assembly, gpa: Allocator) void { gpa.free(self.text); } -pub fn writeToFile(self: Assembly, file: std.fs.File) !void { +pub fn writeToFile(self: Assembly, file: Io.File) !void { var file_writer = file.writer(&.{}); var buffers = [_][]const u8{ self.data, self.text }; diff --git a/lib/compiler/aro/main.zig b/lib/compiler/aro/main.zig index d3655e43da..66c8add4a3 100644 --- a/lib/compiler/aro/main.zig +++ b/lib/compiler/aro/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const Allocator = mem.Allocator; const mem = std.mem; const process = std.process; @@ -50,7 +51,7 @@ pub fn main() u8 { defer gpa.free(aro_name); var stderr_buf: [1024]u8 = undefined; - var stderr = std.fs.File.stderr().writer(&stderr_buf); + var stderr = Io.File.stderr().writer(&stderr_buf); var diagnostics: Diagnostics = .{ .output = .{ .to_writer = .{ .color = .detect(stderr.file), diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 2c8d71e3e2..6e0e2d8eca 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -7,7 +7,7 @@ const assert = std.debug.assert; const fmt = std.fmt; const mem = std.mem; const process = std.process; -const File = std.fs.File; +const File = std.Io.File; const Step = std.Build.Step; const Watch = std.Build.Watch; const WebServer = std.Build.WebServer; @@ -1845,9 +1845,9 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { } var stdio_buffer_allocation: [256]u8 = undefined; -var stdout_writer_allocation: std.fs.File.Writer = undefined; +var stdout_writer_allocation: Io.File.Writer = undefined; fn initStdoutWriter() *Writer { - stdout_writer_allocation = std.fs.File.stdout().writerStreaming(&stdio_buffer_allocation); + stdout_writer_allocation = Io.File.stdout().writerStreaming(&stdio_buffer_allocation); return &stdout_writer_allocation.interface; } diff --git a/lib/compiler/libc.zig b/lib/compiler/libc.zig index a18a7a0e06..142b87062e 100644 --- a/lib/compiler/libc.zig +++ b/lib/compiler/libc.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const LibCInstallation = std.zig.LibCInstallation; @@ -39,7 +40,7 @@ pub fn main() !void { var input_file: ?[]const u8 = null; var target_arch_os_abi: []const u8 = "native"; var print_includes: bool = false; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; { var i: usize = 2; diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index 1608c121b1..c360ea8df0 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -1,12 +1,13 @@ const builtin = @import("builtin"); + const std = @import("std"); +const Io = std.Io; const mem = std.mem; const fs = std.fs; const elf = std.elf; const Allocator = std.mem.Allocator; -const File = std.fs.File; +const File = std.Io.File; const assert = std.debug.assert; - const fatal = std.process.fatal; const Server = std.zig.Server; @@ -56,7 +57,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void fatal("unexpected positional argument: '{s}'", .{arg}); } } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - return std.fs.File.stdout().writeAll(usage); + return Io.File.stdout().writeAll(usage); } else if (mem.eql(u8, arg, "-O") or mem.eql(u8, arg, "--output-target")) { i += 1; if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); @@ -177,7 +178,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void } }; - const mode = if (out_fmt != .elf or only_keep_debug) fs.File.default_mode else stat.mode; + const mode = if (out_fmt != .elf or only_keep_debug) Io.File.default_mode else stat.mode; var output_file = try fs.cwd().createFile(output, .{ .mode = mode }); defer output_file.close(io); @@ -221,8 +222,8 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void try out.end(); if (listen) { - var stdin_reader = fs.File.stdin().reader(io, &stdin_buffer); - var stdout_writer = fs.File.stdout().writer(&stdout_buffer); + var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); var server = try Server.init(.{ .in = &stdin_reader.interface, .out = &stdout_writer.interface, diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index 28305e801b..bbd3d172b4 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Allocator = std.mem.Allocator; const assert = std.debug.assert; @@ -68,7 +69,7 @@ pub fn main() !void { const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - const stdout = std.fs.File.stdout(); + const stdout = Io.File.stdout(); try stdout.writeAll(usage); return std.process.cleanExit(); } else if (mem.eql(u8, arg, "--")) { diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index ffaa62e7ca..17da5c7b75 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const code_pages = @import("code_pages.zig"); const SupportedCodePage = code_pages.SupportedCodePage; const lang = @import("lang.zig"); @@ -169,7 +170,7 @@ pub const Options = struct { coff_options: cvtres.CoffOptions = .{}, pub const IoSource = union(enum) { - stdio: std.fs.File, + stdio: Io.File, filename: []const u8, }; pub const AutoIncludes = enum { any, msvc, gnu, none }; diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 8509aa610f..61fd00e683 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -169,9 +169,9 @@ pub const ErrorDetails = struct { filename_string_index: FilenameStringIndex, pub const FilenameStringIndex = std.meta.Int(.unsigned, 32 - @bitSizeOf(FileOpenErrorEnum)); - pub const FileOpenErrorEnum = std.meta.FieldEnum(std.fs.File.OpenError || std.fs.File.StatError); + pub const FileOpenErrorEnum = std.meta.FieldEnum(Io.File.OpenError || Io.File.StatError); - pub fn enumFromError(err: (std.fs.File.OpenError || std.fs.File.StatError)) FileOpenErrorEnum { + pub fn enumFromError(err: (Io.File.OpenError || Io.File.StatError)) FileOpenErrorEnum { return switch (err) { inline else => |e| @field(ErrorDetails.FileOpenError.FileOpenErrorEnum, @errorName(e)), }; @@ -1094,8 +1094,8 @@ const CorrespondingLines = struct { last_byte: u8 = 0, at_eof: bool = false, span: SourceMappings.CorrespondingSpan, - file: std.fs.File, - file_reader: std.fs.File.Reader, + file: Io.File, + file_reader: Io.File.Reader, code_page: SupportedCodePage, pub fn init( diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 42308a8987..e171d8199c 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -45,7 +45,7 @@ pub fn main() !void { } var stdout_buffer: [1024]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; var error_handler: ErrorHandler = switch (zig_integration) { true => .{ @@ -447,8 +447,8 @@ const IoStream = struct { } pub const Source = union(enum) { - file: std.fs.File, - stdio: std.fs.File, + file: Io.File, + stdio: Io.File, memory: std.ArrayList(u8), /// The source has been closed and any usage of the Source in this state is illegal (except deinit). closed: void, @@ -500,10 +500,10 @@ const IoStream = struct { } pub const Writer = union(enum) { - file: std.fs.File.Writer, + file: Io.File.Writer, allocating: std.Io.Writer.Allocating, - pub const Error = Allocator.Error || std.fs.File.WriteError; + pub const Error = Allocator.Error || Io.File.WriteError; pub fn interface(this: *@This()) *std.Io.Writer { return switch (this.*) { diff --git a/lib/compiler/resinator/utils.zig b/lib/compiler/resinator/utils.zig index f8080539cb..e8565f3af9 100644 --- a/lib/compiler/resinator/utils.zig +++ b/lib/compiler/resinator/utils.zig @@ -32,8 +32,8 @@ pub fn openFileNotDir( cwd: std.fs.Dir, io: Io, path: []const u8, - flags: std.fs.File.OpenFlags, -) (std.fs.File.OpenError || std.fs.File.StatError)!std.fs.File { + flags: Io.File.OpenFlags, +) (Io.File.OpenError || Io.File.StatError)!Io.File { const file = try cwd.openFile(io, path, flags); errdefer file.close(io); // https://github.com/ziglang/zig/issues/5732 diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 72ed3e7677..07a6724ec0 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -74,8 +74,8 @@ pub fn main() void { fn mainServer() !void { @disableInstrumentation(); - var stdin_reader = std.fs.File.stdin().readerStreaming(runner_threaded_io.io(), &stdin_buffer); - var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); + var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io.io(), &stdin_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); var server = try std.zig.Server.init(.{ .in = &stdin_reader.interface, .out = &stdout_writer.interface, @@ -228,7 +228,7 @@ fn mainTerminal() void { .root_name = "Test", .estimated_total_items = test_fn_list.len, }); - const have_tty = std.fs.File.stderr().isTty(); + const have_tty = Io.File.stderr().isTty(); var leaks: usize = 0; for (test_fn_list, 0..) |test_fn, i| { @@ -318,7 +318,7 @@ pub fn log( /// work-in-progress backends can handle it. pub fn mainSimple() anyerror!void { @disableInstrumentation(); - // is the backend capable of calling `std.fs.File.writeAll`? + // is the backend capable of calling `Io.File.writeAll`? const enable_write = switch (builtin.zig_backend) { .stage2_aarch64, .stage2_riscv64 => true, else => false, @@ -334,7 +334,7 @@ pub fn mainSimple() anyerror!void { var failed: u64 = 0; // we don't want to bring in File and Writer if the backend doesn't support it - const stdout = if (enable_write) std.fs.File.stdout() else {}; + const stdout = if (enable_write) Io.File.stdout() else {}; for (builtin.test_functions) |test_fn| { if (enable_write) { diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index 0c72298b30..830c70e424 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const mem = std.mem; const process = std.process; @@ -34,7 +35,7 @@ pub fn main() u8 { } var stderr_buf: [1024]u8 = undefined; - var stderr = std.fs.File.stderr().writer(&stderr_buf); + var stderr = Io.File.stderr().writer(&stderr_buf); var diagnostics: aro.Diagnostics = switch (zig_integration) { false => .{ .output = .{ .to_writer = .{ .color = .detect(stderr.file), @@ -99,7 +100,7 @@ fn serveErrorBundle(arena: std.mem.Allocator, diagnostics: *const aro.Diagnostic "translation failure", ); var stdout_buffer: [1024]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); var server: std.zig.Server = .{ .out = &stdout_writer.interface, .in = undefined, @@ -129,13 +130,13 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration args[i] = arg; if (mem.eql(u8, arg, "--help")) { var stdout_buf: [512]u8 = undefined; - var stdout = std.fs.File.stdout().writer(&stdout_buf); + var stdout = Io.File.stdout().writer(&stdout_buf); try stdout.interface.print(usage, .{args[0]}); try stdout.interface.flush(); return; } else if (mem.eql(u8, arg, "--version")) { var stdout_buf: [512]u8 = undefined; - var stdout = std.fs.File.stdout().writer(&stdout_buf); + var stdout = Io.File.stdout().writer(&stdout_buf); // TODO add version try stdout.interface.writeAll("0.0.0-dev\n"); try stdout.interface.flush(); @@ -228,7 +229,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration d.comp.cwd.createFile(path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) }) else - std.fs.File.stdout(); + Io.File.stdout(); defer if (dep_file_name != null) file.close(io); var file_writer = file.writer(&out_buf); @@ -246,7 +247,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration var close_out_file = false; var out_file_path: []const u8 = ""; - var out_file: std.fs.File = .stdout(); + var out_file: Io.File = .stdout(); defer if (close_out_file) out_file.close(io); if (d.output_name) |path| blk: { diff --git a/lib/std/Build.zig b/lib/std/Build.zig index fcd94ce134..2755b895c2 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1,3 +1,4 @@ +const Build = @This(); const builtin = @import("builtin"); const std = @import("std.zig"); @@ -9,13 +10,12 @@ const panic = std.debug.panic; const assert = debug.assert; const log = std.log; const StringHashMap = std.StringHashMap; -const Allocator = mem.Allocator; +const Allocator = std.mem.Allocator; const Target = std.Target; const process = std.process; const EnvMap = std.process.EnvMap; -const File = fs.File; +const File = std.Io.File; const Sha256 = std.crypto.hash.sha2.Sha256; -const Build = @This(); const ArrayList = std.ArrayList; pub const Cache = @import("Build/Cache.zig"); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index acde47071d..2b1e6d8ace 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -667,7 +667,7 @@ fn clearZigProcess(s: *Step, gpa: Allocator) void { } } -fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { +fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 0, diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index b5f058ddfc..4aa1c0a9dc 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -3,7 +3,7 @@ const ObjCopy = @This(); const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; -const File = std.fs.File; +const File = std.Io.File; const InstallDir = std.Build.InstallDir; const Step = std.Build.Step; const elf = std.elf; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index e66e30cc79..1df6f42a35 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1,15 +1,16 @@ -const std = @import("std"); +const Run = @This(); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const Build = std.Build; -const Step = Build.Step; +const Step = std.Build.Step; const fs = std.fs; const mem = std.mem; const process = std.process; -const EnvMap = process.EnvMap; +const EnvMap = std.process.EnvMap; const assert = std.debug.assert; -const Path = Build.Cache.Path; - -const Run = @This(); +const Path = std.Build.Cache.Path; pub const base_id: Step.Id = .run; @@ -2095,7 +2096,7 @@ pub const CachedTestMetadata = struct { } }; -fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { +fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { while (metadata.next_index < metadata.names.len) { const i = metadata.next_index; metadata.next_index += 1; @@ -2114,7 +2115,7 @@ fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr } } -fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { +fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 0, @@ -2125,7 +2126,7 @@ fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { }; } -fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index: u32) !void { +fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 4, @@ -2140,7 +2141,7 @@ fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index: } fn sendRunFuzzTestMessage( - file: std.fs.File, + file: Io.File, index: u32, kind: std.Build.abi.fuzz.LimitKind, amount_or_instance: u64, diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 0727e3efd3..f783718cef 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -528,7 +528,7 @@ pub fn Poller(comptime StreamEnum: type) type { /// Given an enum, returns a struct with fields of that enum, each field /// representing an I/O stream for polling. pub fn PollFiles(comptime StreamEnum: type) type { - return @Struct(.auto, null, std.meta.fieldNames(StreamEnum), &@splat(std.fs.File), &@splat(.{})); + return @Struct(.auto, null, std.meta.fieldNames(StreamEnum), &@splat(Io.File), &@splat(.{})); } test { diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 5601293cfb..3f25bc6a26 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -1,7 +1,8 @@ +const Writer = @This(); + const builtin = @import("builtin"); const native_endian = builtin.target.cpu.arch.endian(); -const Writer = @This(); const std = @import("../std.zig"); const assert = std.debug.assert; const Limit = std.Io.Limit; @@ -2837,7 +2838,7 @@ test "discarding sendFile" { const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [256]u8 = undefined; - var file_writer: std.fs.File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, &r_buffer); try file_writer.interface.writeByte('h'); try file_writer.interface.flush(); @@ -2859,7 +2860,7 @@ test "allocating sendFile" { const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; - var file_writer: std.fs.File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, &r_buffer); try file_writer.interface.writeAll("abcd"); try file_writer.interface.flush(); @@ -2883,7 +2884,7 @@ test sendFileReading { const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; - var file_writer: std.fs.File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, &r_buffer); try file_writer.interface.writeAll("abcd"); try file_writer.interface.flush(); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index 9ea2d48ee5..b922acc333 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -10,7 +10,7 @@ const expectError = std.testing.expectError; const DefaultPrng = std.Random.DefaultPrng; const mem = std.mem; const fs = std.fs; -const File = std.fs.File; +const File = std.Io.File; const assert = std.debug.assert; const tmpDir = std.testing.tmpDir; diff --git a/lib/std/Io/tty.zig b/lib/std/Io/tty.zig index 08e0bd71f0..d1f8b576c2 100644 --- a/lib/std/Io/tty.zig +++ b/lib/std/Io/tty.zig @@ -1,9 +1,10 @@ -const std = @import("std"); const builtin = @import("builtin"); -const File = std.fs.File; +const native_os = builtin.os.tag; + +const std = @import("std"); +const File = std.Io.File; const process = std.process; const windows = std.os.windows; -const native_os = builtin.os.tag; pub const Color = enum { black, diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 467d4754ff..d8b22c2db0 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -1,19 +1,21 @@ //! This API is non-allocating, non-fallible, thread-safe, and lock-free. +const Progress = @This(); -const std = @import("std"); const builtin = @import("builtin"); +const is_big_endian = builtin.cpu.arch.endian() == .big; +const is_windows = builtin.os.tag == .windows; + +const std = @import("std"); +const Io = std.Io; const windows = std.os.windows; const testing = std.testing; const assert = std.debug.assert; -const Progress = @This(); const posix = std.posix; -const is_big_endian = builtin.cpu.arch.endian() == .big; -const is_windows = builtin.os.tag == .windows; const Writer = std.Io.Writer; /// `null` if the current node (and its children) should /// not print on update() -terminal: std.fs.File, +terminal: Io.File, terminal_mode: TerminalMode, @@ -472,7 +474,7 @@ pub fn start(options: Options) Node { if (options.disable_printing) { return Node.none; } - const stderr: std.fs.File = .stderr(); + const stderr: Io.File = .stderr(); global_progress.terminal = stderr; if (stderr.enableAnsiEscapeCodes()) |_| { global_progress.terminal_mode = .ansi_escape_codes; @@ -633,8 +635,8 @@ pub fn unlockStdErr() void { /// Protected by `stderr_mutex`. const stderr_writer: *Writer = &stderr_file_writer.interface; /// Protected by `stderr_mutex`. -var stderr_file_writer: std.fs.File.Writer = .{ - .interface = std.fs.File.Writer.initInterface(&.{}), +var stderr_file_writer: Io.File.Writer = .{ + .interface = Io.File.Writer.initInterface(&.{}), .file = if (is_windows) undefined else .stderr(), .mode = .streaming, }; diff --git a/lib/std/Random/benchmark.zig b/lib/std/Random/benchmark.zig index 57dc69051e..97afe23b95 100644 --- a/lib/std/Random/benchmark.zig +++ b/lib/std/Random/benchmark.zig @@ -1,7 +1,9 @@ // zig run -O ReleaseFast --zig-lib-dir ../.. benchmark.zig -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const time = std.time; const Timer = time.Timer; const Random = std.Random; @@ -123,7 +125,7 @@ fn mode(comptime x: comptime_int) comptime_int { pub fn main() !void { var stdout_buffer: [0x100]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; var buffer: [1024]u8 = undefined; diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 9f532c3bec..8d8e5979df 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -175,7 +175,7 @@ pub const SetNameError = error{ Unsupported, Unexpected, InvalidWtf8, -} || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError; +} || posix.PrctlError || posix.WriteError || Io.File.OpenError || std.fmt.BufPrintError; pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { if (name.len > max_name_len) return error.NameTooLong; @@ -293,7 +293,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { pub const GetNameError = error{ Unsupported, Unexpected, -} || posix.PrctlError || posix.ReadError || std.fs.File.OpenError || std.fmt.BufPrintError; +} || posix.PrctlError || posix.ReadError || Io.File.OpenError || std.fmt.BufPrintError; /// On Windows, the result is encoded as [WTF-8](https://wtf-8.codeberg.page/). /// On other platforms, the result is an opaque sequence of bytes with no particular encoding. diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 9541e01db5..1d21918b5c 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -171,7 +171,7 @@ fn rescanWindows(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanW cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); } -pub const AddCertsFromDirPathError = fs.File.OpenError || AddCertsFromDirError; +pub const AddCertsFromDirPathError = Io.File.OpenError || AddCertsFromDirError; pub fn addCertsFromDirPath( cb: *Bundle, @@ -212,7 +212,7 @@ pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, i } } -pub const AddCertsFromFilePathError = fs.File.OpenError || AddCertsFromFileError || Io.Clock.Error; +pub const AddCertsFromFilePathError = Io.File.OpenError || AddCertsFromFileError || Io.Clock.Error; pub fn addCertsFromFilePathAbsolute( cb: *Bundle, @@ -242,8 +242,8 @@ pub fn addCertsFromFilePath( } pub const AddCertsFromFileError = Allocator.Error || - fs.File.GetSeekPosError || - fs.File.ReadError || + Io.File.GetSeekPosError || + Io.File.ReadError || ParseCertError || std.base64.Error || error{ CertificateAuthorityBundleTooBig, MissingEndCertificateMarker, Streaming }; diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index d32f1be8e0..473505ac51 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -6,7 +6,7 @@ const mem = std.mem; const Allocator = std.mem.Allocator; const Bundle = @import("../Bundle.zig"); -pub const RescanMacError = Allocator.Error || fs.File.OpenError || fs.File.ReadError || fs.File.SeekError || Bundle.ParseCertError || error{EndOfStream}; +pub const RescanMacError = Allocator.Error || Io.File.OpenError || Io.File.ReadError || Io.File.SeekError || Bundle.ParseCertError || error{EndOfStream}; pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanMacError!void { cb.bytes.clearRetainingCapacity(); diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index 54024f070e..1b71110be5 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -1,10 +1,12 @@ // zig run -O ReleaseFast --zig-lib-dir ../.. benchmark.zig -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const mem = std.mem; const time = std.time; -const Timer = time.Timer; +const Timer = std.time.Timer; const crypto = std.crypto; const KiB = 1024; @@ -504,7 +506,7 @@ fn mode(comptime x: comptime_int) comptime_int { pub fn main() !void { // Size of buffer is about size of printed message. var stdout_buffer: [0x100]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 0cb96ed593..97741ecb40 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -8,7 +8,7 @@ const posix = std.posix; const fs = std.fs; const testing = std.testing; const Allocator = mem.Allocator; -const File = std.fs.File; +const File = std.Io.File; const windows = std.os.windows; const builtin = @import("builtin"); @@ -575,7 +575,7 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - fs.File.stderr().writeAll("aborting due to recursive panic\n") catch {}; + File.stderr().writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } @@ -1596,7 +1596,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex // A segfault happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - fs.File.stderr().writeAll("aborting due to recursive panic\n") catch {}; + File.stderr().writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } diff --git a/lib/std/debug/ElfFile.zig b/lib/std/debug/ElfFile.zig index 92bcca1bcf..5dbae18130 100644 --- a/lib/std/debug/ElfFile.zig +++ b/lib/std/debug/ElfFile.zig @@ -123,7 +123,7 @@ pub const LoadError = error{ pub fn load( gpa: Allocator, - elf_file: std.fs.File, + elf_file: Io.File, opt_build_id: ?[]const u8, di_search_paths: *const DebugInfoSearchPaths, ) LoadError!ElfFile { @@ -423,7 +423,7 @@ const LoadInnerResult = struct { }; fn loadInner( arena: Allocator, - elf_file: std.fs.File, + elf_file: Io.File, opt_crc: ?u32, ) (LoadError || error{ CrcMismatch, Streaming, Canceled })!LoadInnerResult { const mapped_mem: []align(std.heap.page_size_min) const u8 = mapped: { diff --git a/lib/std/debug/Info.zig b/lib/std/debug/Info.zig index 9268ca0247..da7656e626 100644 --- a/lib/std/debug/Info.zig +++ b/lib/std/debug/Info.zig @@ -27,7 +27,7 @@ coverage: *Coverage, pub const LoadError = error{ MissingDebugInfo, UnsupportedDebugInfo, -} || std.fs.File.OpenError || ElfFile.LoadError || MachOFile.Error || std.debug.Dwarf.ScanError; +} || Io.File.OpenError || ElfFile.LoadError || MachOFile.Error || std.debug.Dwarf.ScanError; pub fn load( gpa: Allocator, diff --git a/lib/std/debug/Pdb.zig b/lib/std/debug/Pdb.zig index c10b361f72..3ecfd1b363 100644 --- a/lib/std/debug/Pdb.zig +++ b/lib/std/debug/Pdb.zig @@ -1,5 +1,5 @@ const std = @import("../std.zig"); -const File = std.fs.File; +const File = std.Io.File; const Allocator = std.mem.Allocator; const pdb = std.pdb; const assert = std.debug.assert; diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index 557f3901eb..3af7223293 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -204,7 +204,7 @@ const Module = struct { coff_section_headers: []coff.SectionHeader, const MappedFile = struct { - file: fs.File, + file: Io.File, section_handle: windows.HANDLE, section_view: []const u8, fn deinit(mf: *const MappedFile, io: Io) void { diff --git a/lib/std/debug/simple_panic.zig b/lib/std/debug/simple_panic.zig index 45e97777c4..f6ff77e04f 100644 --- a/lib/std/debug/simple_panic.zig +++ b/lib/std/debug/simple_panic.zig @@ -15,7 +15,7 @@ pub fn call(msg: []const u8, ra: ?usize) noreturn { @branchHint(.cold); _ = ra; std.debug.lockStdErr(); - const stderr: std.fs.File = .stderr(); + const stderr: std.Io.File = .stderr(); stderr.writeAll(msg) catch {}; @trap(); } diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index c91056b0ab..ca36d5cbb9 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -225,7 +225,7 @@ pub const ElfDynLib = struct { const fd = try resolveFromName(io, path); defer posix.close(fd); - const file: std.fs.File = .{ .handle = fd }; + const file: Io.File = .{ .handle = fd }; const stat = try file.stat(); const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 15b8e9b558..f770ddd30e 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -12,7 +12,7 @@ const posix = std.posix; const ArenaAllocator = std.heap.ArenaAllocator; const Dir = std.fs.Dir; -const File = std.fs.File; +const File = std.Io.File; const tmpDir = testing.tmpDir; const SymLinkFlags = std.fs.Dir.SymLinkFlags; @@ -2231,7 +2231,7 @@ test "read file non vectored" { const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); defer file.close(io); { - var file_writer: std.fs.File.Writer = .init(file, &.{}); + var file_writer: File.Writer = .init(file, &.{}); try file_writer.interface.writeAll(contents); try file_writer.interface.flush(); } @@ -2263,7 +2263,7 @@ test "seek keeping partial buffer" { const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); defer file.close(io); { - var file_writer: std.fs.File.Writer = .init(file, &.{}); + var file_writer: File.Writer = .init(file, &.{}); try file_writer.interface.writeAll(contents); try file_writer.interface.flush(); } @@ -2325,7 +2325,7 @@ test "seekTo flushes buffered data" { defer file.close(io); { var buf: [16]u8 = undefined; - var file_writer = std.fs.File.writer(file, &buf); + var file_writer = File.writer(file, &buf); try file_writer.interface.writeAll(contents); try file_writer.seekTo(8); diff --git a/lib/std/hash/benchmark.zig b/lib/std/hash/benchmark.zig index a21d6e9ada..6744b87fac 100644 --- a/lib/std/hash/benchmark.zig +++ b/lib/std/hash/benchmark.zig @@ -1,7 +1,8 @@ // zig run -O ReleaseFast --zig-lib-dir ../.. benchmark.zig +const builtin = @import("builtin"); const std = @import("std"); -const builtin = @import("builtin"); +const Io = std.Io; const time = std.time; const Timer = time.Timer; const hash = std.hash; @@ -354,7 +355,7 @@ fn mode(comptime x: comptime_int) comptime_int { pub fn main() !void { var stdout_buffer: [0x100]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; var buffer: [1024]u8 = undefined; diff --git a/lib/std/http.zig b/lib/std/http.zig index a768372ecc..291e22539b 100644 --- a/lib/std/http.zig +++ b/lib/std/http.zig @@ -2,7 +2,7 @@ const builtin = @import("builtin"); const std = @import("std.zig"); const assert = std.debug.assert; const Writer = std.Io.Writer; -const File = std.fs.File; +const File = std.Io.File; pub const Client = @import("http/Client.zig"); pub const Server = @import("http/Server.zig"); diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig index 36b0e04e5c..7e479de8d4 100644 --- a/lib/std/pdb.zig +++ b/lib/std/pdb.zig @@ -12,7 +12,7 @@ const math = std.math; const mem = std.mem; const coff = std.coff; const fs = std.fs; -const File = std.fs.File; +const File = std.Io.File; const debug = std.debug; const ArrayList = std.ArrayList; diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 8889e50ea3..82fa2c41d1 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -1,20 +1,20 @@ +const builtin = @import("builtin"); +const native_os = builtin.target.os.tag; + const std = @import("../std.zig"); +const Io = std.Io; const posix = std.posix; const testing = std.testing; -const expect = testing.expect; -const expectEqual = testing.expectEqual; -const expectError = testing.expectError; +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const expectError = std.testing.expectError; const fs = std.fs; const mem = std.mem; const elf = std.elf; const linux = std.os.linux; - const a = std.testing.allocator; - -const builtin = @import("builtin"); const AtomicRmwOp = std.builtin.AtomicRmwOp; const AtomicOrder = std.builtin.AtomicOrder; -const native_os = builtin.target.os.tag; const tmpDir = std.testing.tmpDir; const AT = posix.AT; @@ -663,14 +663,14 @@ test "dup & dup2" { var file = try tmp.dir.createFile("os_dup_test", .{}); defer file.close(io); - var duped = std.fs.File{ .handle = try posix.dup(file.handle) }; + var duped = Io.File{ .handle = try posix.dup(file.handle) }; defer duped.close(io); try duped.writeAll("dup"); // Tests aren't run in parallel so using the next fd shouldn't be an issue. const new_fd = duped.handle + 1; try posix.dup2(file.handle, new_fd); - var dup2ed = std.fs.File{ .handle = new_fd }; + var dup2ed = Io.File{ .handle = new_fd }; defer dup2ed.close(io); try dup2ed.writeAll("dup2"); } diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index be3026ff10..87d2fe3ba9 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -8,7 +8,7 @@ const Io = std.Io; const unicode = std.unicode; const fs = std.fs; const process = std.process; -const File = std.fs.File; +const File = std.Io.File; const windows = std.os.windows; const linux = std.os.linux; const posix = std.posix; @@ -1055,7 +1055,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { fn writeIntFd(fd: i32, value: ErrInt) !void { var buffer: [8]u8 = undefined; - var fw: std.fs.File.Writer = .initStreaming(.{ .handle = fd }, &buffer); + var fw: File.Writer = .initStreaming(.{ .handle = fd }, &buffer); fw.interface.writeInt(u64, value, .little) catch unreachable; fw.interface.flush() catch return error.SystemResources; } diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig index fd3f46ec58..c02f550a4a 100644 --- a/lib/std/unicode/throughput_test.zig +++ b/lib/std/unicode/throughput_test.zig @@ -1,8 +1,8 @@ const std = @import("std"); +const Io = std.Io; const time = std.time; const unicode = std.unicode; - -const Timer = time.Timer; +const Timer = std.time.Timer; const N = 1_000_000; @@ -41,7 +41,7 @@ fn benchmarkCodepointCount(buf: []const u8) !ResultCount { pub fn main() !void { // Size of buffer is about size of printed message. var stdout_buffer: [0x100]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; try stdout.print("short ASCII strings\n", .{}); diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 09c785613f..37ce7b4cfa 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -11,9 +11,11 @@ //! * In the future, possibly inline assembly, which needs to get parsed and //! handled by the codegen backend, and errors reported there. However for now, //! inline assembly is not an exception. +const Zir = @This(); +const builtin = @import("builtin"); const std = @import("std"); -const builtin = @import("builtin"); +const Io = std.Io; const mem = std.mem; const Allocator = std.mem.Allocator; const assert = std.debug.assert; @@ -21,8 +23,6 @@ const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; const Ast = std.zig.Ast; -const Zir = @This(); - instructions: std.MultiArrayList(Inst).Slice, /// In order to store references to strings in fewer bytes, we copy all /// string bytes into here. String bytes can be null. It is up to whomever @@ -45,7 +45,7 @@ pub const Header = extern struct { /// it's essentially free to have a zero field here and makes the warning go away, /// making it more likely that following Valgrind warnings will be taken seriously. unused: u32 = 0, - stat_inode: std.fs.File.INode, + stat_inode: Io.File.INode, stat_size: u64, stat_mtime: i128, }; diff --git a/lib/std/zig/Zoir.zig b/lib/std/zig/Zoir.zig index 08a7fc9639..d82b8f1861 100644 --- a/lib/std/zig/Zoir.zig +++ b/lib/std/zig/Zoir.zig @@ -1,6 +1,13 @@ //! Zig Object Intermediate Representation. //! Simplified AST for the ZON (Zig Object Notation) format. //! `ZonGen` converts `Ast` to `Zoir`. +const Zoir = @This(); + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const Ast = std.zig.Ast; nodes: std.MultiArrayList(Node.Repr).Slice, extra: []u32, @@ -25,7 +32,7 @@ pub const Header = extern struct { /// making it more likely that following Valgrind warnings will be taken seriously. unused: u64 = 0, - stat_inode: std.fs.File.INode, + stat_inode: Io.File.INode, stat_size: u64, stat_mtime: i128, @@ -254,9 +261,3 @@ pub const CompileError = extern struct { assert(std.meta.hasUniqueRepresentation(Note)); } }; - -const std = @import("std"); -const assert = std.debug.assert; -const Allocator = std.mem.Allocator; -const Ast = std.zig.Ast; -const Zoir = @This(); diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 9a52ae2c81..9ca0124f4f 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -9578,7 +9578,7 @@ pub fn asmValue( pub fn dump(b: *Builder) void { var buffer: [4000]u8 = undefined; - const stderr: std.fs.File = .stderr(); + const stderr: Io.File = .stderr(); b.printToFile(stderr, &buffer) catch {}; } @@ -9589,7 +9589,7 @@ pub fn printToFilePath(b: *Builder, io: Io, dir: std.fs.Dir, path: []const u8) ! try b.printToFile(io, file, &buffer); } -pub fn printToFile(b: *Builder, file: std.fs.File, buffer: []u8) !void { +pub fn printToFile(b: *Builder, file: Io.File, buffer: []u8) !void { var fw = file.writer(buffer); try print(b, &fw.interface); try fw.interface.flush(); diff --git a/lib/std/zig/perf_test.zig b/lib/std/zig/perf_test.zig index 1566a15d2d..da3dd42f15 100644 --- a/lib/std/zig/perf_test.zig +++ b/lib/std/zig/perf_test.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Tokenizer = std.zig.Tokenizer; const fmtIntSizeBin = std.fmt.fmtIntSizeBin; @@ -22,7 +23,7 @@ pub fn main() !void { const bytes_per_sec = @as(u64, @intFromFloat(@floor(bytes_per_sec_float))); var stdout_buffer: [1024]u8 = undefined; - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); const stdout = &stdout_writer.interface; try stdout.print("parsing speed: {Bi:.2}/s, {Bi:.2} used \n", .{ bytes_per_sec, memory_used }); try stdout.flush(); diff --git a/lib/std/zip.zig b/lib/std/zip.zig index c2dbaf5b81..9588651e7f 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -4,9 +4,10 @@ //! Note that this file uses the abbreviation "cd" for "central directory" const builtin = @import("builtin"); -const std = @import("std"); -const File = std.fs.File; const is_le = builtin.target.cpu.arch.endian() == .little; + +const std = @import("std"); +const File = std.Io.File; const Writer = std.Io.Writer; const Reader = std.Io.Reader; const flate = std.compress.flate; diff --git a/src/Compilation.zig b/src/Compilation.zig index df64dee19f..582c9dff3c 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5325,7 +5325,7 @@ fn docsCopyModule( comp: *Compilation, module: *Package.Module, name: []const u8, - tar_file_writer: *fs.File.Writer, + tar_file_writer: *Io.File.Writer, ) !void { const io = comp.io; const root = module.root; @@ -5361,7 +5361,7 @@ fn docsCopyModule( }; defer file.close(io); const stat = try file.stat(); - var file_reader: fs.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); + var file_reader: Io.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| { return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive {f}{s}: {t}", .{ diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 58f970abe5..988282097b 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -882,7 +882,7 @@ fn fail(f: *Fetch, msg_tok: std.zig.Ast.TokenIndex, msg_str: u32) RunError { } const Resource = union(enum) { - file: fs.File.Reader, + file: Io.File.Reader, http_request: HttpRequest, git: Git, dir: Io.Dir, @@ -1653,7 +1653,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute fn dumpHashInfo(all_files: []const *const HashedFile) !void { var stdout_buffer: [1024]u8 = undefined; - var stdout_writer: fs.File.Writer = .initStreaming(.stdout(), &stdout_buffer); + var stdout_writer: Io.File.Writer = .initStreaming(.stdout(), &stdout_buffer); const w = &stdout_writer.interface; for (all_files) |hashed_file| { try w.print("{t}: {x}: {s}\n", .{ hashed_file.kind, &hashed_file.hash, hashed_file.normalized_path }); @@ -1712,11 +1712,11 @@ fn deleteFileFallible(dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error try dir.deleteFile(deleted_file.fs_path); } -fn setExecutable(file: fs.File) !void { +fn setExecutable(file: Io.File) !void { if (!std.fs.has_executable_bit) return; const S = std.posix.S; - const mode = fs.File.default_mode | S.IXUSR | S.IXGRP | S.IXOTH; + const mode = Io.File.default_mode | S.IXUSR | S.IXGRP | S.IXOTH; try file.chmod(mode); } @@ -1738,10 +1738,10 @@ const HashedFile = struct { size: u64, const Error = - fs.File.OpenError || - fs.File.ReadError || - fs.File.StatError || - fs.File.ChmodError || + Io.File.OpenError || + Io.File.ReadError || + Io.File.StatError || + Io.File.ChmodError || Io.Dir.ReadLinkError; const Kind = enum { file, link }; diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 864865bd19..0fca3a0ee3 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -198,8 +198,8 @@ pub const Repository = struct { repo: *Repository, allocator: Allocator, format: Oid.Format, - pack_file: *std.fs.File.Reader, - index_file: *std.fs.File.Reader, + pack_file: *Io.File.Reader, + index_file: *Io.File.Reader, ) !void { repo.* = .{ .odb = undefined }; try repo.odb.init(allocator, format, pack_file, index_file); @@ -372,9 +372,9 @@ pub const Repository = struct { /// [pack-format](https://git-scm.com/docs/pack-format). const Odb = struct { format: Oid.Format, - pack_file: *std.fs.File.Reader, + pack_file: *Io.File.Reader, index_header: IndexHeader, - index_file: *std.fs.File.Reader, + index_file: *Io.File.Reader, cache: ObjectCache = .{}, allocator: Allocator, @@ -383,8 +383,8 @@ const Odb = struct { odb: *Odb, allocator: Allocator, format: Oid.Format, - pack_file: *std.fs.File.Reader, - index_file: *std.fs.File.Reader, + pack_file: *Io.File.Reader, + index_file: *Io.File.Reader, ) !void { try pack_file.seekTo(0); try index_file.seekTo(0); @@ -1272,8 +1272,8 @@ const IndexEntry = struct { pub fn indexPack( allocator: Allocator, format: Oid.Format, - pack: *std.fs.File.Reader, - index_writer: *std.fs.File.Writer, + pack: *Io.File.Reader, + index_writer: *Io.File.Writer, ) !void { try pack.seekTo(0); @@ -1372,7 +1372,7 @@ pub fn indexPack( fn indexPackFirstPass( allocator: Allocator, format: Oid.Format, - pack: *std.fs.File.Reader, + pack: *Io.File.Reader, index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), pending_deltas: *std.ArrayList(IndexEntry), ) !Oid { @@ -1425,7 +1425,7 @@ fn indexPackFirstPass( fn indexPackHashDelta( allocator: Allocator, format: Oid.Format, - pack: *std.fs.File.Reader, + pack: *Io.File.Reader, delta: IndexEntry, index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry), cache: *ObjectCache, @@ -1477,7 +1477,7 @@ fn indexPackHashDelta( fn resolveDeltaChain( allocator: Allocator, format: Oid.Format, - pack: *std.fs.File.Reader, + pack: *Io.File.Reader, base_object: Object, delta_offsets: []const u64, cache: *ObjectCache, diff --git a/src/Zcu.zig b/src/Zcu.zig index 58d884afe3..cd4a8c7783 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1200,7 +1200,7 @@ pub const EmbedFile = struct { /// `.none` means the file was not loaded, so `stat` is undefined. val: InternPool.Index, /// If this is `null` and `val` is `.none`, the file has never been loaded. - err: ?(std.fs.File.OpenError || std.fs.File.StatError || std.fs.File.ReadError || error{UnexpectedEof}), + err: ?(Io.File.OpenError || Io.File.StatError || Io.File.ReadError || error{UnexpectedEof}), stat: Cache.File.Stat, pub const Index = enum(u32) { @@ -2927,7 +2927,7 @@ comptime { } } -pub fn loadZirCache(gpa: Allocator, io: Io, cache_file: std.fs.File) !Zir { +pub fn loadZirCache(gpa: Allocator, io: Io, cache_file: Io.File) !Zir { var buffer: [2000]u8 = undefined; var file_reader = cache_file.reader(io, &buffer); return result: { @@ -2986,7 +2986,7 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_br: *Io.Reader return zir; } -pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.Stat, zir: Zir) (std.fs.File.WriteError || Allocator.Error)!void { +pub fn saveZirCache(gpa: Allocator, cache_file: Io.File, stat: Io.File.Stat, zir: Zir) (Io.File.WriteError || Allocator.Error)!void { const safety_buffer = if (data_has_safety_tag) try gpa.alloc([8]u8, zir.instructions.len) else @@ -3026,7 +3026,7 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S }; } -pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir) std.fs.File.WriteError!void { +pub fn saveZoirCache(cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir) Io.File.WriteError!void { const header: Zoir.Header = .{ .nodes_len = @intCast(zoir.nodes.len), .extra_len = @intCast(zoir.extra.len), diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index d2ca004058..55d6a3861f 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -118,7 +118,7 @@ pub fn updateFile( const zir_dir = cache_directory.handle; // Determine whether we need to reload the file from disk and redo parsing and AstGen. - var lock: std.fs.File.Lock = switch (file.status) { + var lock: Io.File.Lock = switch (file.status) { .never_loaded, .retryable_failure => lock: { // First, load the cached ZIR code, if any. log.debug("AstGen checking cache: {f} (local={}, digest={s})", .{ @@ -346,8 +346,8 @@ pub fn updateFile( fn loadZirZoirCache( zcu: *Zcu, - cache_file: std.fs.File, - stat: std.fs.File.Stat, + cache_file: Io.File, + stat: Io.File.Stat, file: *Zcu.File, comptime mode: Ast.Mode, ) !enum { success, invalid, truncated, stale } { diff --git a/src/fmt.zig b/src/fmt.zig index 907c7885ad..7bdc24054e 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -37,9 +37,9 @@ const Fmt = struct { arena: Allocator, io: Io, out_buffer: std.Io.Writer.Allocating, - stdout_writer: *fs.File.Writer, + stdout_writer: *Io.File.Writer, - const SeenMap = std.AutoHashMap(fs.File.INode, void); + const SeenMap = std.AutoHashMap(Io.File.INode, void); }; pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !void { @@ -59,7 +59,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try fs.File.stdout().writeAll(usage_fmt); + try Io.File.stdout().writeAll(usage_fmt); return process.cleanExit(); } else if (mem.eql(u8, arg, "--color")) { if (i + 1 >= args.len) { @@ -99,9 +99,9 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! fatal("cannot use --stdin with positional arguments", .{}); } - const stdin: fs.File = .stdin(); + const stdin: Io.File = .stdin(); var stdio_buffer: [1024]u8 = undefined; - var file_reader: fs.File.Reader = stdin.reader(io, &stdio_buffer); + var file_reader: Io.File.Reader = stdin.reader(io, &stdio_buffer); const source_code = std.zig.readSourceFileToEndAlloc(gpa, &file_reader) catch |err| { fatal("unable to read stdin: {}", .{err}); }; @@ -154,7 +154,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! process.exit(code); } - return fs.File.stdout().writeAll(formatted); + return Io.File.stdout().writeAll(formatted); } if (input_files.items.len == 0) { @@ -162,7 +162,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! } var stdout_buffer: [4096]u8 = undefined; - var stdout_writer = fs.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(&stdout_buffer); var fmt: Fmt = .{ .gpa = gpa, @@ -272,7 +272,7 @@ fn fmtPathFile( return error.IsDir; var read_buffer: [1024]u8 = undefined; - var file_reader: fs.File.Reader = source_file.reader(io, &read_buffer); + var file_reader: Io.File.Reader = source_file.reader(io, &read_buffer); file_reader.size = stat.size; const gpa = fmt.gpa; diff --git a/src/link.zig b/src/link.zig index ef095987c9..d5daf6fca7 100644 --- a/src/link.zig +++ b/src/link.zig @@ -393,7 +393,7 @@ pub const File = struct { comp: *Compilation, emit: Path, - file: ?fs.File, + file: ?Io.File, /// When using the LLVM backend, the emitted object is written to a file with this name. This /// object file then becomes a normal link input to LLD or a self-hosted linker. /// @@ -1110,7 +1110,7 @@ pub const File = struct { }; } - fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: fs.File) anyerror!void { + fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: Io.File) anyerror!void { const comp = base.comp; const diags = &comp.link_diags; const gpa = comp.gpa; @@ -1238,7 +1238,7 @@ pub const File = struct { pub fn determineMode( output_mode: std.builtin.OutputMode, link_mode: std.builtin.LinkMode, - ) fs.File.Mode { + ) Io.File.Mode { // On common systems with a 0o022 umask, 0o777 will still result in a file created // with 0o755 permissions, but it works appropriately if the system is configured // more leniently. As another data point, C's fopen seems to open files with the @@ -1247,10 +1247,10 @@ pub const File = struct { switch (output_mode) { .Lib => return switch (link_mode) { .dynamic => executable_mode, - .static => fs.File.default_mode, + .static => Io.File.default_mode, }, .Exe => return executable_mode, - .Obj => return fs.File.default_mode, + .Obj => return Io.File.default_mode, } } @@ -1660,19 +1660,19 @@ pub const Input = union(enum) { pub const Object = struct { path: Path, - file: fs.File, + file: Io.File, must_link: bool, hidden: bool, }; pub const Res = struct { path: Path, - file: fs.File, + file: Io.File, }; pub const Dso = struct { path: Path, - file: fs.File, + file: Io.File, needed: bool, weak: bool, reexport: bool, @@ -1694,7 +1694,7 @@ pub const Input = union(enum) { } /// Returns `null` in the case of `dso_exact`. - pub fn pathAndFile(input: Input) ?struct { Path, fs.File } { + pub fn pathAndFile(input: Input) ?struct { Path, Io.File } { return switch (input) { .object, .archive => |obj| .{ obj.path, obj.file }, inline .res, .dso => |x| .{ x.path, x.file }, @@ -2075,7 +2075,7 @@ fn resolveLibInput( fn finishResolveLibInput( resolved_inputs: *std.ArrayList(Input), path: Path, - file: std.fs.File, + file: Io.File, link_mode: std.builtin.LinkMode, query: UnresolvedInput.Query, ) ResolveLibInputResult { diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 95f4ca8bbd..cfb02fba38 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1,3 +1,24 @@ +const Dwarf = @This(); + +const std = @import("std"); +const Io = std.Io; +const Allocator = std.mem.Allocator; +const DW = std.dwarf; +const Zir = std.zig.Zir; +const assert = std.debug.assert; +const log = std.log.scoped(.dwarf); +const Writer = std.Io.Writer; + +const InternPool = @import("../InternPool.zig"); +const Module = @import("../Package.zig").Module; +const Type = @import("../Type.zig"); +const Value = @import("../Value.zig"); +const Zcu = @import("../Zcu.zig"); +const codegen = @import("../codegen.zig"); +const dev = @import("../dev.zig"); +const link = @import("../link.zig"); +const target_info = @import("../target.zig"); + gpa: Allocator, bin_file: *link.File, format: DW.Format, @@ -29,16 +50,16 @@ pub const UpdateError = error{ UnexpectedEndOfFile, } || codegen.GenerateSymbolError || - std.fs.File.OpenError || - std.fs.File.SetEndPosError || - std.fs.File.CopyRangeError || - std.fs.File.PReadError || - std.fs.File.PWriteError; + Io.File.OpenError || + Io.File.SetEndPosError || + Io.File.CopyRangeError || + Io.File.PReadError || + Io.File.PWriteError; pub const FlushError = UpdateError; pub const RelocError = - std.fs.File.PWriteError; + Io.File.PWriteError; pub const AddressSize = enum(u8) { @"32" = 4, @@ -6350,7 +6371,7 @@ const AbbrevCode = enum { }); }; -fn getFile(dwarf: *Dwarf) ?std.fs.File { +fn getFile(dwarf: *Dwarf) ?Io.File { if (dwarf.bin_file.cast(.macho)) |macho_file| if (macho_file.d_sym) |*d_sym| return d_sym.file; return dwarf.bin_file.file; } @@ -6429,21 +6450,3 @@ const force_incremental = false; inline fn incremental(dwarf: Dwarf) bool { return force_incremental or dwarf.bin_file.comp.config.incremental; } - -const Allocator = std.mem.Allocator; -const DW = std.dwarf; -const Dwarf = @This(); -const InternPool = @import("../InternPool.zig"); -const Module = @import("../Package.zig").Module; -const Type = @import("../Type.zig"); -const Value = @import("../Value.zig"); -const Zcu = @import("../Zcu.zig"); -const Zir = std.zig.Zir; -const assert = std.debug.assert; -const codegen = @import("../codegen.zig"); -const dev = @import("../dev.zig"); -const link = @import("../link.zig"); -const log = std.log.scoped(.dwarf); -const std = @import("std"); -const target_info = @import("../target.zig"); -const Writer = std.Io.Writer; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ae7d631f09..584a50c7f2 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3651,7 +3651,7 @@ fn fileLookup(files: std.MultiArrayList(File.Entry), index: File.Index, zig_obje pub fn addFileHandle( gpa: Allocator, file_handles: *std.ArrayList(File.Handle), - handle: fs.File, + handle: Io.File, ) Allocator.Error!File.HandleIndex { try file_handles.append(gpa, handle); return @intCast(file_handles.items.len - 1); @@ -4068,7 +4068,7 @@ fn fmtDumpState(self: *Elf, writer: *std.Io.Writer) std.Io.Writer.Error!void { } /// Caller owns the memory. -pub fn preadAllAlloc(allocator: Allocator, handle: fs.File, offset: u64, size: u64) ![]u8 { +pub fn preadAllAlloc(allocator: Allocator, handle: Io.File, offset: u64, size: u64) ![]u8 { const buffer = try allocator.alloc(u8, math.cast(usize, size) orelse return error.Overflow); errdefer allocator.free(buffer); const amt = try handle.preadAll(buffer, offset); @@ -4460,6 +4460,7 @@ pub fn cast(elf_file: *Elf, comptime T: type, x: anytype) error{LinkFailure}!T { } const std = @import("std"); +const Io = std.Io; const build_options = @import("build_options"); const builtin = @import("builtin"); const assert = std.debug.assert; diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index d51a82b266..c0dde4176a 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -1,3 +1,30 @@ +const Object = @This(); + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const eh_frame = @import("eh_frame.zig"); +const elf = std.elf; +const fs = std.fs; +const log = std.log.scoped(.link); +const math = std.math; +const mem = std.mem; +const Path = std.Build.Cache.Path; +const Allocator = std.mem.Allocator; + +const Diags = @import("../../link.zig").Diags; +const Archive = @import("Archive.zig"); +const Atom = @import("Atom.zig"); +const AtomList = @import("AtomList.zig"); +const Cie = eh_frame.Cie; +const Elf = @import("../Elf.zig"); +const Fde = eh_frame.Fde; +const File = @import("file.zig").File; +const Merge = @import("Merge.zig"); +const Symbol = @import("Symbol.zig"); +const Alignment = Atom.Alignment; +const riscv = @import("../riscv.zig"); + archive: ?InArchive = null, /// Archive files cannot contain subdirectories, so only the basename is needed /// for output. However, the full path is kept for error reporting. @@ -68,7 +95,7 @@ pub fn parse( diags: *Diags, /// For error reporting purposes only. path: Path, - handle: fs.File, + handle: Io.File, target: *const std.Target, debug_fmt_strip: bool, default_sym_version: elf.Versym, @@ -97,7 +124,7 @@ pub fn parseCommon( gpa: Allocator, diags: *Diags, path: Path, - handle: fs.File, + handle: Io.File, target: *const std.Target, ) !void { const offset = if (self.archive) |ar| ar.offset else 0; @@ -264,7 +291,7 @@ fn initAtoms( gpa: Allocator, diags: *Diags, path: Path, - handle: fs.File, + handle: Io.File, debug_fmt_strip: bool, target: *const std.Target, ) !void { @@ -421,7 +448,7 @@ fn initSymbols( fn parseEhFrame( self: *Object, gpa: Allocator, - handle: fs.File, + handle: Io.File, shndx: u32, target: *const std.Target, ) !void { @@ -1310,7 +1337,7 @@ fn addString(self: *Object, gpa: Allocator, str: []const u8) !u32 { } /// Caller owns the memory. -fn preadShdrContentsAlloc(self: Object, gpa: Allocator, handle: fs.File, index: u32) ![]u8 { +fn preadShdrContentsAlloc(self: Object, gpa: Allocator, handle: Io.File, index: u32) ![]u8 { assert(index < self.shdrs.items.len); const offset = if (self.archive) |ar| ar.offset else 0; const shdr = self.shdrs.items[index]; @@ -1320,7 +1347,7 @@ fn preadShdrContentsAlloc(self: Object, gpa: Allocator, handle: fs.File, index: } /// Caller owns the memory. -fn preadRelocsAlloc(self: Object, gpa: Allocator, handle: fs.File, shndx: u32) ![]align(1) const elf.Elf64_Rela { +fn preadRelocsAlloc(self: Object, gpa: Allocator, handle: Io.File, shndx: u32) ![]align(1) const elf.Elf64_Rela { const raw = try self.preadShdrContentsAlloc(gpa, handle, shndx); const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela)); return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; @@ -1552,29 +1579,3 @@ const InArchive = struct { offset: u64, size: u32, }; - -const Object = @This(); - -const std = @import("std"); -const assert = std.debug.assert; -const eh_frame = @import("eh_frame.zig"); -const elf = std.elf; -const fs = std.fs; -const log = std.log.scoped(.link); -const math = std.math; -const mem = std.mem; -const Path = std.Build.Cache.Path; -const Allocator = std.mem.Allocator; - -const Diags = @import("../../link.zig").Diags; -const Archive = @import("Archive.zig"); -const Atom = @import("Atom.zig"); -const AtomList = @import("AtomList.zig"); -const Cie = eh_frame.Cie; -const Elf = @import("../Elf.zig"); -const Fde = eh_frame.Fde; -const File = @import("file.zig").File; -const Merge = @import("Merge.zig"); -const Symbol = @import("Symbol.zig"); -const Alignment = Atom.Alignment; -const riscv = @import("../riscv.zig"); diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig index 1e17aa34a8..3720fe53d6 100644 --- a/src/link/Elf/SharedObject.zig +++ b/src/link/Elf/SharedObject.zig @@ -1,3 +1,20 @@ +const SharedObject = @This(); + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const elf = std.elf; +const log = std.log.scoped(.elf); +const mem = std.mem; +const Path = std.Build.Cache.Path; +const Stat = std.Build.Cache.File.Stat; +const Allocator = mem.Allocator; + +const Elf = @import("../Elf.zig"); +const File = @import("file.zig").File; +const Symbol = @import("Symbol.zig"); +const Diags = @import("../../link.zig").Diags; + path: Path, index: File.Index, @@ -94,7 +111,7 @@ pub fn parseHeader( gpa: Allocator, diags: *Diags, file_path: Path, - fs_file: std.fs.File, + fs_file: Io.File, stat: Stat, target: *const std.Target, ) !Header { @@ -192,7 +209,7 @@ pub fn parse( gpa: Allocator, /// Moves resources from header. Caller may unconditionally deinit. header: *Header, - fs_file: std.fs.File, + fs_file: Io.File, ) !Parsed { const symtab = if (header.dynsym_sect_index) |index| st: { const shdr = header.sections[index]; @@ -534,19 +551,3 @@ const Format = struct { } } }; - -const SharedObject = @This(); - -const std = @import("std"); -const assert = std.debug.assert; -const elf = std.elf; -const log = std.log.scoped(.elf); -const mem = std.mem; -const Path = std.Build.Cache.Path; -const Stat = std.Build.Cache.File.Stat; -const Allocator = mem.Allocator; - -const Elf = @import("../Elf.zig"); -const File = @import("file.zig").File; -const Symbol = @import("Symbol.zig"); -const Diags = @import("../../link.zig").Diags; diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig index 50f5159d18..52d3c6e6f0 100644 --- a/src/link/Elf/file.zig +++ b/src/link/Elf/file.zig @@ -1,3 +1,20 @@ +const std = @import("std"); +const Io = std.Io; +const elf = std.elf; +const log = std.log.scoped(.link); +const Path = std.Build.Cache.Path; +const Allocator = std.mem.Allocator; + +const Archive = @import("Archive.zig"); +const Atom = @import("Atom.zig"); +const Cie = @import("eh_frame.zig").Cie; +const Elf = @import("../Elf.zig"); +const LinkerDefined = @import("LinkerDefined.zig"); +const Object = @import("Object.zig"); +const SharedObject = @import("SharedObject.zig"); +const Symbol = @import("Symbol.zig"); +const ZigObject = @import("ZigObject.zig"); + pub const File = union(enum) { zig_object: *ZigObject, linker_defined: *LinkerDefined, @@ -279,22 +296,6 @@ pub const File = union(enum) { shared_object: SharedObject, }; - pub const Handle = std.fs.File; + pub const Handle = Io.File; pub const HandleIndex = Index; }; - -const std = @import("std"); -const elf = std.elf; -const log = std.log.scoped(.link); -const Path = std.Build.Cache.Path; -const Allocator = std.mem.Allocator; - -const Archive = @import("Archive.zig"); -const Atom = @import("Atom.zig"); -const Cie = @import("eh_frame.zig").Cie; -const Elf = @import("../Elf.zig"); -const LinkerDefined = @import("LinkerDefined.zig"); -const Object = @import("Object.zig"); -const SharedObject = @import("SharedObject.zig"); -const Symbol = @import("Symbol.zig"); -const ZigObject = @import("ZigObject.zig"); diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 7d12ccedb2..e35444bc02 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -1,3 +1,23 @@ +const Elf = @This(); + +const builtin = @import("builtin"); +const native_endian = builtin.cpu.arch.endian(); + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const log = std.log.scoped(.link); + +const codegen = @import("../codegen.zig"); +const Compilation = @import("../Compilation.zig"); +const InternPool = @import("../InternPool.zig"); +const link = @import("../link.zig"); +const MappedFile = @import("MappedFile.zig"); +const target_util = @import("../target.zig"); +const Type = @import("../Type.zig"); +const Value = @import("../Value.zig"); +const Zcu = @import("../Zcu.zig"); + base: link.File, options: link.File.OpenOptions, mf: MappedFile, @@ -1973,8 +1993,8 @@ pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !Symbol.Index { return lazy_gop.value_ptr.*; } -pub fn loadInput(elf: *Elf, input: link.Input) (std.fs.File.Reader.SizeError || - std.Io.File.Reader.Error || MappedFile.Error || error{ EndOfStream, BadMagic, LinkFailure })!void { +pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || + Io.File.Reader.Error || MappedFile.Error || error{ EndOfStream, BadMagic, LinkFailure })!void { const io = elf.base.comp.io; var buf: [4096]u8 = undefined; switch (input) { @@ -2007,7 +2027,7 @@ pub fn loadInput(elf: *Elf, input: link.Input) (std.fs.File.Reader.SizeError || .dso_exact => |dso_exact| try elf.loadDsoExact(dso_exact.name), } } -fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void { +fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { const comp = elf.base.comp; const gpa = comp.gpa; const diags = &comp.link_diags; @@ -2067,7 +2087,7 @@ fn loadObject( elf: *Elf, path: std.Build.Cache.Path, member: ?[]const u8, - fr: *std.Io.File.Reader, + fr: *Io.File.Reader, fl: MappedFile.Node.FileLocation, ) !void { const comp = elf.base.comp; @@ -2310,7 +2330,7 @@ fn loadObject( }, } } -fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *std.Io.File.Reader) !void { +fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { const comp = elf.base.comp; const diags = &comp.link_diags; const r = &fr.interface; @@ -3822,19 +3842,3 @@ pub fn printNode( try w.writeByte('\n'); } } - -const assert = std.debug.assert; -const builtin = @import("builtin"); -const codegen = @import("../codegen.zig"); -const Compilation = @import("../Compilation.zig"); -const Elf = @This(); -const InternPool = @import("../InternPool.zig"); -const link = @import("../link.zig"); -const log = std.log.scoped(.link); -const MappedFile = @import("MappedFile.zig"); -const native_endian = builtin.cpu.arch.endian(); -const std = @import("std"); -const target_util = @import("../target.zig"); -const Type = @import("../Type.zig"); -const Value = @import("../Value.zig"); -const Zcu = @import("../Zcu.zig"); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 471465cea1..72a49c0c9e 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -890,7 +890,7 @@ pub fn classifyInputFile(self: *MachO, input: link.Input) !void { _ = try self.addTbd(.fromLinkInput(input), true, fh); } -fn parseFatFile(self: *MachO, file: std.fs.File, path: Path) !?fat.Arch { +fn parseFatFile(self: *MachO, file: Io.File, path: Path) !?fat.Arch { const diags = &self.base.comp.link_diags; const fat_h = fat.readFatHeader(file) catch return null; if (fat_h.magic != macho.FAT_MAGIC and fat_h.magic != macho.FAT_MAGIC_64) return null; @@ -903,7 +903,7 @@ fn parseFatFile(self: *MachO, file: std.fs.File, path: Path) !?fat.Arch { return diags.failParse(path, "missing arch in universal file: expected {s}", .{@tagName(cpu_arch)}); } -pub fn readMachHeader(file: std.fs.File, offset: usize) !macho.mach_header_64 { +pub fn readMachHeader(file: Io.File, offset: usize) !macho.mach_header_64 { var buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined; const nread = try file.preadAll(&buffer, offset); if (nread != buffer.len) return error.InputOutput; @@ -911,7 +911,7 @@ pub fn readMachHeader(file: std.fs.File, offset: usize) !macho.mach_header_64 { return hdr; } -pub fn readArMagic(file: std.fs.File, offset: usize, buffer: *[Archive.SARMAG]u8) ![]const u8 { +pub fn readArMagic(file: Io.File, offset: usize, buffer: *[Archive.SARMAG]u8) ![]const u8 { const nread = try file.preadAll(buffer, offset); if (nread != buffer.len) return error.InputOutput; return buffer[0..Archive.SARMAG]; @@ -3768,7 +3768,7 @@ pub fn getInternalObject(self: *MachO) ?*InternalObject { return self.getFile(index).?.internal; } -pub fn addFileHandle(self: *MachO, file: fs.File) !File.HandleIndex { +pub fn addFileHandle(self: *MachO, file: Io.File) !File.HandleIndex { const gpa = self.base.comp.gpa; const index: File.HandleIndex = @intCast(self.file_handles.items.len); const fh = try self.file_handles.addOne(gpa); @@ -5373,10 +5373,11 @@ const max_distance = (1 << (jump_bits - 1)); const max_allowed_distance = max_distance - 0x500_000; const MachO = @This(); - -const std = @import("std"); const build_options = @import("build_options"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const fs = std.fs; const log = std.log.scoped(.link); @@ -5386,6 +5387,11 @@ const math = std.math; const mem = std.mem; const meta = std.meta; const Writer = std.Io.Writer; +const AtomicBool = std.atomic.Value(bool); +const Cache = std.Build.Cache; +const Hash = std.hash.Wyhash; +const Md5 = std.crypto.hash.Md5; +const Allocator = std.mem.Allocator; const aarch64 = codegen.aarch64.encoding; const bind = @import("MachO/dyld_info/bind.zig"); @@ -5403,11 +5409,8 @@ const trace = @import("../tracy.zig").trace; const synthetic = @import("MachO/synthetic.zig"); const Alignment = Atom.Alignment; -const Allocator = mem.Allocator; const Archive = @import("MachO/Archive.zig"); -const AtomicBool = std.atomic.Value(bool); const Bind = bind.Bind; -const Cache = std.Build.Cache; const CodeSignature = @import("MachO/CodeSignature.zig"); const Compilation = @import("../Compilation.zig"); const DataInCode = synthetic.DataInCode; @@ -5417,14 +5420,12 @@ const ExportTrie = @import("MachO/dyld_info/Trie.zig"); const Path = Cache.Path; const File = @import("MachO/file.zig").File; const GotSection = synthetic.GotSection; -const Hash = std.hash.Wyhash; const Indsymtab = synthetic.Indsymtab; const InternalObject = @import("MachO/InternalObject.zig"); const ObjcStubsSection = synthetic.ObjcStubsSection; const Object = @import("MachO/Object.zig"); const LazyBind = bind.LazyBind; const LaSymbolPtrSection = synthetic.LaSymbolPtrSection; -const Md5 = std.crypto.hash.Md5; const Zcu = @import("../Zcu.zig"); const InternPool = @import("../InternPool.zig"); const Rebase = @import("MachO/dyld_info/Rebase.zig"); diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index 5bded3b9e3..5f9a9ecac9 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -1,17 +1,19 @@ const CodeSignature = @This(); const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const fs = std.fs; const log = std.log.scoped(.link); const macho = std.macho; const mem = std.mem; const testing = std.testing; +const Sha256 = std.crypto.hash.sha2.Sha256; +const Allocator = std.mem.Allocator; + const trace = @import("../../tracy.zig").trace; -const Allocator = mem.Allocator; const Hasher = @import("hasher.zig").ParallelHasher; const MachO = @import("../MachO.zig"); -const Sha256 = std.crypto.hash.sha2.Sha256; const hash_size = Sha256.digest_length; @@ -250,7 +252,7 @@ pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const } pub const WriteOpts = struct { - file: fs.File, + file: Io.File, exec_seg_base: u64, exec_seg_limit: u64, file_size: u32, diff --git a/src/link/MachO/fat.zig b/src/link/MachO/fat.zig index 7772f7a4de..fd9a302531 100644 --- a/src/link/MachO/fat.zig +++ b/src/link/MachO/fat.zig @@ -1,18 +1,20 @@ +const builtin = @import("builtin"); +const native_endian = builtin.target.cpu.arch.endian(); + const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; -const builtin = @import("builtin"); const log = std.log.scoped(.macho); const macho = std.macho; const mem = std.mem; -const native_endian = builtin.target.cpu.arch.endian(); const MachO = @import("../MachO.zig"); -pub fn readFatHeader(file: std.fs.File) !macho.fat_header { +pub fn readFatHeader(file: Io.File) !macho.fat_header { return readFatHeaderGeneric(macho.fat_header, file, 0); } -fn readFatHeaderGeneric(comptime Hdr: type, file: std.fs.File, offset: usize) !Hdr { +fn readFatHeaderGeneric(comptime Hdr: type, file: Io.File, offset: usize) !Hdr { var buffer: [@sizeOf(Hdr)]u8 = undefined; const nread = try file.preadAll(&buffer, offset); if (nread != buffer.len) return error.InputOutput; @@ -27,7 +29,7 @@ pub const Arch = struct { size: u32, }; -pub fn parseArchs(file: std.fs.File, fat_header: macho.fat_header, out: *[2]Arch) ![]const Arch { +pub fn parseArchs(file: Io.File, fat_header: macho.fat_header, out: *[2]Arch) ![]const Arch { var count: usize = 0; var fat_arch_index: u32 = 0; while (fat_arch_index < fat_header.nfat_arch and count < out.len) : (fat_arch_index += 1) { diff --git a/src/link/MachO/file.zig b/src/link/MachO/file.zig index 05b43de181..cd687a4941 100644 --- a/src/link/MachO/file.zig +++ b/src/link/MachO/file.zig @@ -355,11 +355,12 @@ pub const File = union(enum) { dylib: Dylib, }; - pub const Handle = std.fs.File; + pub const Handle = Io.File; pub const HandleIndex = Index; }; const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const log = std.log.scoped(.link); const macho = std.macho; diff --git a/src/link/MachO/hasher.zig b/src/link/MachO/hasher.zig index 78cd847c40..8cf53071c8 100644 --- a/src/link/MachO/hasher.zig +++ b/src/link/MachO/hasher.zig @@ -1,3 +1,9 @@ +const std = @import("std"); +const Io = std.Io; +const Allocator = std.mem.Allocator; + +const trace = @import("../../tracy.zig").trace; + pub fn ParallelHasher(comptime Hasher: type) type { const hash_size = Hasher.digest_length; @@ -5,7 +11,7 @@ pub fn ParallelHasher(comptime Hasher: type) type { allocator: Allocator, io: std.Io, - pub fn hash(self: Self, file: fs.File, out: [][hash_size]u8, opts: struct { + pub fn hash(self: Self, file: Io.File, out: [][hash_size]u8, opts: struct { chunk_size: u64 = 0x4000, max_file_size: ?u64 = null, }) !void { @@ -23,7 +29,7 @@ pub fn ParallelHasher(comptime Hasher: type) type { const buffer = try self.allocator.alloc(u8, chunk_size * out.len); defer self.allocator.free(buffer); - const results = try self.allocator.alloc(fs.File.PReadError!usize, out.len); + const results = try self.allocator.alloc(Io.File.PReadError!usize, out.len); defer self.allocator.free(results); { @@ -51,11 +57,11 @@ pub fn ParallelHasher(comptime Hasher: type) type { } fn worker( - file: fs.File, + file: Io.File, fstart: usize, buffer: []u8, out: *[hash_size]u8, - err: *fs.File.PReadError!usize, + err: *Io.File.PReadError!usize, ) void { const tracy = trace(@src()); defer tracy.end(); @@ -66,11 +72,3 @@ pub fn ParallelHasher(comptime Hasher: type) type { const Self = @This(); }; } - -const assert = std.debug.assert; -const fs = std.fs; -const mem = std.mem; -const std = @import("std"); -const trace = @import("../../tracy.zig").trace; - -const Allocator = mem.Allocator; diff --git a/src/link/MachO/uuid.zig b/src/link/MachO/uuid.zig index d08ac0c5b8..4d8eac7523 100644 --- a/src/link/MachO/uuid.zig +++ b/src/link/MachO/uuid.zig @@ -1,10 +1,18 @@ +const std = @import("std"); +const Io = std.Io; +const Md5 = std.crypto.hash.Md5; + +const trace = @import("../../tracy.zig").trace; +const Compilation = @import("../../Compilation.zig"); +const Hasher = @import("hasher.zig").ParallelHasher; + /// Calculates Md5 hash of each chunk in parallel and then hashes all Md5 hashes to produce /// the final digest. /// While this is NOT a correct MD5 hash of the contents, this methodology is used by LLVM/LLD /// and we will use it too as it seems accepted by Apple OSes. /// TODO LLD also hashes the output filename to disambiguate between same builds with different /// output files. Should we also do that? -pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[Md5.digest_length]u8) !void { +pub fn calcUuid(comp: *const Compilation, file: Io.File, file_size: u64, out: *[Md5.digest_length]u8) !void { const tracy = trace(@src()); defer tracy.end(); @@ -37,12 +45,3 @@ inline fn conform(out: *[Md5.digest_length]u8) void { out[6] = (out[6] & 0x0F) | (3 << 4); out[8] = (out[8] & 0x3F) | 0x80; } - -const fs = std.fs; -const mem = std.mem; -const std = @import("std"); -const trace = @import("../../tracy.zig").trace; - -const Compilation = @import("../../Compilation.zig"); -const Md5 = std.crypto.hash.Md5; -const Hasher = @import("hasher.zig").ParallelHasher; diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 975b94578b..7d4134ccaf 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -1,3 +1,15 @@ +const MappedFile = @This(); + +const builtin = @import("builtin"); +const is_linux = builtin.os.tag == .linux; +const is_windows = builtin.os.tag == .windows; + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const linux = std.os.linux; +const windows = std.os.windows; + file: std.Io.File, flags: packed struct { block_size: std.mem.Alignment, @@ -16,7 +28,7 @@ writers: std.SinglyLinkedList, pub const growth_factor = 4; -pub const Error = std.posix.MMapError || std.posix.MRemapError || std.fs.File.SetEndPosError || error{ +pub const Error = std.posix.MMapError || std.posix.MRemapError || Io.File.SetEndPosError || error{ NotFile, SystemResources, IsDir, @@ -618,7 +630,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested // Resize the entire file if (ni == Node.Index.root) { try mf.ensureCapacityForSetLocation(gpa); - try std.fs.File.adaptFromNewApi(mf.file).setEndPos(new_size); + try Io.File.adaptFromNewApi(mf.file).setEndPos(new_size); try mf.ensureTotalCapacity(@intCast(new_size)); ni.setLocationAssumeCapacity(mf, old_offset, new_size); return; @@ -1059,12 +1071,3 @@ fn verifyNode(mf: *MappedFile, parent_ni: Node.Index) void { ni = node.next; } } - -const assert = std.debug.assert; -const builtin = @import("builtin"); -const is_linux = builtin.os.tag == .linux; -const is_windows = builtin.os.tag == .windows; -const linux = std.os.linux; -const MappedFile = @This(); -const std = @import("std"); -const windows = std.os.windows; diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 160e6cdcc6..7ab1e0eb4b 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -20,6 +20,7 @@ const native_endian = builtin.cpu.arch.endian(); const build_options = @import("build_options"); const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const Cache = std.Build.Cache; const Path = Cache.Path; @@ -3001,9 +3002,9 @@ pub fn createEmpty( .read = true, .mode = if (fs.has_executable_bit) if (target.os.tag == .wasi and output_mode == .Exe) - fs.File.default_mode | 0b001_000_000 + Io.File.default_mode | 0b001_000_000 else - fs.File.default_mode + Io.File.default_mode else 0, }); diff --git a/src/link/tapi.zig b/src/link/tapi.zig index 4c1471a6b4..fff25b7544 100644 --- a/src/link/tapi.zig +++ b/src/link/tapi.zig @@ -1,10 +1,10 @@ const std = @import("std"); -const fs = std.fs; +const Io = std.Io; const mem = std.mem; const log = std.log.scoped(.tapi); -const yaml = @import("tapi/yaml.zig"); +const Allocator = std.mem.Allocator; -const Allocator = mem.Allocator; +const yaml = @import("tapi/yaml.zig"); const Yaml = yaml.Yaml; const VersionField = union(enum) { @@ -130,7 +130,7 @@ pub const Tbd = union(enum) { pub const TapiError = error{ NotLibStub, InputOutput, -} || yaml.YamlError || std.fs.File.PReadError; +} || yaml.YamlError || Io.File.PReadError; pub const LibStub = struct { /// Underlying memory for stub's contents. @@ -139,7 +139,7 @@ pub const LibStub = struct { /// Typed contents of the tbd file. inner: []Tbd, - pub fn loadFromFile(allocator: Allocator, file: fs.File) TapiError!LibStub { + pub fn loadFromFile(allocator: Allocator, file: Io.File) TapiError!LibStub { const filesize = blk: { const stat = file.stat() catch break :blk std.math.maxInt(u32); break :blk @min(stat.size, std.math.maxInt(u32)); -- cgit v1.2.3 From dd1d15b72aa3bae4b38e2337609758ffb7a7b55a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 6 Dec 2025 17:32:19 -0800 Subject: update all occurrences of std.fs.Dir to std.Io.Dir --- lib/compiler/aro/aro/Compilation.zig | 6 ++-- lib/compiler/resinator/cli.zig | 2 +- lib/compiler/resinator/errors.zig | 6 ++-- lib/compiler/resinator/main.zig | 2 +- lib/compiler/resinator/utils.zig | 4 +-- lib/compiler/std-docs.zig | 2 +- lib/std/Build.zig | 2 +- lib/std/Build/Step.zig | 6 ++-- lib/std/Build/Watch.zig | 2 +- lib/std/Io/Dir.zig | 2 +- lib/std/crypto/Certificate/Bundle.zig | 4 +-- lib/std/dynamic_library.zig | 2 +- lib/std/fs/path.zig | 4 +-- lib/std/fs/test.zig | 13 ++++---- lib/std/process/Child.zig | 4 +-- lib/std/testing.zig | 60 ++++++++++++++++++----------------- lib/std/zig/WindowsSdk.zig | 8 ++--- lib/std/zig/llvm/Builder.zig | 2 +- lib/std/zip.zig | 5 +-- src/Compilation.zig | 4 +-- src/Package/Fetch/git.zig | 4 +-- src/fmt.zig | 6 ++-- src/link/Lld.zig | 7 ++-- src/link/MachO.zig | 2 +- 24 files changed, 81 insertions(+), 78 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index 06b27c33bb..c31caefb0f 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -154,7 +154,7 @@ gpa: Allocator, /// Allocations in this arena live all the way until `Compilation.deinit`. arena: Allocator, io: Io, -cwd: std.fs.Dir, +cwd: Io.Dir, diagnostics: *Diagnostics, sources: std.StringArrayHashMapUnmanaged(Source) = .empty, @@ -181,7 +181,7 @@ pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .empty, /// Used by MS extensions which allow searching for includes relative to the directory of the main source file. ms_cwd_source_id: ?Source.Id = null, -pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: std.fs.Dir) Compilation { +pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: Io.Dir) Compilation { return .{ .gpa = gpa, .arena = arena, @@ -193,7 +193,7 @@ pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, /// Initialize Compilation with default environment, /// pragma handlers and emulation mode set to target. -pub fn initDefault(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: std.fs.Dir) !Compilation { +pub fn initDefault(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: Io.Dir) !Compilation { var comp: Compilation = .{ .gpa = gpa, .arena = arena, diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index 17da5c7b75..bb54289e3e 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -250,7 +250,7 @@ pub const Options = struct { /// worlds' situation where we'll be compatible with most use-cases /// of the .rc extension being omitted from the CLI args, but still /// work fine if the file itself does not have an extension. - pub fn maybeAppendRC(options: *Options, cwd: std.fs.Dir) !void { + pub fn maybeAppendRC(options: *Options, cwd: Io.Dir) !void { switch (options.input_source) { .stdio => return, .filename => {}, diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 61fd00e683..14ff28a697 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -67,7 +67,7 @@ pub const Diagnostics = struct { return @intCast(index); } - pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void { + pub fn renderToStdErr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { const io = self.io; const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); @@ -903,7 +903,7 @@ pub fn renderErrorMessage( io: Io, writer: *std.Io.Writer, tty_config: std.Io.tty.Config, - cwd: std.fs.Dir, + cwd: Io.Dir, err_details: ErrorDetails, source: []const u8, strings: []const []const u8, @@ -1100,7 +1100,7 @@ const CorrespondingLines = struct { pub fn init( io: Io, - cwd: std.fs.Dir, + cwd: Io.Dir, err_details: ErrorDetails, line_for_comparison: []const u8, corresponding_span: SourceMappings.CorrespondingSpan, diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index e171d8199c..c726a06cf4 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -707,7 +707,7 @@ const ErrorHandler = union(enum) { pub fn emitDiagnostics( self: *ErrorHandler, allocator: Allocator, - cwd: std.fs.Dir, + cwd: Io.Dir, source: []const u8, diagnostics: *Diagnostics, mappings: SourceMappings, diff --git a/lib/compiler/resinator/utils.zig b/lib/compiler/resinator/utils.zig index e8565f3af9..3f03b73c54 100644 --- a/lib/compiler/resinator/utils.zig +++ b/lib/compiler/resinator/utils.zig @@ -25,11 +25,11 @@ pub const UncheckedSliceWriter = struct { } }; -/// Cross-platform 'std.fs.Dir.openFile' wrapper that will always return IsDir if +/// Cross-platform 'Io.Dir.openFile' wrapper that will always return IsDir if /// a directory is attempted to be opened. /// TODO: Remove once https://github.com/ziglang/zig/issues/5732 is addressed. pub fn openFileNotDir( - cwd: std.fs.Dir, + cwd: Io.Dir, io: Io, path: []const u8, flags: Io.File.OpenFlags, diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 15c17ee59b..f1ca7fb5bb 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -133,7 +133,7 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void { const Context = struct { gpa: Allocator, io: Io, - lib_dir: std.fs.Dir, + lib_dir: Io.Dir, zig_lib_directory: []const u8, zig_exe_path: []const u8, global_cache_path: []const u8, diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 2755b895c2..7bfdbb6449 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1699,7 +1699,7 @@ pub fn addCheckFile( return Step.CheckFile.create(b, file_source, options); } -pub fn truncateFile(b: *Build, dest_path: []const u8) (fs.Dir.MakeError || fs.Dir.StatFileError)!void { +pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void { const io = b.graph.io; if (b.verbose) log.info("truncate {s}", .{dest_path}); const cwd = fs.cwd(); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 2b1e6d8ace..56ef32e8d8 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -505,7 +505,7 @@ pub fn evalZigProcess( return result; } -/// Wrapper around `std.fs.Dir.updateFile` that handles verbose and error output. +/// Wrapper around `Io.Dir.updateFile` that handles verbose and error output. pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u8) !Io.Dir.PrevStatus { const b = s.owner; const io = b.graph.io; @@ -515,8 +515,8 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u return s.fail("unable to update file from '{f}' to '{s}': {t}", .{ src_path, dest_path, err }); } -/// Wrapper around `std.fs.Dir.makePathStatus` that handles verbose and error output. -pub fn installDir(s: *Step, dest_path: []const u8) !std.fs.Dir.MakePathStatus { +/// Wrapper around `Io.Dir.makePathStatus` that handles verbose and error output. +pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus { const b = s.owner; try handleVerbose(b, null, &.{ "install", "-d", dest_path }); return std.fs.cwd().makePathStatus(dest_path) catch |err| diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index ca01376e02..ff06ad3ff3 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -350,7 +350,7 @@ const Os = switch (builtin.os.tag) { } fn init(gpa: Allocator, path: Cache.Path) !*@This() { - // The following code is a drawn out NtCreateFile call. (mostly adapted from std.fs.Dir.makeOpenDirAccessMaskW) + // The following code is a drawn out NtCreateFile call. (mostly adapted from Io.Dir.makeOpenDirAccessMaskW) // It's necessary in order to get the specific flags that are required when calling ReadDirectoryChangesW. var dir_handle: windows.HANDLE = undefined; const root_fd = path.root_dir.handle.fd; diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 5a74c8ca72..1c28c2f9b3 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -481,7 +481,7 @@ pub fn updateFile( } var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available. - var atomic_file = try std.fs.Dir.atomicFile(.adaptFromNewApi(dest_dir), dest_path, .{ + var atomic_file = try Dir.atomicFile(.adaptFromNewApi(dest_dir), dest_path, .{ .permissions = actual_permissions, .write_buffer = &buffer, }); diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 1d21918b5c..df671e6f63 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -177,7 +177,7 @@ pub fn addCertsFromDirPath( cb: *Bundle, gpa: Allocator, io: Io, - dir: fs.Dir, + dir: Io.Dir, sub_dir_path: []const u8, ) AddCertsFromDirPathError!void { var iterable_dir = try dir.openDir(sub_dir_path, .{ .iterate = true }); @@ -200,7 +200,7 @@ pub fn addCertsFromDirPathAbsolute( pub const AddCertsFromDirError = AddCertsFromFilePathError; -pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, iterable_dir: fs.Dir) AddCertsFromDirError!void { +pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, iterable_dir: Io.Dir) AddCertsFromDirError!void { var it = iterable_dir.iterate(); while (try it.next()) |entry| { switch (entry.kind) { diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index ca36d5cbb9..7db177ad70 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -157,7 +157,7 @@ pub const ElfDynLib = struct { dt_gnu_hash: *elf.gnu_hash.Header, }; - fn openPath(path: []const u8, io: Io) !std.fs.Dir { + fn openPath(path: []const u8, io: Io) !Io.Dir { if (path.len == 0) return error.NotDir; var parts = std.mem.tokenizeScalar(u8, path, '/'); var parent = if (path[0] == '/') try std.fs.cwd().openDir("/", .{}) else std.fs.cwd(); diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index f00007756f..a8465f52d4 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -872,7 +872,7 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error! /// This function is like a series of `cd` statements executed one after another. /// It resolves "." and ".." to the best of its ability, but will not convert relative paths to -/// an absolute path, use std.fs.Dir.realpath instead. +/// an absolute path, use Io.Dir.realpath instead. /// ".." components may persist in the resolved path if the resolved path is relative or drive-relative. /// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters. /// @@ -1095,7 +1095,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator /// This function is like a series of `cd` statements executed one after another. /// It resolves "." and ".." to the best of its ability, but will not convert relative paths to -/// an absolute path, use std.fs.Dir.realpath instead. +/// an absolute path, use Io.Dir.realpath instead. /// ".." components may persist in the resolved path if the resolved path is relative. /// The result does not have a trailing path separator. /// This function does not perform any syscalls. Executing this series of path diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index f770ddd30e..36ccd3a6be 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -9,12 +9,11 @@ const mem = std.mem; const wasi = std.os.wasi; const windows = std.os.windows; const posix = std.posix; - const ArenaAllocator = std.heap.ArenaAllocator; -const Dir = std.fs.Dir; +const Dir = std.Io.Dir; const File = std.Io.File; -const tmpDir = testing.tmpDir; -const SymLinkFlags = std.fs.Dir.SymLinkFlags; +const tmpDir = std.testing.tmpDir; +const SymLinkFlags = std.Io.Dir.SymLinkFlags; const PathType = enum { relative, @@ -80,7 +79,7 @@ const TestContext = struct { path_sep: u8, arena: ArenaAllocator, tmp: testing.TmpDir, - dir: std.fs.Dir, + dir: Io.Dir, transform_fn: *const PathType.TransformFn, pub fn init(path_type: PathType, path_sep: u8, allocator: mem.Allocator, transform_fn: *const PathType.TransformFn) TestContext { @@ -1772,7 +1771,7 @@ test "open file with exclusive lock twice, make sure second lock waits" { errdefer file.close(io); const S = struct { - fn checkFn(dir: *fs.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { + fn checkFn(dir: *Io.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { started.set(); const file1 = try dir.createFile(path, .{ .lock = .exclusive }); @@ -2016,7 +2015,7 @@ test "walker without fully iterating" { try testing.expectEqual(@as(usize, 1), num_walked); } -test "'.' and '..' in fs.Dir functions" { +test "'.' and '..' in Io.Dir functions" { if (native_os == .windows and builtin.cpu.arch == .aarch64) { // https://github.com/ziglang/zig/issues/17134 return error.SkipZigTest; diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index 87d2fe3ba9..b774303901 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -77,7 +77,7 @@ cwd: ?[]const u8, /// Set to change the current working directory when spawning the child process. /// This is not yet implemented for Windows. See https://github.com/ziglang/zig/issues/5190 /// Once that is done, `cwd` will be deprecated in favor of this field. -cwd_dir: ?fs.Dir = null, +cwd_dir: ?Io.Dir = null, err_pipe: if (native_os == .windows) void else ?posix.fd_t, @@ -439,7 +439,7 @@ pub fn run(args: struct { allocator: mem.Allocator, argv: []const []const u8, cwd: ?[]const u8 = null, - cwd_dir: ?fs.Dir = null, + cwd_dir: ?Io.Dir = null, /// Required if unable to access the current env map (e.g. building a /// library on some platforms). env_map: ?*const EnvMap = null, diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 63131d771c..19038543a6 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -1,5 +1,7 @@ -const std = @import("std.zig"); const builtin = @import("builtin"); + +const std = @import("std.zig"); +const Io = std.Io; const assert = std.debug.assert; const math = std.math; @@ -28,7 +30,7 @@ pub var allocator_instance: std.heap.GeneralPurposeAllocator(.{ break :b .init; }; -pub var io_instance: std.Io.Threaded = undefined; +pub var io_instance: Io.Threaded = undefined; pub const io = io_instance.io(); /// TODO https://github.com/ziglang/zig/issues/5738 @@ -355,7 +357,7 @@ test expectApproxEqRel { /// This function is intended to be used only in tests. When the two slices are not /// equal, prints diagnostics to stderr to show exactly how they are not equal (with /// the differences highlighted in red), then returns a test failure error. -/// The colorized output is optional and controlled by the return of `std.Io.tty.Config.detect`. +/// The colorized output is optional and controlled by the return of `Io.tty.Config.detect`. /// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead. pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void { const diff_index: usize = diff_index: { @@ -378,8 +380,8 @@ fn failEqualSlices( expected: []const T, actual: []const T, diff_index: usize, - w: *std.Io.Writer, - ttyconf: std.Io.tty.Config, + w: *Io.Writer, + ttyconf: Io.tty.Config, ) !void { try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); @@ -464,11 +466,11 @@ fn SliceDiffer(comptime T: type) type { start_index: usize, expected: []const T, actual: []const T, - ttyconf: std.Io.tty.Config, + ttyconf: Io.tty.Config, const Self = @This(); - pub fn write(self: Self, writer: *std.Io.Writer) !void { + pub fn write(self: Self, writer: *Io.Writer) !void { for (self.expected, 0..) |value, i| { const full_index = self.start_index + i; const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; @@ -487,9 +489,9 @@ fn SliceDiffer(comptime T: type) type { const BytesDiffer = struct { expected: []const u8, actual: []const u8, - ttyconf: std.Io.tty.Config, + ttyconf: Io.tty.Config, - pub fn write(self: BytesDiffer, writer: *std.Io.Writer) !void { + pub fn write(self: BytesDiffer, writer: *Io.Writer) !void { var expected_iterator = std.mem.window(u8, self.expected, 16, 16); var row: usize = 0; while (expected_iterator.next()) |chunk| { @@ -535,7 +537,7 @@ const BytesDiffer = struct { } } - fn writeDiff(self: BytesDiffer, writer: *std.Io.Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void { + fn writeDiff(self: BytesDiffer, writer: *Io.Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void { if (diff) try self.ttyconf.setColor(writer, .red); try writer.print(fmt, args); if (diff) try self.ttyconf.setColor(writer, .reset); @@ -605,8 +607,8 @@ pub fn expect(ok: bool) !void { } pub const TmpDir = struct { - dir: std.fs.Dir, - parent_dir: std.fs.Dir, + dir: Io.Dir, + parent_dir: Io.Dir, sub_path: [sub_path_len]u8, const random_bytes_count = 12; @@ -620,7 +622,7 @@ pub const TmpDir = struct { } }; -pub fn tmpDir(opts: std.fs.Dir.OpenOptions) TmpDir { +pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir { var random_bytes: [TmpDir.random_bytes_count]u8 = undefined; std.crypto.random.bytes(&random_bytes); var sub_path: [TmpDir.sub_path_len]u8 = undefined; @@ -929,7 +931,7 @@ test "expectEqualDeep primitive type" { a, b, - pub fn format(self: @This(), writer: *std.Io.Writer) !void { + pub fn format(self: @This(), writer: *Io.Writer) !void { try writer.writeAll(@tagName(self)); } }; @@ -1160,7 +1162,7 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime } else |err| switch (err) { error.OutOfMemory => { if (failing_allocator_inst.allocated_bytes != failing_allocator_inst.freed_bytes) { - const tty_config: std.Io.tty.Config = .detect(.stderr()); + const tty_config: Io.tty.Config = .detect(.stderr()); print( "\nfail_index: {d}/{d}\nallocated bytes: {d}\nfreed bytes: {d}\nallocations: {d}\ndeallocations: {d}\nallocation that was made to fail: {f}", .{ @@ -1220,14 +1222,14 @@ pub inline fn fuzz( return @import("root").fuzz(context, testOne, options); } -/// A `std.Io.Reader` that writes a predetermined list of buffers during `stream`. +/// A `Io.Reader` that writes a predetermined list of buffers during `stream`. pub const Reader = struct { calls: []const Call, - interface: std.Io.Reader, + interface: Io.Reader, next_call_index: usize, next_offset: usize, /// Further reduces how many bytes are written in each `stream` call. - artificial_limit: std.Io.Limit = .unlimited, + artificial_limit: Io.Limit = .unlimited, pub const Call = struct { buffer: []const u8, @@ -1247,7 +1249,7 @@ pub const Reader = struct { }; } - fn stream(io_r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize { + fn stream(io_r: *Io.Reader, w: *Io.Writer, limit: Io.Limit) Io.Reader.StreamError!usize { const r: *Reader = @alignCast(@fieldParentPtr("interface", io_r)); if (r.calls.len - r.next_call_index == 0) return error.EndOfStream; const call = r.calls[r.next_call_index]; @@ -1262,13 +1264,13 @@ pub const Reader = struct { } }; -/// A `std.Io.Reader` that gets its data from another `std.Io.Reader`, and always +/// A `Io.Reader` that gets its data from another `Io.Reader`, and always /// writes to its own buffer (and returns 0) during `stream` and `readVec`. pub const ReaderIndirect = struct { - in: *std.Io.Reader, - interface: std.Io.Reader, + in: *Io.Reader, + interface: Io.Reader, - pub fn init(in: *std.Io.Reader, buffer: []u8) ReaderIndirect { + pub fn init(in: *Io.Reader, buffer: []u8) ReaderIndirect { return .{ .in = in, .interface = .{ @@ -1283,17 +1285,17 @@ pub const ReaderIndirect = struct { }; } - fn readVec(r: *std.Io.Reader, _: [][]u8) std.Io.Reader.Error!usize { + fn readVec(r: *Io.Reader, _: [][]u8) Io.Reader.Error!usize { try streamInner(r); return 0; } - fn stream(r: *std.Io.Reader, _: *std.Io.Writer, _: std.Io.Limit) std.Io.Reader.StreamError!usize { + fn stream(r: *Io.Reader, _: *Io.Writer, _: Io.Limit) Io.Reader.StreamError!usize { try streamInner(r); return 0; } - fn streamInner(r: *std.Io.Reader) std.Io.Reader.Error!void { + fn streamInner(r: *Io.Reader) Io.Reader.Error!void { const r_indirect: *ReaderIndirect = @alignCast(@fieldParentPtr("interface", r)); // If there's no room remaining in the buffer at all, make room. @@ -1301,12 +1303,12 @@ pub const ReaderIndirect = struct { try r.rebase(r.buffer.len); } - var writer: std.Io.Writer = .{ + var writer: Io.Writer = .{ .buffer = r.buffer, .end = r.end, .vtable = &.{ - .drain = std.Io.Writer.unreachableDrain, - .rebase = std.Io.Writer.unreachableRebase, + .drain = Io.Writer.unreachableDrain, + .rebase = Io.Writer.unreachableRebase, }, }; defer r.end = writer.end; diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig index a7b16e1bed..6b6e4fa9f7 100644 --- a/lib/std/zig/WindowsSdk.zig +++ b/lib/std/zig/WindowsSdk.zig @@ -77,7 +77,7 @@ pub fn free(sdk: WindowsSdk, allocator: Allocator) void { /// and a version. Returns slice of version strings sorted in descending order. /// Caller owns result. fn iterateAndFilterByVersion( - iterator: *std.fs.Dir.Iterator, + iterator: *Io.Dir.Iterator, allocator: Allocator, prefix: []const u8, ) error{OutOfMemory}![][]const u8 { @@ -608,7 +608,7 @@ pub const Installation = struct { }; const MsvcLibDir = struct { - fn findInstancesDirViaSetup(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { + fn findInstancesDirViaSetup(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir { const vs_setup_key_path = "SOFTWARE\\Microsoft\\VisualStudio\\Setup"; const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path, .{}) catch |err| switch (err) { error.KeyNotFound => return error.PathNotFound, @@ -633,7 +633,7 @@ const MsvcLibDir = struct { return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; } - fn findInstancesDirViaCLSID(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { + fn findInstancesDirViaCLSID(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir { const setup_configuration_clsid = "{177f0c4a-1cd3-4de7-a32c-71dbbb9fa36d}"; const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid, .{}) catch |err| switch (err) { error.KeyNotFound => return error.PathNotFound, @@ -669,7 +669,7 @@ const MsvcLibDir = struct { return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; } - fn findInstancesDir(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { + fn findInstancesDir(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir { // First, try getting the packages cache path from the registry. // This only seems to exist when the path is different from the default. method1: { diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 9ca0124f4f..443bdcc391 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -9582,7 +9582,7 @@ pub fn dump(b: *Builder) void { b.printToFile(stderr, &buffer) catch {}; } -pub fn printToFilePath(b: *Builder, io: Io, dir: std.fs.Dir, path: []const u8) !void { +pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void { var buffer: [4000]u8 = undefined; const file = try dir.createFile(io, path, .{}); defer file.close(io); diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 9588651e7f..0ca77c98a1 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -7,6 +7,7 @@ const builtin = @import("builtin"); const is_le = builtin.target.cpu.arch.endian() == .little; const std = @import("std"); +const Io = std.Io; const File = std.Io.File; const Writer = std.Io.Writer; const Reader = std.Io.Reader; @@ -461,7 +462,7 @@ pub const Iterator = struct { stream: *File.Reader, options: ExtractOptions, filename_buf: []u8, - dest: std.fs.Dir, + dest: Io.Dir, ) !void { if (filename_buf.len < self.filename_len) return error.ZipInsufficientBuffer; @@ -650,7 +651,7 @@ pub const ExtractOptions = struct { }; /// Extract the zipped files to the given `dest` directory. -pub fn extract(dest: std.fs.Dir, fr: *File.Reader, options: ExtractOptions) !void { +pub fn extract(dest: Io.Dir, fr: *File.Reader, options: ExtractOptions) !void { if (options.verify_checksums) @panic("TODO unimplemented"); var iter = try Iterator.init(fr); diff --git a/src/Compilation.zig b/src/Compilation.zig index 582c9dff3c..d75cba5a11 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -446,7 +446,7 @@ pub const Path = struct { } /// Given a `Path`, returns the directory handle and sub path to be used to open the path. - pub fn openInfo(p: Path, dirs: Directories) struct { fs.Dir, []const u8 } { + pub fn openInfo(p: Path, dirs: Directories) struct { Io.Dir, []const u8 } { const dir = switch (p.root) { .none => { const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); @@ -1872,7 +1872,7 @@ pub const CreateDiagnostic = union(enum) { pub const CreateCachePath = struct { which: enum { local, global }, sub: []const u8, - err: (fs.Dir.MakeError || fs.Dir.OpenError || fs.Dir.StatFileError), + err: (Io.Dir.MakeError || Io.Dir.OpenError || Io.Dir.StatFileError), }; pub fn format(diag: CreateDiagnostic, w: *Writer) Writer.Error!void { switch (diag) { diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 0fca3a0ee3..abaa8fef73 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -214,7 +214,7 @@ pub const Repository = struct { pub fn checkout( repository: *Repository, io: Io, - worktree: std.fs.Dir, + worktree: Io.Dir, commit_oid: Oid, diagnostics: *Diagnostics, ) !void { @@ -231,7 +231,7 @@ pub const Repository = struct { fn checkoutTree( repository: *Repository, io: Io, - dir: std.fs.Dir, + dir: Io.Dir, tree_oid: Oid, current_path: []const u8, diagnostics: *Diagnostics, diff --git a/src/fmt.zig b/src/fmt.zig index 7bdc24054e..663d09e9cb 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -204,7 +204,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! } } -fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) !void { +fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: Io.Dir, sub_path: []const u8) !void { fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) { error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path), else => { @@ -219,7 +219,7 @@ fn fmtPathDir( fmt: *Fmt, file_path: []const u8, check_mode: bool, - parent_dir: fs.Dir, + parent_dir: Io.Dir, parent_sub_path: []const u8, ) !void { const io = fmt.io; @@ -257,7 +257,7 @@ fn fmtPathFile( fmt: *Fmt, file_path: []const u8, check_mode: bool, - dir: fs.Dir, + dir: Io.Dir, sub_path: []const u8, ) !void { const io = fmt.io; diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 66b032e0a9..49f6d3f7c7 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -400,7 +400,7 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { // regarding eliding redundant object -> object transformations. return error.NoObjectsToLink; }; - try std.fs.Dir.copyFile( + try Io.Dir.copyFile( the_object_path.root_dir.handle, the_object_path.sub_path, directory.handle, @@ -816,7 +816,7 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { // regarding eliding redundant object -> object transformations. return error.NoObjectsToLink; }; - try std.fs.Dir.copyFile( + try Io.Dir.copyFile( the_object_path.root_dir.handle, the_object_path.sub_path, directory.handle, @@ -1371,7 +1371,7 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { // regarding eliding redundant object -> object transformations. return error.NoObjectsToLink; }; - try fs.Dir.copyFile( + try Io.Dir.copyFile( the_object_path.root_dir.handle, the_object_path.sub_path, directory.handle, @@ -1692,6 +1692,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi } const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const Cache = std.Build.Cache; const allocPrint = std.fmt.allocPrint; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 72a49c0c9e..93adc633ce 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3573,7 +3573,7 @@ pub fn getTarget(self: *const MachO) *const std.Target { /// into a new inode, remove the original file, and rename the copy to match /// the original file. This is super messy, but there doesn't seem any other /// way to please the XNU. -pub fn invalidateKernelCache(dir: fs.Dir, sub_path: []const u8) !void { +pub fn invalidateKernelCache(dir: Io.Dir, sub_path: []const u8) !void { const tracy = trace(@src()); defer tracy.end(); if (builtin.target.os.tag.isDarwin() and builtin.target.cpu.arch == .aarch64) { -- cgit v1.2.3 From 8328de24f13e21e325207b19288a143854df50df Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 6 Dec 2025 17:52:57 -0800 Subject: update all occurrences of openFile to receive an io instance --- lib/compiler/aro/aro/Compilation.zig | 4 +-- lib/compiler/aro/aro/Driver/Filesystem.zig | 2 +- lib/compiler/aro/aro/Toolchain.zig | 6 ++-- lib/compiler/objcopy.zig | 2 +- lib/compiler/std-docs.zig | 2 +- lib/std/Build/Cache.zig | 8 ++++-- lib/std/Build/Cache/Path.zig | 8 ++---- lib/std/Build/Fuzz.zig | 4 +-- lib/std/Build/Step/Run.zig | 6 ++-- lib/std/Build/Step/UpdateSourceFiles.zig | 2 +- lib/std/Build/Step/WriteFile.zig | 6 ++-- lib/std/Build/WebServer.zig | 4 +-- lib/std/Io/Dir.zig | 2 +- lib/std/Io/test.zig | 2 +- lib/std/Thread.zig | 4 +-- lib/std/crypto/Certificate/Bundle.zig | 2 +- lib/std/debug/ElfFile.zig | 2 +- lib/std/debug/Info.zig | 2 +- lib/std/debug/MachOFile.zig | 2 +- lib/std/debug/SelfInfo/Elf.zig | 4 +-- lib/std/debug/SelfInfo/MachO.zig | 2 +- lib/std/debug/SelfInfo/Windows.zig | 6 ++-- lib/std/fs.zig | 17 ----------- lib/std/fs/test.zig | 46 +++++++++++++++--------------- lib/std/os/linux/IoUring.zig | 6 ++-- lib/std/posix/test.zig | 8 +++--- lib/std/zig/system.zig | 6 ++-- src/Compilation.zig | 8 +++--- src/Package/Fetch.zig | 6 ++-- src/Package/Fetch/git.zig | 2 +- src/Zcu.zig | 2 +- src/Zcu/PerThread.zig | 4 +-- src/fmt.zig | 2 +- src/introspect.zig | 4 +-- src/link.zig | 24 ++++++++-------- src/link/Coff.zig | 4 +-- src/link/Elf2.zig | 14 +++++---- src/link/MachO.zig | 8 ++++-- src/link/MachO/relocatable.zig | 7 +++-- src/link/MappedFile.zig | 2 +- src/main.zig | 10 +++---- 41 files changed, 124 insertions(+), 138 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index c31caefb0f..09e4861d13 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -1641,7 +1641,7 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin const io = comp.io; - const file = try comp.cwd.openFile(path, .{}); + const file = try comp.cwd.openFile(io, path, .{}); defer file.close(io); return comp.addSourceFromFile(file, path, kind); } @@ -1975,7 +1975,7 @@ fn getPathContents(comp: *Compilation, path: []const u8, limit: Io.Limit) ![]u8 const io = comp.io; - const file = try comp.cwd.openFile(path, .{}); + const file = try comp.cwd.openFile(io, path, .{}); defer file.close(io); return comp.getFileContents(file, limit); } diff --git a/lib/compiler/aro/aro/Driver/Filesystem.zig b/lib/compiler/aro/aro/Driver/Filesystem.zig index 19ac9bfe41..b0bdbb7e21 100644 --- a/lib/compiler/aro/aro/Driver/Filesystem.zig +++ b/lib/compiler/aro/aro/Driver/Filesystem.zig @@ -213,7 +213,7 @@ pub const Filesystem = union(enum) { pub fn readFile(fs: Filesystem, io: Io, path: []const u8, buf: []u8) ?[]const u8 { return switch (fs) { .real => |cwd| { - const file = cwd.openFile(path, .{}) catch return null; + const file = cwd.openFile(io, path, .{}) catch return null; defer file.close(io); const bytes_read = file.readAll(buf) catch return null; diff --git a/lib/compiler/aro/aro/Toolchain.zig b/lib/compiler/aro/aro/Toolchain.zig index ae84369205..95a8baba77 100644 --- a/lib/compiler/aro/aro/Toolchain.zig +++ b/lib/compiler/aro/aro/Toolchain.zig @@ -524,12 +524,12 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned pub fn readFile(tc: *const Toolchain, path: []const u8, buf: []u8) ?[]const u8 { const comp = tc.driver.comp; - return comp.cwd.adaptToNewApi().readFile(comp.io, path, buf) catch null; + return comp.cwd.readFile(comp.io, path, buf) catch null; } pub fn exists(tc: *const Toolchain, path: []const u8) bool { const comp = tc.driver.comp; - comp.cwd.adaptToNewApi().access(comp.io, path, .{}) catch return false; + comp.cwd.access(comp.io, path, .{}) catch return false; return true; } @@ -547,7 +547,7 @@ pub fn canExecute(tc: *const Toolchain, path: []const u8) bool { } const comp = tc.driver.comp; - comp.cwd.adaptToNewApi().access(comp.io, path, .{ .execute = true }) catch return false; + comp.cwd.access(comp.io, path, .{ .execute = true }) catch return false; // Todo: ensure path is not a directory return true; } diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index c360ea8df0..485e644daa 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -157,7 +157,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); - var in: File.Reader = .initSize(input_file.adaptToNewApi(), io, &input_buffer, stat.size); + var in: File.Reader = .initSize(input_file, io, &input_buffer, stat.size); const elf_hdr = std.elf.Header.read(&in.interface) catch |err| switch (err) { error.ReadFailed => fatal("unable to read {s}: {t}", .{ input, in.err.? }), diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index f1ca7fb5bb..e4efac28cd 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -225,7 +225,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { }, else => continue, } - var file = try entry.dir.openFile(entry.basename, .{}); + var file = try entry.dir.openFile(io, entry.basename, .{}); defer file.close(io); const stat = try file.stat(); var file_reader: std.Io.File.Reader = .{ diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index b06547dc53..42459c033d 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -502,6 +502,8 @@ pub const Manifest = struct { @memcpy(manifest_file_path[0..self.hex_digest.len], &self.hex_digest); manifest_file_path[hex_digest_len..][0..ext.len].* = ext.*; + const io = self.cache.io; + // We'll try to open the cache with an exclusive lock, but if that would block // and `want_shared_lock` is set, a shared lock might be sufficient, so we'll // open with a shared lock instead. @@ -517,7 +519,7 @@ pub const Manifest = struct { break; } else |err| switch (err) { error.WouldBlock => { - self.manifest_file = self.cache.manifest_dir.openFile(&manifest_file_path, .{ + self.manifest_file = self.cache.manifest_dir.openFile(io, &manifest_file_path, .{ .mode = .read_write, .lock = .shared, }) catch |e| { @@ -757,7 +759,7 @@ pub const Manifest = struct { const pp = cache_hash_file.prefixed_path; const dir = self.cache.prefixes()[pp.prefix].handle; - const this_file = dir.openFile(pp.sub_path, .{ .mode = .read_only }) catch |err| switch (err) { + const this_file = dir.openFile(io, pp.sub_path, .{ .mode = .read_only }) catch |err| switch (err) { error.FileNotFound => { // Every digest before this one has been populated successfully. return .{ .miss = .{ .file_digests_populated = idx } }; @@ -900,7 +902,7 @@ pub const Manifest = struct { } else { const pp = ch_file.prefixed_path; const dir = self.cache.prefixes()[pp.prefix].handle; - const handle = try dir.openFile(pp.sub_path, .{}); + const handle = try dir.openFile(io, pp.sub_path, .{}); defer handle.close(io); return populateFileHashHandle(self, ch_file, handle); } diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index f6f76c1e8f..60211670de 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -59,18 +59,14 @@ pub fn joinStringZ(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Erro return p.root_dir.joinZ(gpa, parts); } -pub fn openFile( - p: Path, - sub_path: []const u8, - flags: Io.File.OpenFlags, -) !Io.File { +pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.File.OpenFlags) !Io.File { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.openFile(joined_path, flags); + return p.root_dir.handle.openFile(io, joined_path, flags); } pub fn openDir( diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index db83f393fd..c95c9bd354 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -405,7 +405,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO .root_dir = run_step.step.owner.cache_root, .sub_path = "v/" ++ std.fmt.hex(coverage_id), }; - var coverage_file = coverage_file_path.root_dir.handle.openFile(coverage_file_path.sub_path, .{}) catch |err| { + var coverage_file = coverage_file_path.root_dir.handle.openFile(io, coverage_file_path.sub_path, .{}) catch |err| { log.err("step '{s}': failed to load coverage file '{f}': {t}", .{ run_step.step.name, coverage_file_path, err, }); @@ -528,7 +528,7 @@ pub fn waitAndPrintReport(fuzz: *Fuzz) void { .root_dir = cov.run.step.owner.cache_root, .sub_path = "v/" ++ std.fmt.hex(cov.id), }; - var coverage_file = coverage_file_path.root_dir.handle.openFile(coverage_file_path.sub_path, .{}) catch |err| { + var coverage_file = coverage_file_path.root_dir.handle.openFile(io, coverage_file_path.sub_path, .{}) catch |err| { fatal("step '{s}': failed to load coverage file '{f}': {t}", .{ cov.run.step.name, coverage_file_path, err, }); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 1df6f42a35..7c54c8048e 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -846,7 +846,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { errdefer result.deinit(); result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory; - const file = file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{}) catch |err| { + const file = file_path.root_dir.handle.openFile(io, file_path.subPathOrDot(), .{}) catch |err| { return step.fail( "unable to open input file '{f}': {t}", .{ file_path, err }, @@ -1111,7 +1111,7 @@ pub fn rerunInFuzzMode( errdefer result.deinit(); result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory; - const file = try file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{}); + const file = try file_path.root_dir.handle.openFile(io, file_path.subPathOrDot(), .{}); defer file.close(io); var buf: [1024]u8 = undefined; @@ -2185,7 +2185,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { }, .lazy_path => |lazy_path| { const path = lazy_path.getPath3(b, &run.step); - const file = path.root_dir.handle.openFile(path.subPathOrDot(), .{}) catch |err| { + const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| { return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)}); }; defer file.close(io); diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig index 7cdb521d21..f5d95182e9 100644 --- a/lib/std/Build/Step/UpdateSourceFiles.zig +++ b/lib/std/Build/Step/UpdateSourceFiles.zig @@ -99,7 +99,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .cwd(), io, source_path, - b.build_root.handle.adaptToNewApi(), + b.build_root.handle, output_source_file.sub_path, .{}, ) catch |err| { diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 201b132271..2834f18564 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -284,7 +284,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { }, .copy => |file_source| { const source_path = file_source.getPath2(b, step); - const prev_status = Io.Dir.updateFile(.cwd(), io, source_path, cache_dir.adaptToNewApi(), file.sub_path, .{}) catch |err| { + const prev_status = Io.Dir.updateFile(.cwd(), io, source_path, cache_dir, file.sub_path, .{}) catch |err| { return step.fail("unable to update file from '{s}' to '{f}{s}{c}{s}': {t}", .{ source_path, b.cache_root, cache_path, fs.path.sep, file.sub_path, err, }); @@ -321,10 +321,10 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .directory => try cache_dir.makePath(dest_path), .file => { const prev_status = Io.Dir.updateFile( - src_entry_path.root_dir.handle.adaptToNewApi(), + src_entry_path.root_dir.handle, io, src_entry_path.sub_path, - cache_dir.adaptToNewApi(), + cache_dir, dest_path, .{}, ) catch |err| { diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index f91075b444..9938d5e1b0 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -504,14 +504,14 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons var archiver: std.tar.Writer = .{ .underlying_writer = &response.writer }; for (paths) |path| { - var file = path.root_dir.handle.openFile(path.sub_path, .{}) catch |err| { + var file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err| { log.err("failed to open '{f}': {s}", .{ path, @errorName(err) }); continue; }; defer file.close(io); const stat = try file.stat(); var read_buffer: [1024]u8 = undefined; - var file_reader: Io.File.Reader = .initSize(file.adaptToNewApi(), io, &read_buffer, stat.size); + var file_reader: Io.File.Reader = .initSize(file, io, &read_buffer, stat.size); // TODO: this logic is completely bogus -- obviously so, because `path.root_dir.path` can // be cwd-relative. This is also related to why linkification doesn't work in the fuzzer UI: diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 1c28c2f9b3..9ae636d4a6 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -481,7 +481,7 @@ pub fn updateFile( } var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available. - var atomic_file = try Dir.atomicFile(.adaptFromNewApi(dest_dir), dest_path, .{ + var atomic_file = try Dir.atomicFile(dest_dir, dest_path, .{ .permissions = actual_permissions, .write_buffer = &buffer, }); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index b922acc333..9f21fe50e7 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -44,7 +44,7 @@ test "write a file, read it, then delete it" { } { - var file = try tmp.dir.openFile(tmp_file_name, .{}); + var file = try tmp.dir.openFile(io, tmp_file_name, .{}); defer file.close(io); const file_size = try file.getEndPos(); diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 8d8e5979df..102bb59415 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -208,7 +208,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { var buf: [32]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); - const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only }); + const file = try std.fs.cwd().openFile(io, path, .{ .mode = .write_only }); defer file.close(io); try file.writeAll(name); @@ -325,7 +325,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co var threaded: std.Io.Threaded = .init_single_threaded; const io = threaded.ioBasic(); - const file = try std.fs.cwd().openFile(path, .{}); + const file = try std.fs.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.readerStreaming(io, &.{}); diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index df671e6f63..eb60ad37a8 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -208,7 +208,7 @@ pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, i else => continue, } - try addCertsFromFilePath(cb, gpa, io, now, iterable_dir.adaptToNewApi(), entry.name); + try addCertsFromFilePath(cb, gpa, io, now, iterable_dir, entry.name); } } diff --git a/lib/std/debug/ElfFile.zig b/lib/std/debug/ElfFile.zig index 5dbae18130..a0f1188ade 100644 --- a/lib/std/debug/ElfFile.zig +++ b/lib/std/debug/ElfFile.zig @@ -375,7 +375,7 @@ fn loadSeparateDebugFile( args: anytype, ) Allocator.Error!?[]align(std.heap.page_size_min) const u8 { const path = try std.fmt.allocPrint(arena, fmt, args); - const elf_file = std.fs.cwd().openFile(path, .{}) catch return null; + const elf_file = std.fs.cwd().openFile(io, path, .{}) catch return null; defer elf_file.close(io); const result = loadInner(arena, elf_file, opt_crc) catch |err| switch (err) { diff --git a/lib/std/debug/Info.zig b/lib/std/debug/Info.zig index da7656e626..6b31f03f72 100644 --- a/lib/std/debug/Info.zig +++ b/lib/std/debug/Info.zig @@ -39,7 +39,7 @@ pub fn load( ) LoadError!Info { switch (format) { .elf => { - var file = try path.root_dir.handle.openFile(path.sub_path, .{}); + var file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); defer file.close(io); var elf_file: ElfFile = try .load(gpa, file, null, &.none); diff --git a/lib/std/debug/MachOFile.zig b/lib/std/debug/MachOFile.zig index 3f0f620a90..ae904c0aec 100644 --- a/lib/std/debug/MachOFile.zig +++ b/lib/std/debug/MachOFile.zig @@ -512,7 +512,7 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { + const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig index 155dac6fb8..124768687c 100644 --- a/lib/std/debug/SelfInfo/Elf.zig +++ b/lib/std/debug/SelfInfo/Elf.zig @@ -325,7 +325,7 @@ const Module = struct { } fn loadElf(mod: *Module, gpa: Allocator, io: Io) Error!LoadedElf { const load_result = if (mod.name.len > 0) res: { - var file = std.fs.cwd().openFile(mod.name, .{}) catch return error.MissingDebugInfo; + var file = std.fs.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(mod.name)); } else res: { @@ -334,7 +334,7 @@ const Module = struct { else => return error.ReadFailed, }; defer gpa.free(path); - var file = std.fs.cwd().openFile(path, .{}) catch return error.MissingDebugInfo; + var file = std.fs.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(path)); }; diff --git a/lib/std/debug/SelfInfo/MachO.zig b/lib/std/debug/SelfInfo/MachO.zig index 2491cf416c..15da616f3b 100644 --- a/lib/std/debug/SelfInfo/MachO.zig +++ b/lib/std/debug/SelfInfo/MachO.zig @@ -616,7 +616,7 @@ test { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { + const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index 3af7223293..c7f9d8c352 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -387,7 +387,7 @@ const Module = struct { const section_view = section_view_ptr.?[0..coff_len]; coff_obj = coff.Coff.init(section_view, false) catch return error.InvalidDebugInfo; break :mapped .{ - .file = .adaptFromNewApi(coff_file), + .file = coff_file, .section_handle = section_handle, .section_view = section_view, }; @@ -432,7 +432,7 @@ const Module = struct { break :pdb null; }; const pdb_file_open_result = if (fs.path.isAbsolute(path)) res: { - break :res std.fs.cwd().openFile(path, .{}); + break :res std.fs.cwd().openFile(io, path, .{}); } else res: { const self_dir = fs.selfExeDirPathAlloc(gpa) catch |err| switch (err) { error.OutOfMemory, error.Unexpected => |e| return e, @@ -441,7 +441,7 @@ const Module = struct { defer gpa.free(self_dir); const abs_path = try fs.path.join(gpa, &.{ self_dir, path }); defer gpa.free(abs_path); - break :res std.fs.cwd().openFile(abs_path, .{}); + break :res std.fs.cwd().openFile(io, abs_path, .{}); }; const pdb_file = pdb_file_open_result catch |err| switch (err) { error.FileNotFound, error.IsDir => break :pdb null, diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 9472e5d2a5..cb4daf7c50 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -287,23 +287,6 @@ pub fn symLinkAbsoluteW( return windows.CreateSymbolicLink(null, mem.span(sym_link_path_w), mem.span(target_path_w), flags.is_directory); } -pub const OpenSelfExeError = Io.File.OpenSelfExeError; - -/// Deprecated in favor of `Io.File.openSelfExe`. -pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File { - if (native_os == .linux or native_os == .serenity or native_os == .windows) { - var threaded: Io.Threaded = .init_single_threaded; - const io = threaded.ioBasic(); - return .adaptFromNewApi(try Io.File.openSelfExe(io, flags)); - } - // Use of max_path_bytes here is valid as the resulting path is immediately - // opened with no modification. - var buf: [max_path_bytes]u8 = undefined; - const self_exe_path = try selfExePath(&buf); - buf[self_exe_path.len] = 0; - return openFileAbsolute(buf[0..self_exe_path.len :0], flags); -} - // This is `posix.ReadLinkError || posix.RealPathError` with impossible errors excluded pub const SelfExePathError = error{ FileNotFound, diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 36ccd3a6be..7d566da0e9 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -855,7 +855,7 @@ test "directory operations on files" { } // ensure the file still exists and is a file as a sanity check - file = try ctx.dir.openFile(test_file_name, .{}); + file = try ctx.dir.openFile(io, test_file_name, .{}); const stat = try file.stat(); try testing.expectEqual(File.Kind.file, stat.kind); file.close(io); @@ -895,12 +895,12 @@ test "file operations on directories" { if (native_os == .wasi and builtin.link_libc) { // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747 - const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }); + const handle = try ctx.dir.openFile(io, test_dir_name, .{ .mode = .read_write }); handle.close(io); } else { // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms. // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732 - try testing.expectError(error.IsDir, ctx.dir.openFile(test_dir_name, .{ .mode = .read_write })); + try testing.expectError(error.IsDir, ctx.dir.openFile(io, test_dir_name, .{ .mode = .read_write })); } if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) { @@ -973,8 +973,8 @@ test "Dir.rename files" { try ctx.dir.rename(test_file_name, renamed_test_file_name); // Ensure the file was renamed - try testing.expectError(error.FileNotFound, ctx.dir.openFile(test_file_name, .{})); - file = try ctx.dir.openFile(renamed_test_file_name, .{}); + try testing.expectError(error.FileNotFound, ctx.dir.openFile(io, test_file_name, .{})); + file = try ctx.dir.openFile(io, renamed_test_file_name, .{}); file.close(io); // Rename to self succeeds @@ -986,8 +986,8 @@ test "Dir.rename files" { existing_file.close(io); try ctx.dir.rename(renamed_test_file_name, existing_file_path); - try testing.expectError(error.FileNotFound, ctx.dir.openFile(renamed_test_file_name, .{})); - file = try ctx.dir.openFile(existing_file_path, .{}); + try testing.expectError(error.FileNotFound, ctx.dir.openFile(io, renamed_test_file_name, .{})); + file = try ctx.dir.openFile(io, existing_file_path, .{}); file.close(io); } }.impl); @@ -1026,7 +1026,7 @@ test "Dir.rename directories" { // Ensure the directory was renamed and the file still exists in it try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_renamed_path, .{})); dir = try ctx.dir.openDir(test_dir_renamed_again_path, .{}); - file = try dir.openFile("test_file", .{}); + file = try dir.openFile(io, "test_file", .{}); file.close(io); dir.close(io); } @@ -1119,8 +1119,8 @@ test "rename" { try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); // ensure the file was renamed - try testing.expectError(error.FileNotFound, tmp_dir1.dir.openFile(test_file_name, .{})); - file = try tmp_dir2.dir.openFile(renamed_test_file_name, .{}); + try testing.expectError(error.FileNotFound, tmp_dir1.dir.openFile(io, test_file_name, .{})); + file = try tmp_dir2.dir.openFile(io, renamed_test_file_name, .{}); file.close(io); } @@ -1156,8 +1156,8 @@ test "renameAbsolute" { ); // ensure the file was renamed - try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(test_file_name, .{})); - file = try tmp_dir.dir.openFile(renamed_test_file_name, .{}); + try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(io, test_file_name, .{})); + file = try tmp_dir.dir.openFile(io, renamed_test_file_name, .{}); const stat = try file.stat(); try testing.expectEqual(File.Kind.file, stat.kind); file.close(io); @@ -1512,7 +1512,7 @@ test "setEndPos" { const file_name = "afile.txt"; try tmp.dir.writeFile(.{ .sub_path = file_name, .data = "ninebytes" }); - const f = try tmp.dir.openFile(file_name, .{ .mode = .read_write }); + const f = try tmp.dir.openFile(io, file_name, .{ .mode = .read_write }); defer f.close(io); const initial_size = try f.getEndPos(); @@ -1856,7 +1856,7 @@ test "read from locked file" { .lock = .exclusive, }); defer f.close(io); - const f2 = try ctx.dir.openFile(filename, .{}); + const f2 = try ctx.dir.openFile(io, filename, .{}); defer f2.close(io); var buffer: [1]u8 = undefined; if (builtin.os.tag == .windows) { @@ -2041,12 +2041,12 @@ test "'.' and '..' in Io.Dir functions" { try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{}); try ctx.dir.rename(copy_path, rename_path); - const renamed_file = try ctx.dir.openFile(rename_path, .{}); + const renamed_file = try ctx.dir.openFile(io, rename_path, .{}); renamed_file.close(io); try ctx.dir.deleteFile(rename_path); try ctx.dir.writeFile(.{ .sub_path = update_path, .data = "something" }); - var dir = ctx.dir.adaptToNewApi(); + var dir = ctx.dir; const prev_status = try dir.updateFile(io, file_path, dir, update_path, .{}); try testing.expectEqual(Io.Dir.PrevStatus.stale, prev_status); @@ -2186,7 +2186,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.access(invalid_path, .{})); - var dir = ctx.dir.adaptToNewApi(); + var dir = ctx.dir; try testing.expectError(expected_err, dir.updateFile(io, invalid_path, dir, invalid_path, .{})); try testing.expectError(expected_err, ctx.dir.copyFile(invalid_path, ctx.dir, invalid_path, .{})); @@ -2235,7 +2235,7 @@ test "read file non vectored" { try file_writer.interface.flush(); } - var file_reader: std.Io.File.Reader = .initAdapted(file, io, &.{}); + var file_reader: std.Io.File.Reader = .init(file, io, &.{}); var write_buffer: [100]u8 = undefined; var w: std.Io.Writer = .fixed(&write_buffer); @@ -2268,7 +2268,7 @@ test "seek keeping partial buffer" { } var read_buffer: [3]u8 = undefined; - var file_reader: Io.File.Reader = .initAdapted(file, io, &read_buffer); + var file_reader: Io.File.Reader = .init(file, io, &read_buffer); try testing.expectEqual(0, file_reader.logicalPos()); @@ -2301,7 +2301,7 @@ test "seekBy" { defer tmp_dir.cleanup(); try tmp_dir.dir.writeFile(.{ .sub_path = "blah.txt", .data = "let's test seekBy" }); - const f = try tmp_dir.dir.openFile("blah.txt", .{ .mode = .read_only }); + const f = try tmp_dir.dir.openFile(io, "blah.txt", .{ .mode = .read_only }); defer f.close(io); var reader = f.readerStreaming(io, &.{}); try reader.seekBy(2); @@ -2332,7 +2332,7 @@ test "seekTo flushes buffered data" { } var read_buffer: [16]u8 = undefined; - var file_reader: std.Io.File.Reader = .initAdapted(file, io, &read_buffer); + var file_reader: std.Io.File.Reader = .init(file, io, &read_buffer); var buf: [4]u8 = undefined; try file_reader.interface.readSliceAll(&buf); @@ -2347,7 +2347,7 @@ test "File.Writer sendfile with buffered contents" { { try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); - const in = try tmp_dir.dir.openFile("a", .{}); + const in = try tmp_dir.dir.openFile(io, "a", .{}); defer in.close(io); const out = try tmp_dir.dir.createFile("b", .{}); defer out.close(io); @@ -2364,7 +2364,7 @@ test "File.Writer sendfile with buffered contents" { try out_w.interface.flush(); } - var check = try tmp_dir.dir.openFile("b", .{}); + var check = try tmp_dir.dir.openFile(io, "b", .{}); defer check.close(io); var check_buf: [4]u8 = undefined; var check_r = check.reader(io, &check_buf); diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index e4a5bd3738..c7d3f35d40 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -3002,7 +3002,7 @@ test "renameat" { }, cqe); // Validate that the old file doesn't exist anymore - try testing.expectError(error.FileNotFound, tmp.dir.openFile(old_path, .{})); + try testing.expectError(error.FileNotFound, tmp.dir.openFile(io, old_path, .{})); // Validate that the new file exists with the proper content var new_file_data: [16]u8 = undefined; @@ -3057,7 +3057,7 @@ test "unlinkat" { }, cqe); // Validate that the file doesn't exist anymore - _ = tmp.dir.openFile(path, .{}) catch |err| switch (err) { + _ = tmp.dir.openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => {}, else => std.debug.panic("unexpected error: {}", .{err}), }; @@ -3154,7 +3154,7 @@ test "symlinkat" { }, cqe); // Validate that the symlink exist - _ = try tmp.dir.openFile(link_path, .{}); + _ = try tmp.dir.openFile(io, link_path, .{}); } test "linkat" { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 82fa2c41d1..19313e3ff7 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -164,10 +164,10 @@ test "linkat with different directories" { // Test 1: link from file in subdir back up to target in parent directory try posix.linkat(tmp.dir.fd, target_name, subdir.fd, link_name, 0); - const efd = try tmp.dir.openFile(target_name, .{}); + const efd = try tmp.dir.openFile(io, target_name, .{}); defer efd.close(io); - const nfd = try subdir.openFile(link_name, .{}); + const nfd = try subdir.openFile(io, link_name, .{}); defer nfd.close(io); { @@ -429,7 +429,7 @@ test "mmap" { // Map the whole file { - const file = try tmp.dir.openFile(test_out_file, .{}); + const file = try tmp.dir.openFile(io, test_out_file, .{}); defer file.close(io); const data = try posix.mmap( @@ -454,7 +454,7 @@ test "mmap" { // Map the upper half of the file { - const file = try tmp.dir.openFile(test_out_file, .{}); + const file = try tmp.dir.openFile(io, test_out_file, .{}); defer file.close(io); const data = try posix.mmap( diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 4f0c11797d..cc74da956a 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -817,7 +817,7 @@ fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion { // .dynstr section, and finding the max version number of symbols // that start with "GLIBC_2.". const glibc_so_basename = "libc.so.6"; - var file = dir.openFile(glibc_so_basename, .{}) catch |err| switch (err) { + var file = dir.openFile(io, glibc_so_basename, .{}) catch |err| switch (err) { error.NameTooLong => return error.Unexpected, error.BadPathName => return error.Unexpected, error.PipeBusy => return error.Unexpected, // Windows-only @@ -851,7 +851,7 @@ fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion { // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system. var buffer: [8000]u8 = undefined; - var file_reader: Io.File.Reader = .initAdapted(file, io, &buffer); + var file_reader: Io.File.Reader = .init(file, io, &buffer); return glibcVerFromSoFile(&file_reader) catch |err| switch (err) { error.InvalidElfMagic, @@ -1053,7 +1053,7 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ var is_elf_file = false; defer if (!is_elf_file) file.close(io); - file_reader = .initAdapted(file, io, &file_reader_buffer); + file_reader = .init(file, io, &file_reader_buffer); file_name = undefined; // it aliases file_reader_buffer const header = elf.Header.read(&file_reader.interface) catch |hdr_err| switch (hdr_err) { diff --git a/src/Compilation.zig b/src/Compilation.zig index d75cba5a11..24b994f608 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1104,7 +1104,7 @@ pub const CObject = struct { const source_line = source_line: { if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; - const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; + const file = fs.cwd().openFile(io, file_name, .{}) catch break :source_line 0; defer file.close(io); var buffer: [1024]u8 = undefined; var file_reader = file.reader(io, &buffer); @@ -1179,7 +1179,7 @@ pub const CObject = struct { }; var buffer: [1024]u8 = undefined; - const file = try fs.cwd().openFile(path, .{}); + const file = try fs.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.reader(io, &buffer); var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); @@ -5354,14 +5354,14 @@ fn docsCopyModule( }, else => continue, } - var file = mod_dir.openFile(entry.path, .{}) catch |err| { + var file = mod_dir.openFile(io, entry.path, .{}) catch |err| { return comp.lockAndSetMiscFailure(.docs_copy, "unable to open {f}{s}: {t}", .{ root.fmt(comp), entry.path, err, }); }; defer file.close(io); const stat = try file.stat(); - var file_reader: Io.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); + var file_reader: Io.File.Reader = .initSize(file, io, &buffer, stat.size); archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| { return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive {f}{s}: {t}", .{ diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 988282097b..3bd05120ff 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -390,7 +390,7 @@ pub fn run(f: *Fetch) RunError!void { var server_header_buffer: [init_resource_buffer_size]u8 = undefined; const file_err = if (dir_err == error.NotDir) e: { - if (fs.cwd().openFile(path_or_url, .{})) |file| { + if (fs.cwd().openFile(io, path_or_url, .{})) |file| { var resource: Resource = .{ .file = file.reader(io, &server_header_buffer) }; return f.runResource(path_or_url, &resource, null); } else |err| break :e err; @@ -995,7 +995,7 @@ fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u if (ascii.eqlIgnoreCase(uri.scheme, "file")) { const path = try uri.path.toRawMaybeAlloc(arena); - const file = f.parent_package_root.openFile(path, .{}) catch |err| { + const file = f.parent_package_root.openFile(io, path, .{}) catch |err| { return f.fail(f.location_tok, try eb.printString("unable to open '{f}{s}': {t}", .{ f.parent_package_root, path, err, })); @@ -1677,7 +1677,7 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er switch (hashed_file.kind) { .file => { - var file = try dir.openFile(hashed_file.fs_path, .{}); + var file = try dir.openFile(io, hashed_file.fs_path, .{}); defer file.close(io); // Hard-coded false executable bit: https://github.com/ziglang/zig/issues/17463 hasher.update(&.{ 0, 0 }); diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index abaa8fef73..ccae9440e2 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -1714,7 +1714,7 @@ pub fn main() !void { const format = std.meta.stringToEnum(Oid.Format, args[1]) orelse return error.InvalidFormat; - var pack_file = try std.fs.cwd().openFile(args[2], .{}); + var pack_file = try std.fs.cwd().openFile(io, args[2], .{}); defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = pack_file.reader(io, &pack_file_buffer); diff --git a/src/Zcu.zig b/src/Zcu.zig index cd4a8c7783..d2634a8962 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1076,7 +1076,7 @@ pub const File = struct { var f = f: { const dir, const sub_path = file.path.openInfo(zcu.comp.dirs); - break :f try dir.openFile(sub_path, .{}); + break :f try dir.openFile(io, sub_path, .{}); }; defer f.close(io); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 55d6a3861f..45b1302138 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -94,7 +94,7 @@ pub fn updateFile( // In any case we need to examine the stat of the file to determine the course of action. var source_file = f: { const dir, const sub_path = file.path.openInfo(comp.dirs); - break :f try dir.openFile(sub_path, .{}); + break :f try dir.openFile(io, sub_path, .{}); }; defer source_file.close(io); @@ -2466,7 +2466,7 @@ fn updateEmbedFileInner( var file = f: { const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs); - break :f try dir.openFile(sub_path, .{}); + break :f try dir.openFile(io, sub_path, .{}); }; defer file.close(io); diff --git a/src/fmt.zig b/src/fmt.zig index 663d09e9cb..ce8a31fa4c 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -262,7 +262,7 @@ fn fmtPathFile( ) !void { const io = fmt.io; - const source_file = try dir.openFile(sub_path, .{}); + const source_file = try dir.openFile(io, sub_path, .{}); var file_closed = false; errdefer if (!file_closed) source_file.close(io); diff --git a/src/introspect.zig b/src/introspect.zig index 9b6797e7d8..d2faa9a55c 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -22,7 +22,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { // Try lib/zig/std/std.zig const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir; - const file = test_zig_dir.openFile(test_index_file, .{}) catch { + const file = test_zig_dir.openFile(io, test_index_file, .{}) catch { test_zig_dir.close(io); break :zig_dir; }; @@ -32,7 +32,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { // Try lib/std/std.zig var test_zig_dir = base_dir.openDir("lib", .{}) catch return null; - const file = test_zig_dir.openFile(test_index_file, .{}) catch { + const file = test_zig_dir.openFile(io, test_index_file, .{}) catch { test_zig_dir.close(io); return null; }; diff --git a/src/link.zig b/src/link.zig index d5daf6fca7..073ec632c6 100644 --- a/src/link.zig +++ b/src/link.zig @@ -637,7 +637,7 @@ pub const File = struct { } } } - base.file = try emit.root_dir.handle.openFile(emit.sub_path, .{ .mode = .read_write }); + base.file = try emit.root_dir.handle.openFile(io, emit.sub_path, .{ .mode = .read_write }); }, .elf2, .coff2 => if (base.file == null) { const mf = if (base.cast(.elf2)) |elf| @@ -646,10 +646,10 @@ pub const File = struct { &coff.mf else unreachable; - mf.file = try base.emit.root_dir.handle.adaptToNewApi().openFile(io, base.emit.sub_path, .{ + mf.file = try base.emit.root_dir.handle.openFile(io, base.emit.sub_path, .{ .mode = .read_write, }); - base.file = .adaptFromNewApi(mf.file); + base.file = mf.file; try mf.ensureTotalCapacity(@intCast(mf.nodes.items[0].location().resolve(mf)[1])); }, .c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }), @@ -2007,7 +2007,7 @@ fn resolveLibInput( .sub_path = try std.fmt.allocPrint(arena, "lib{s}.tbd", .{lib_name}), }; try checked_paths.print(gpa, "\n {f}", .{test_path}); - var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { + var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => break :tbd, else => |e| fatal("unable to search for tbd library '{f}': {s}", .{ test_path, @errorName(e) }), }; @@ -2043,7 +2043,7 @@ fn resolveLibInput( .sub_path = try std.fmt.allocPrint(arena, "lib{s}.so", .{lib_name}), }; try checked_paths.print(gpa, "\n {f}", .{test_path}); - var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { + var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => break :so, else => |e| fatal("unable to search for so library '{f}': {s}", .{ test_path, @errorName(e), @@ -2061,7 +2061,7 @@ fn resolveLibInput( .sub_path = try std.fmt.allocPrint(arena, "lib{s}.a", .{lib_name}), }; try checked_paths.print(gpa, "\n {f}", .{test_path}); - var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { + var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => break :mingw, else => |e| fatal("unable to search for static library '{f}': {s}", .{ test_path, @errorName(e) }), }; @@ -2115,7 +2115,7 @@ fn resolvePathInput( .static_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .static, color), .shared_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color), .object => { - var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| + var file = pq.path.root_dir.handle.openFile(io, pq.path.sub_path, .{}) catch |err| fatal("failed to open object {f}: {s}", .{ pq.path, @errorName(err) }); errdefer file.close(io); try resolved_inputs.append(gpa, .{ .object = .{ @@ -2127,7 +2127,7 @@ fn resolvePathInput( return null; }, .res => { - var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| + var file = pq.path.root_dir.handle.openFile(io, pq.path.sub_path, .{}) catch |err| fatal("failed to open windows resource {f}: {s}", .{ pq.path, @errorName(err) }); errdefer file.close(io); try resolved_inputs.append(gpa, .{ .res = .{ @@ -2164,7 +2164,7 @@ fn resolvePathInputLib( .static_library, .shared_library => true, else => false, }) { - var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { + var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => return .no_match, else => |e| fatal("unable to search for {s} library '{f}': {s}", .{ @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e), @@ -2242,7 +2242,7 @@ fn resolvePathInputLib( return .ok; } - var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { + var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => return .no_match, else => |e| fatal("unable to search for {s} library {f}: {s}", .{ @tagName(link_mode), test_path, @errorName(e), @@ -2253,7 +2253,7 @@ fn resolvePathInputLib( } pub fn openObject(io: Io, path: Path, must_link: bool, hidden: bool) !Input.Object { - var file = try path.root_dir.handle.openFile(path.sub_path, .{}); + var file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); errdefer file.close(io); return .{ .path = path, @@ -2264,7 +2264,7 @@ pub fn openObject(io: Io, path: Path, must_link: bool, hidden: bool) !Input.Obje } pub fn openDso(io: Io, path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso { - var file = try path.root_dir.handle.openFile(path.sub_path, .{}); + var file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); errdefer file.close(io); return .{ .path = path, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index f33e0ccdea..e1d52fb7c4 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -632,7 +632,7 @@ fn create( }; const coff = try arena.create(Coff); - const file = try path.root_dir.handle.adaptToNewApi().createFile(comp.io, path.sub_path, .{ + const file = try path.root_dir.handle.createFile(comp.io, path.sub_path, .{ .read = true, .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), }); @@ -644,7 +644,7 @@ fn create( .comp = comp, .emit = path, - .file = .adaptFromNewApi(file), + .file = file, .gc_sections = false, .print_gc_sections = false, .build_id = .none, diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index e35444bc02..72fdb244a4 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -928,6 +928,7 @@ fn create( path: std.Build.Cache.Path, options: link.File.OpenOptions, ) !*Elf { + const io = comp.io; const target = &comp.root_mod.resolved_target.result; assert(target.ofmt == .elf); const class: std.elf.CLASS = switch (target.ptrBitWidth()) { @@ -973,11 +974,11 @@ fn create( }; const elf = try arena.create(Elf); - const file = try path.root_dir.handle.adaptToNewApi().createFile(comp.io, path.sub_path, .{ + const file = try path.root_dir.handle.createFile(io, path.sub_path, .{ .read = true, .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), }); - errdefer file.close(comp.io); + errdefer file.close(io); elf.* = .{ .base = .{ .tag = .elf2, @@ -985,7 +986,7 @@ fn create( .comp = comp, .emit = path, - .file = .adaptFromNewApi(file), + .file = file, .gc_sections = false, .print_gc_sections = false, .build_id = .none, @@ -3325,12 +3326,13 @@ fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void { const file_loc = isi.fileLocation(elf); if (file_loc.size == 0) return; const comp = elf.base.comp; + const io = comp.io; const gpa = comp.gpa; const ii = isi.input(elf); const path = ii.path(elf); - const file = try path.root_dir.handle.adaptToNewApi().openFile(comp.io, path.sub_path, .{}); - defer file.close(comp.io); - var fr = file.reader(comp.io, &.{}); + const file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); + defer file.close(io); + var fr = file.reader(io, &.{}); try fr.seekTo(file_loc.offset); var nw: MappedFile.Node.Writer = undefined; const si = isi.symbol(elf); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 93adc633ce..e837cc853a 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1126,7 +1126,9 @@ fn parseDependentDylibs(self: *MachO) !void { if (self.dylibs.items.len == 0) return; - const gpa = self.base.comp.gpa; + const comp = self.base.comp; + const gpa = comp.gpa; + const io = comp.io; const framework_dirs = self.framework_dirs; // TODO delete this, directories must instead be resolved by the frontend @@ -1183,7 +1185,7 @@ fn parseDependentDylibs(self: *MachO) !void { const path = if (existing_ext.len > 0) id.name[0 .. id.name.len - existing_ext.len] else id.name; for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { test_path.clearRetainingCapacity(); - if (self.base.comp.sysroot) |root| { + if (comp.sysroot) |root| { try test_path.print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext }); } else { try test_path.print("{s}{s}", .{ path, ext }); @@ -1235,7 +1237,7 @@ fn parseDependentDylibs(self: *MachO) !void { .path = Path.initCwd(full_path), .weak = is_weak, }; - const file = try lib.path.root_dir.handle.openFile(lib.path.sub_path, .{}); + const file = try lib.path.root_dir.handle.openFile(io, lib.path.sub_path, .{}); const fh = try self.addFileHandle(file); const fat_arch = try self.parseFatFile(file, lib.path); const offset = if (fat_arch) |fa| fa.offset else 0; diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index d2a6c2a3ab..0f42442640 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -1,6 +1,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { - const gpa = macho_file.base.comp.gpa; - const diags = &macho_file.base.comp.link_diags; + const gpa = comp.gpa; + const io = comp.io; + const diags = &comp.link_diags; // TODO: "positional arguments" is a CLI concept, not a linker concept. Delete this unnecessary array list. var positionals = std.array_list.Managed(link.Input).init(gpa); @@ -19,7 +20,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat // debug info segments/sections (this is apparently by design by Apple), we copy // the *only* input file over. const path = positionals.items[0].path().?; - const in_file = path.root_dir.handle.openFile(path.sub_path, .{}) catch |err| + const in_file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err| return diags.fail("failed to open {f}: {s}", .{ path, @errorName(err) }); const stat = in_file.stat() catch |err| return diags.fail("failed to stat {f}: {s}", .{ path, @errorName(err) }); diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 7d4134ccaf..a61c6e764c 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -630,7 +630,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested // Resize the entire file if (ni == Node.Index.root) { try mf.ensureCapacityForSetLocation(gpa); - try Io.File.adaptFromNewApi(mf.file).setEndPos(new_size); + try mf.file.setEndPos(new_size); try mf.ensureTotalCapacity(@intCast(new_size)); ni.setLocationAssumeCapacity(mf, old_offset, new_size); return; diff --git a/src/main.zig b/src/main.zig index 3ca64881f8..b040b6c8ef 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4681,7 +4681,7 @@ fn cmdTranslateC( } else { const hex_digest = Cache.binToHex(result.digest); const out_zig_path = try fs.path.join(arena, &.{ "o", &hex_digest, translated_basename }); - const zig_file = comp.dirs.local_cache.handle.openFile(out_zig_path, .{}) catch |err| { + const zig_file = comp.dirs.local_cache.handle.openFile(io, out_zig_path, .{}) catch |err| { const path = comp.dirs.local_cache.path orelse "."; fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, @@ -6187,7 +6187,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { const display_path = zig_source_path orelse ""; const source: [:0]const u8 = s: { var f = if (zig_source_path) |p| file: { - break :file fs.cwd().openFile(p, .{}) catch |err| { + break :file fs.cwd().openFile(io, p, .{}) catch |err| { fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); }; } else Io.File.stdin(); @@ -6494,7 +6494,7 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { const cache_file = args[0]; - var f = fs.cwd().openFile(cache_file, .{}) catch |err| { + var f = fs.cwd().openFile(io, cache_file, .{}) catch |err| { fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) }); }; defer f.close(io); @@ -6541,7 +6541,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { const new_source_path = args[1]; const old_source = source: { - var f = fs.cwd().openFile(old_source_path, .{}) catch |err| + var f = fs.cwd().openFile(io, old_source_path, .{}) catch |err| fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); @@ -6549,7 +6549,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); }; const new_source = source: { - var f = fs.cwd().openFile(new_source_path, .{}) catch |err| + var f = fs.cwd().openFile(io, new_source_path, .{}) catch |err| fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); -- cgit v1.2.3 From f53248a40936ebc9aaf75ddbd16e67ebec05ab84 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 13:39:09 -0800 Subject: update all std.fs.cwd() to std.Io.Dir.cwd() --- lib/compiler/aro/aro/Compilation.zig | 8 +- lib/compiler/aro/aro/Driver.zig | 10 +-- lib/compiler/aro/aro/Parser.zig | 27 +++---- lib/compiler/aro/aro/Preprocessor.zig | 6 +- lib/compiler/aro/aro/Tokenizer.zig | 5 +- lib/compiler/aro/aro/Value.zig | 11 +-- lib/compiler/aro/main.zig | 2 +- lib/compiler/objcopy.zig | 4 +- lib/compiler/reduce.zig | 6 +- lib/compiler/resinator/cli.zig | 2 +- lib/compiler/resinator/compile.zig | 4 +- lib/compiler/resinator/main.zig | 22 +++--- lib/compiler/std-docs.zig | 2 +- lib/compiler/translate-c/main.zig | 8 +- lib/std/Build.zig | 10 +-- lib/std/Build/Cache.zig | 8 +- lib/std/Build/Step.zig | 17 ++-- lib/std/Build/Step/CheckFile.zig | 4 +- lib/std/Build/Step/ConfigHeader.zig | 8 +- lib/std/Build/Step/Options.zig | 15 ++-- lib/std/Build/Step/Run.zig | 2 +- lib/std/Build/Watch.zig | 16 ++-- lib/std/Io/File.zig | 8 ++ lib/std/Io/Threaded.zig | 9 +-- lib/std/Io/Writer.zig | 6 +- lib/std/Io/net/test.zig | 2 +- lib/std/Io/test.zig | 10 +-- lib/std/Thread.zig | 4 +- lib/std/crypto/Certificate/Bundle/macos.zig | 2 +- lib/std/crypto/codecs/asn1/test.zig | 4 +- lib/std/debug.zig | 20 ++--- lib/std/debug/ElfFile.zig | 2 +- lib/std/debug/MachOFile.zig | 2 +- lib/std/debug/SelfInfo/Elf.zig | 19 +++-- lib/std/debug/SelfInfo/MachO.zig | 2 +- lib/std/debug/SelfInfo/Windows.zig | 4 +- lib/std/dynamic_library.zig | 8 +- lib/std/fs/test.zig | 116 +++++++++++++--------------- lib/std/os/linux/IoUring.zig | 24 +++--- lib/std/os/linux/test.zig | 6 +- lib/std/os/windows.zig | 4 +- lib/std/posix.zig | 14 ++-- lib/std/posix/test.zig | 52 ++++++------- lib/std/process/Child.zig | 2 +- lib/std/std.zig | 2 +- lib/std/tar.zig | 14 ++-- lib/std/testing.zig | 2 +- lib/std/zig/LibCInstallation.zig | 12 +-- lib/std/zig/WindowsSdk.zig | 2 +- lib/std/zig/system.zig | 6 +- lib/std/zig/system/darwin/macos.zig | 7 +- lib/std/zip.zig | 4 +- src/Compilation.zig | 20 ++--- src/Package/Fetch.zig | 12 +-- src/Package/Fetch/git.zig | 12 +-- src/Zcu/PerThread.zig | 4 +- src/codegen/llvm.zig | 17 ++-- src/fmt.zig | 6 +- src/introspect.zig | 4 +- src/libs/freebsd.zig | 12 +-- src/libs/glibc.zig | 16 ++-- src/libs/mingw.zig | 17 ++-- src/libs/netbsd.zig | 12 +-- src/link/C.zig | 4 +- src/link/Coff.zig | 6 +- src/link/Elf.zig | 4 +- src/link/Lld.zig | 4 +- src/link/MachO.zig | 14 ++-- src/link/MachO/CodeSignature.zig | 2 +- src/link/SpirV.zig | 3 +- src/link/Wasm.zig | 4 +- src/main.zig | 36 ++++----- 72 files changed, 398 insertions(+), 377 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index 09e4861d13..b3e4d5544d 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -2253,7 +2253,7 @@ test "addSourceFromBuffer" { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("path", str); @@ -2267,7 +2267,7 @@ test "addSourceFromBuffer" { var arena: std.heap.ArenaAllocator = .init(allocator); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n"); @@ -2313,7 +2313,7 @@ test "addSourceFromBuffer - exhaustive check for carriage return elimination" { var buf: [alphabet.len]u8 = @splat(alphabet[0]); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var source_count: u32 = 0; @@ -2341,7 +2341,7 @@ test "ignore BOM at beginning of file" { const Test = struct { fn run(arena: Allocator, buf: []const u8) !void { var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("file.c", buf); diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index f933e3ce52..fec3cea0f8 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -1327,7 +1327,7 @@ fn processSource( const dep_file_name = try d.getDepFileName(source, writer_buf[0..std.fs.max_name_bytes]); const file = if (dep_file_name) |path| - d.comp.cwd.createFile(path, .{}) catch |er| + d.comp.cwd.createFile(io, path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) }) else Io.File.stdout(); @@ -1352,7 +1352,7 @@ fn processSource( } const file = if (d.output_name) |some| - d.comp.cwd.createFile(some, .{}) catch |er| + d.comp.cwd.createFile(io, some, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) else Io.File.stdout(); @@ -1405,7 +1405,7 @@ fn processSource( defer assembly.deinit(gpa); if (d.only_preprocess_and_compile) { - const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(io); @@ -1419,7 +1419,7 @@ fn processSource( // then assemble to out_file_name var assembly_name_buf: [std.fs.max_name_bytes]u8 = undefined; const assembly_out_file_name = try d.getRandomFilename(&assembly_name_buf, ".s"); - const out_file = d.comp.cwd.createFile(assembly_out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, assembly_out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); defer out_file.close(io); assembly.writeToFile(out_file) catch |er| @@ -1455,7 +1455,7 @@ fn processSource( }; defer obj.deinit(); - const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(io); diff --git a/lib/compiler/aro/aro/Parser.zig b/lib/compiler/aro/aro/Parser.zig index 4a89e0d460..fc21ee4d0b 100644 --- a/lib/compiler/aro/aro/Parser.zig +++ b/lib/compiler/aro/aro/Parser.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Allocator = mem.Allocator; const assert = std.debug.assert; @@ -211,7 +212,7 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca const prev_total = p.diagnostics.total; var sf = std.heap.stackFallback(1024, p.comp.gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); if (!char_info.isC99IdChar(codepoint)) { @@ -425,7 +426,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) if (p.diagnostics.effectiveKind(diagnostic) == .off) return; var sf = std.heap.stackFallback(1024, p.comp.gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); p.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory; @@ -447,7 +448,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) }, p.pp.expansionSlice(tok_i), true); } -fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !void { +fn formatArgs(p: *Parser, w: *Io.Writer, fmt: []const u8, args: anytype) !void { var i: usize = 0; inline for (std.meta.fields(@TypeOf(args))) |arg_info| { const arg = @field(args, arg_info.name); @@ -476,13 +477,13 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo try w.writeAll(fmt[i..]); } -fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize { +fn formatTokenId(w: *Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize { const i = Diagnostics.templateIndex(w, fmt, "{tok_id}"); try w.writeAll(tok_id.symbol()); return i; } -fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize { +fn formatQualType(p: *Parser, w: *Io.Writer, fmt: []const u8, qt: QualType) !usize { const i = Diagnostics.templateIndex(w, fmt, "{qt}"); try w.writeByte('\''); try qt.print(p.comp, w); @@ -501,7 +502,7 @@ fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) return i; } -fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize { +fn formatResult(p: *Parser, w: *Io.Writer, fmt: []const u8, res: Result) !usize { const i = Diagnostics.templateIndex(w, fmt, "{value}"); switch (res.val.opt_ref) { .none => try w.writeAll("(none)"), @@ -524,7 +525,7 @@ const Normalized = struct { return .{ .str = str }; } - pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Normalized, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{normalized}"); var it: std.unicode.Utf8Iterator = .{ .bytes = ctx.str, @@ -558,7 +559,7 @@ const Codepoint = struct { return .{ .codepoint = codepoint }; } - pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Codepoint, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{codepoint}"); try w.print("{X:0>4}", .{ctx.codepoint}); return i; @@ -572,7 +573,7 @@ const Escaped = struct { return .{ .str = str }; } - pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Escaped, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{s}"); try std.zig.stringEscape(ctx.str, w); return i; @@ -1453,7 +1454,7 @@ fn decl(p: *Parser) Error!bool { return true; } -fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *std.Io.Writer.Allocating) !?[]const u8 { +fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *Io.Writer.Allocating) !?[]const u8 { const w = &allocating.writer; const cond = cond_node.get(&p.tree); @@ -1526,7 +1527,7 @@ fn staticAssert(p: *Parser) Error!bool { } else { if (!res.val.toBool(p.comp)) { var sf = std.heap.stackFallback(1024, gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); if (p.staticAssertMessage(res_node, str, &allocating) catch return error.OutOfMemory) |message| { @@ -9719,7 +9720,7 @@ fn primaryExpr(p: *Parser) Error!?Result { qt = some.qt; } else if (p.func.qt) |func_qt| { var sf = std.heap.stackFallback(1024, gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory; @@ -10608,7 +10609,7 @@ test "Node locations" { const arena = arena_state.allocator(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const file = try comp.addSourceFromBuffer("file.c", diff --git a/lib/compiler/aro/aro/Preprocessor.zig b/lib/compiler/aro/aro/Preprocessor.zig index d47727cbf0..e8343dc83a 100644 --- a/lib/compiler/aro/aro/Preprocessor.zig +++ b/lib/compiler/aro/aro/Preprocessor.zig @@ -3900,7 +3900,7 @@ test "Preserve pragma tokens sometimes" { defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); try comp.addDefaultPragmaHandlers(); @@ -3967,7 +3967,7 @@ test "destringify" { var arena: std.heap.ArenaAllocator = .init(gpa); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var pp = Preprocessor.init(&comp, .default); defer pp.deinit(); @@ -4030,7 +4030,7 @@ test "Include guards" { const arena = arena_state.allocator(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var pp = Preprocessor.init(&comp, .default); defer pp.deinit(); diff --git a/lib/compiler/aro/aro/Tokenizer.zig b/lib/compiler/aro/aro/Tokenizer.zig index c497c5ce82..198d49364a 100644 --- a/lib/compiler/aro/aro/Tokenizer.zig +++ b/lib/compiler/aro/aro/Tokenizer.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const Compilation = @import("Compilation.zig"); @@ -2326,7 +2327,7 @@ test "Tokenizer fuzz test" { fn testOne(_: @This(), input_bytes: []const u8) anyerror!void { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("fuzz.c", input_bytes); @@ -2351,7 +2352,7 @@ test "Tokenizer fuzz test" { fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, langopts: ?LangOpts) !void { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); if (langopts) |provided| { comp.langopts = provided; diff --git a/lib/compiler/aro/aro/Value.zig b/lib/compiler/aro/aro/Value.zig index 25a2d1824f..14949ce03b 100644 --- a/lib/compiler/aro/aro/Value.zig +++ b/lib/compiler/aro/aro/Value.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; @@ -80,7 +81,7 @@ test "minUnsignedBits" { defer arena_state.deinit(); const arena = arena_state.allocator(); - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); comp.target = .fromZigTarget(try std.zig.system.resolveTargetQuery(std.testing.io, target_query)); @@ -119,7 +120,7 @@ test "minSignedBits" { defer arena_state.deinit(); const arena = arena_state.allocator(); - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); comp.target = .fromZigTarget(try std.zig.system.resolveTargetQuery(std.testing.io, target_query)); @@ -1080,7 +1081,7 @@ const NestedPrint = union(enum) { }, }; -pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!void { +pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!void { try w.writeByte('&'); try w.writeAll(base); if (!offset.isZero(comp)) { @@ -1089,7 +1090,7 @@ pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w } } -pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!?NestedPrint { +pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!?NestedPrint { if (qt.is(comp, .bool)) { try w.writeAll(if (v.isZero(comp)) "false" else "true"); return null; @@ -1116,7 +1117,7 @@ pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *std.Io.Writer return null; } -pub fn printString(bytes: []const u8, qt: QualType, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!void { +pub fn printString(bytes: []const u8, qt: QualType, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!void { const size: Compilation.CharUnitSize = @enumFromInt(qt.childType(comp).sizeof(comp)); const without_null = bytes[0 .. bytes.len - @intFromEnum(size)]; try w.writeByte('"'); diff --git a/lib/compiler/aro/main.zig b/lib/compiler/aro/main.zig index 66c8add4a3..d1be1dbb21 100644 --- a/lib/compiler/aro/main.zig +++ b/lib/compiler/aro/main.zig @@ -59,7 +59,7 @@ pub fn main() u8 { } }, }; - var comp = Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |er| switch (er) { + var comp = Compilation.initDefault(gpa, arena, io, &diagnostics, Io.Dir.cwd()) catch |er| switch (er) { error.OutOfMemory => { std.debug.print("out of memory\n", .{}); if (fast_exit) process.exit(1); diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index 485e644daa..e48f76a6a6 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -152,7 +152,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void defer threaded.deinit(); const io = threaded.io(); - const input_file = fs.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); + const input_file = Io.Dir.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); defer input_file.close(io); const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); @@ -180,7 +180,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void const mode = if (out_fmt != .elf or only_keep_debug) Io.File.default_mode else stat.mode; - var output_file = try fs.cwd().createFile(output, .{ .mode = mode }); + var output_file = try Io.Dir.cwd().createFile(io, output, .{ .mode = mode }); defer output_file.close(io); var out = output_file.writer(&output_buffer); diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index bbd3d172b4..d3f33ad81a 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -233,7 +233,7 @@ pub fn main() !void { } } - try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); // std.debug.print("trying this code:\n{s}\n", .{rendered.items}); const interestingness = try runCheck(arena, interestingness_argv.items); @@ -274,7 +274,7 @@ pub fn main() !void { fixups.clearRetainingCapacity(); rendered.clearRetainingCapacity(); try tree.render(gpa, &rendered.writer, fixups); - try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); return std.process.cleanExit(); } @@ -398,7 +398,7 @@ fn transformationsToFixups( } fn parse(gpa: Allocator, file_path: []const u8) !Ast { - const source_code = std.fs.cwd().readFileAllocOptions( + const source_code = Io.Dir.cwd().readFileAllocOptions( file_path, gpa, .limited(std.math.maxInt(u32)), diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index bb54289e3e..ae4ece2968 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -2003,7 +2003,7 @@ test "maybeAppendRC" { // Create the file so that it's found. In this scenario, .rc should not get // appended. - var file = try tmp.dir.createFile("foo", .{}); + var file = try tmp.dir.createFile(io, "foo", .{}); file.close(io); try options.maybeAppendRC(tmp.dir); try std.testing.expectEqualStrings("foo", options.input_source.filename); diff --git a/lib/compiler/resinator/compile.zig b/lib/compiler/resinator/compile.zig index 7dc77e5ee1..3e046a10c1 100644 --- a/lib/compiler/resinator/compile.zig +++ b/lib/compiler/resinator/compile.zig @@ -111,7 +111,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) }); } } - // Re-open the passed in cwd since we want to be able to close it (std.fs.cwd() shouldn't be closed) + // Re-open the passed in cwd since we want to be able to close it (Io.Dir.cwd() shouldn't be closed) const cwd_dir = options.cwd.openDir(".", .{}) catch |err| { try options.diagnostics.append(.{ .err = .failed_to_open_cwd, @@ -406,7 +406,7 @@ pub const Compiler = struct { // `/test.bin` relative to include paths and instead only treats it as // an absolute path. if (std.fs.path.isAbsolute(path)) { - const file = try utils.openFileNotDir(std.fs.cwd(), path, .{}); + const file = try utils.openFileNotDir(Io.Dir.cwd(), path, .{}); errdefer file.close(io); if (self.dependencies) |dependencies| { diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index c726a06cf4..416abc2ab7 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -67,7 +67,7 @@ pub fn main() !void { }, else => |e| return e, }; - try options.maybeAppendRC(std.fs.cwd()); + try options.maybeAppendRC(Io.Dir.cwd()); if (!zig_integration) { // print any warnings/notes @@ -141,7 +141,7 @@ pub fn main() !void { if (!zig_integration) std.debug.unlockStderrWriter(); } - var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd()); + var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var argv: std.ArrayList([]const u8) = .empty; @@ -196,7 +196,7 @@ pub fn main() !void { }; }, .filename => |input_filename| { - break :full_input std.fs.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { + break :full_input Io.Dir.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { try error_handler.emitMessage(gpa, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); std.process.exit(1); }; @@ -212,7 +212,7 @@ pub fn main() !void { try output_file.writeAll(full_input); }, .filename => |output_filename| { - try std.fs.cwd().writeFile(.{ .sub_path = output_filename, .data = full_input }); + try Io.Dir.cwd().writeFile(.{ .sub_path = output_filename, .data = full_input }); }, } return; @@ -277,7 +277,7 @@ pub fn main() !void { const output_buffered_stream = res_stream_writer.interface(); compile(gpa, io, final_input, output_buffered_stream, .{ - .cwd = std.fs.cwd(), + .cwd = Io.Dir.cwd(), .diagnostics = &diagnostics, .source_mappings = &mapping_results.mappings, .dependencies = maybe_dependencies, @@ -294,7 +294,7 @@ pub fn main() !void { .warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page, }) catch |err| switch (err) { error.ParseError, error.CompileError => { - try error_handler.emitDiagnostics(gpa, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings); + try error_handler.emitDiagnostics(gpa, Io.Dir.cwd(), final_input, &diagnostics, mapping_results.mappings); // Delete the output file on error res_stream.cleanupAfterError(io); std.process.exit(1); @@ -306,12 +306,12 @@ pub fn main() !void { // print any warnings/notes if (!zig_integration) { - diagnostics.renderToStdErr(std.fs.cwd(), final_input, mapping_results.mappings); + diagnostics.renderToStdErr(Io.Dir.cwd(), final_input, mapping_results.mappings); } // write the depfile if (options.depfile_path) |depfile_path| { - var depfile = std.fs.cwd().createFile(depfile_path, .{}) catch |err| { + var depfile = Io.Dir.cwd().createFile(io, depfile_path, .{}) catch |err| { try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); std.process.exit(1); }; @@ -440,7 +440,7 @@ const IoStream = struct { // Delete the output file on error file.close(io); // Failing to delete is not really a big deal, so swallow any errors - std.fs.cwd().deleteFile(self.name) catch {}; + Io.Dir.cwd().deleteFile(self.name) catch {}; }, .stdio, .memory, .closed => return, } @@ -457,8 +457,8 @@ const IoStream = struct { switch (source) { .filename => |filename| return .{ .file = switch (io) { - .input => try openFileNotDir(std.fs.cwd(), filename, .{}), - .output => try std.fs.cwd().createFile(filename, .{}), + .input => try openFileNotDir(Io.Dir.cwd(), filename, .{}), + .output => try Io.Dir.cwd().createFile(io, filename, .{}), }, }, .stdio => |file| return .{ .stdio = file }, diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index e4efac28cd..87c4da9faa 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -40,7 +40,7 @@ pub fn main() !void { const zig_exe_path = argv.next().?; const global_cache_path = argv.next().?; - var lib_dir = try std.fs.cwd().openDir(zig_lib_directory, .{}); + var lib_dir = try Io.Dir.cwd().openDir(zig_lib_directory, .{}); defer lib_dir.close(io); var listen_port: u16 = 0; diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index 830c70e424..d0a873fd78 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -47,7 +47,7 @@ pub fn main() u8 { }; defer diagnostics.deinit(); - var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |err| switch (err) { + var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, Io.Dir.cwd()) catch |err| switch (err) { error.OutOfMemory => { std.debug.print("ran out of memory initializing C compilation\n", .{}); if (fast_exit) process.exit(1); @@ -226,7 +226,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration const dep_file_name = try d.getDepFileName(source, out_buf[0..std.fs.max_name_bytes]); const file = if (dep_file_name) |path| - d.comp.cwd.createFile(path, .{}) catch |er| + d.comp.cwd.createFile(io, path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) }) else Io.File.stdout(); @@ -253,10 +253,10 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration if (d.output_name) |path| blk: { if (std.mem.eql(u8, path, "-")) break :blk; if (std.fs.path.dirname(path)) |dirname| { - std.fs.cwd().makePath(dirname) catch |err| + Io.Dir.cwd().makePath(dirname) catch |err| return d.fatal("failed to create path to '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); } - out_file = std.fs.cwd().createFile(path, .{}) catch |err| { + out_file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| { return d.fatal("failed to create output file '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); }; close_out_file = true; diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 7bfdbb6449..cc2f70fd2f 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1702,13 +1702,13 @@ pub fn addCheckFile( pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void { const io = b.graph.io; if (b.verbose) log.info("truncate {s}", .{dest_path}); - const cwd = fs.cwd(); - var src_file = cwd.createFile(dest_path, .{}) catch |err| switch (err) { + const cwd = Io.Dir.cwd(); + var src_file = cwd.createFile(io, dest_path, .{}) catch |err| switch (err) { error.FileNotFound => blk: { if (fs.path.dirname(dest_path)) |dirname| { try cwd.makePath(dirname); } - break :blk try cwd.createFile(dest_path, .{}); + break :blk try cwd.createFile(io, dest_path, .{}); }, else => |e| return e, }; @@ -1846,7 +1846,7 @@ pub fn runAllowFail( }; errdefer b.allocator.free(stdout); - const term = try child.wait(); + const term = try child.wait(io); switch (term) { .Exited => |code| { if (code != 0) { @@ -2193,7 +2193,7 @@ fn dependencyInner( const build_root: std.Build.Cache.Directory = .{ .path = build_root_string, - .handle = fs.cwd().openDir(build_root_string, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(build_root_string, .{}) catch |err| { std.debug.print("unable to open '{s}': {s}\n", .{ build_root_string, @errorName(err), }); diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 42459c033d..fdcb2ab714 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -508,7 +508,7 @@ pub const Manifest = struct { // and `want_shared_lock` is set, a shared lock might be sufficient, so we'll // open with a shared lock instead. while (true) { - if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ + if (self.cache.manifest_dir.createFile(io, &manifest_file_path, .{ .read = true, .truncate = false, .lock = .exclusive, @@ -543,7 +543,7 @@ pub const Manifest = struct { return error.CacheCheckFailed; } - if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ + if (self.cache.manifest_dir.createFile(io, &manifest_file_path, .{ .read = true, .truncate = false, .lock = .exclusive, @@ -873,7 +873,7 @@ pub const Manifest = struct { if (man.want_refresh_timestamp) { man.want_refresh_timestamp = false; - var file = man.cache.manifest_dir.createFile("timestamp", .{ + var file = man.cache.manifest_dir.createFile(io, "timestamp", .{ .read = true, .truncate = true, }) catch |err| switch (err) { @@ -1324,7 +1324,7 @@ fn hashFile(file: Io.File, bin_digest: *[Hasher.mac_length]u8) Io.File.PReadErro fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { const test_out_file = "test-filetimestamp.tmp"; - var file = try dir.createFile(test_out_file, .{ + var file = try dir.createFile(io, test_out_file, .{ .read = true, .truncate = true, }); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 56ef32e8d8..2ec1c0ef31 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -401,6 +401,9 @@ pub fn evalZigProcess( web_server: ?*Build.WebServer, gpa: Allocator, ) !?Path { + const b = s.owner; + const io = b.graph.io; + // If an error occurs, it's happened in this command: assert(s.result_failed_command == null); s.result_failed_command = try allocPrintCmd(gpa, null, argv); @@ -411,7 +414,7 @@ pub fn evalZigProcess( const result = zigProcessUpdate(s, zp, watch, web_server, gpa) catch |err| switch (err) { error.BrokenPipe => { // Process restart required. - const term = zp.child.wait() catch |e| { + const term = zp.child.wait(io) catch |e| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], e }); }; _ = term; @@ -427,7 +430,7 @@ pub fn evalZigProcess( if (s.result_error_msgs.items.len > 0 and result == null) { // Crash detected. - const term = zp.child.wait() catch |e| { + const term = zp.child.wait(io) catch |e| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], e }); }; s.result_peak_rss = zp.child.resource_usage_statistics.getMaxRss() orelse 0; @@ -439,9 +442,7 @@ pub fn evalZigProcess( return result; } assert(argv.len != 0); - const b = s.owner; const arena = b.allocator; - const io = b.graph.io; try handleChildProcUnsupported(s); try handleVerbose(s.owner, null, argv); @@ -478,7 +479,7 @@ pub fn evalZigProcess( zp.child.stdin.?.close(io); zp.child.stdin = null; - const term = zp.child.wait() catch |err| { + const term = zp.child.wait(io) catch |err| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], err }); }; s.result_peak_rss = zp.child.resource_usage_statistics.getMaxRss() orelse 0; @@ -519,7 +520,7 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus { const b = s.owner; try handleVerbose(b, null, &.{ "install", "-d", dest_path }); - return std.fs.cwd().makePathStatus(dest_path) catch |err| + return Io.Dir.cwd().makePathStatus(dest_path) catch |err| return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err }); } @@ -895,7 +896,7 @@ pub fn addWatchInput(step: *Step, lazy_file: Build.LazyPath) Allocator.Error!voi try addWatchInputFromPath(step, .{ .root_dir = .{ .path = null, - .handle = std.fs.cwd(), + .handle = Io.Dir.cwd(), }, .sub_path = std.fs.path.dirname(path_string) orelse "", }, std.fs.path.basename(path_string)); @@ -920,7 +921,7 @@ pub fn addDirectoryWatchInput(step: *Step, lazy_directory: Build.LazyPath) Alloc try addDirectoryWatchInputFromPath(step, .{ .root_dir = .{ .path = null, - .handle = std.fs.cwd(), + .handle = Io.Dir.cwd(), }, .sub_path = path_string, }); diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig index efeedc8b80..560b6ad050 100644 --- a/lib/std/Build/Step/CheckFile.zig +++ b/lib/std/Build/Step/CheckFile.zig @@ -3,7 +3,9 @@ //! TODO: generalize the code in std.testing.expectEqualStrings and make this //! CheckFile step produce those helpful diagnostics when there is not a match. const CheckFile = @This(); + const std = @import("std"); +const Io = std.Io; const Step = std.Build.Step; const fs = std.fs; const mem = std.mem; @@ -53,7 +55,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { try step.singleUnchangingWatchInput(check_file.source); const src_path = check_file.source.getPath2(b, step); - const contents = fs.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index df2419764d..ea7d9d99ff 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -1,5 +1,7 @@ -const std = @import("std"); const ConfigHeader = @This(); + +const std = @import("std"); +const Io = std.Io; const Step = std.Build.Step; const Allocator = std.mem.Allocator; const Writer = std.Io.Writer; @@ -205,7 +207,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .autoconf_undef, .autoconf_at => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read autoconf input file '{s}': {s}", .{ src_path, @errorName(err), }); @@ -219,7 +221,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .cmake => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read cmake input file '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 9f5665e93a..1416e0e916 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -1,12 +1,13 @@ -const std = @import("std"); +const Options = @This(); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const fs = std.fs; const Step = std.Build.Step; const GeneratedFile = std.Build.GeneratedFile; const LazyPath = std.Build.LazyPath; -const Options = @This(); - pub const base_id: Step.Id = .options; step: Step, @@ -542,11 +543,11 @@ test Options { .cache = .{ .io = io, .gpa = arena.allocator(), - .manifest_dir = std.fs.cwd(), + .manifest_dir = Io.Dir.cwd(), }, .zig_exe = "test", .env_map = std.process.EnvMap.init(arena.allocator()), - .global_cache_root = .{ .path = "test", .handle = std.fs.cwd() }, + .global_cache_root = .{ .path = "test", .handle = Io.Dir.cwd() }, .host = .{ .query = .{}, .result = try std.zig.system.resolveTargetQuery(io, .{}), @@ -557,8 +558,8 @@ test Options { var builder = try std.Build.create( &graph, - .{ .path = "test", .handle = std.fs.cwd() }, - .{ .path = "test", .handle = std.fs.cwd() }, + .{ .path = "test", .handle = Io.Dir.cwd() }, + .{ .path = "test", .handle = Io.Dir.cwd() }, &.{}, ); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 7c54c8048e..af6bc20438 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1023,7 +1023,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, options, null); - const dep_file_dir = std.fs.cwd(); + const dep_file_dir = Io.Dir.cwd(); const dep_file_basename = dep_output_file.generated_file.getPath2(b, step); if (has_side_effects) try man.addDepFile(dep_file_dir, dep_file_basename) diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index ff06ad3ff3..f7ac47961e 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -122,7 +122,7 @@ const Os = switch (builtin.os.tag) { }) catch return error.NameTooLong; const stack_ptr: *std.os.linux.file_handle = @ptrCast(&file_handle_buffer); stack_ptr.handle_bytes = file_handle_buffer.len - @sizeOf(std.os.linux.file_handle); - try posix.name_to_handle_at(path.root_dir.handle.fd, adjusted_path, stack_ptr, mount_id, std.os.linux.AT.HANDLE_FID); + try posix.name_to_handle_at(path.root_dir.handle.handle, adjusted_path, stack_ptr, mount_id, std.os.linux.AT.HANDLE_FID); const stack_lfh: FileHandle = .{ .handle = stack_ptr }; return stack_lfh.clone(gpa); } @@ -222,7 +222,7 @@ const Os = switch (builtin.os.tag) { posix.fanotify_mark(fan_fd, .{ .ADD = true, .ONLYDIR = true, - }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| { + }, fan_mask, path.root_dir.handle.handle, path.subPathOrDot()) catch |err| { fatal("unable to watch {f}: {s}", .{ path, @errorName(err) }); }; } @@ -275,7 +275,7 @@ const Os = switch (builtin.os.tag) { posix.fanotify_mark(fan_fd, .{ .REMOVE = true, .ONLYDIR = true, - }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| switch (err) { + }, fan_mask, path.root_dir.handle.handle, path.subPathOrDot()) catch |err| switch (err) { error.FileNotFound => {}, // Expected, harmless. else => |e| std.log.warn("unable to unwatch '{f}': {s}", .{ path, @errorName(e) }), }; @@ -353,7 +353,7 @@ const Os = switch (builtin.os.tag) { // The following code is a drawn out NtCreateFile call. (mostly adapted from Io.Dir.makeOpenDirAccessMaskW) // It's necessary in order to get the specific flags that are required when calling ReadDirectoryChangesW. var dir_handle: windows.HANDLE = undefined; - const root_fd = path.root_dir.handle.fd; + const root_fd = path.root_dir.handle.handle; const sub_path = path.subPathOrDot(); const sub_path_w = try windows.sliceToPrefixedFileW(root_fd, sub_path); const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong; @@ -681,9 +681,9 @@ const Os = switch (builtin.os.tag) { if (!gop.found_existing) { const skip_open_dir = path.sub_path.len == 0; const dir_fd = if (skip_open_dir) - path.root_dir.handle.fd + path.root_dir.handle.handle else - posix.openat(path.root_dir.handle.fd, path.sub_path, dir_open_flags, 0) catch |err| { + posix.openat(path.root_dir.handle.handle, path.sub_path, dir_open_flags, 0) catch |err| { fatal("failed to open directory {f}: {s}", .{ path, @errorName(err) }); }; // Empirically the dir has to stay open or else no events are triggered. @@ -750,7 +750,7 @@ const Os = switch (builtin.os.tag) { // to access that data via the dir_fd field. const path = w.dir_table.keys()[i]; const dir_fd = if (path.sub_path.len == 0) - path.root_dir.handle.fd + path.root_dir.handle.handle else handles.items(.dir_fd)[i]; assert(dir_fd != -1); @@ -761,7 +761,7 @@ const Os = switch (builtin.os.tag) { const last_dir_fd = fd: { const last_path = w.dir_table.keys()[handles.len - 1]; const last_dir_fd = if (last_path.sub_path.len == 0) - last_path.root_dir.handle.fd + last_path.root_dir.handle.handle else handles.items(.dir_fd)[handles.len - 1]; assert(last_dir_fd != -1); diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig index 8e71f648e2..a9b4775772 100644 --- a/lib/std/Io/File.zig +++ b/lib/std/Io/File.zig @@ -527,6 +527,14 @@ pub fn writerStreaming(file: File, io: Io, buffer: []u8) Writer { return .initStreaming(file, io, buffer); } +/// Equivalent to creating a streaming writer, writing `bytes`, and then flushing. +pub fn writeStreamingAll(file: File, io: Io, bytes: []const u8) Writer.Error!void { + var index: usize = 0; + while (index < bytes.len) { + index += try io.vtable.fileWriteStreaming(io.userdata, file, &.{}, &.{bytes[index..]}, 1); + } +} + pub const LockError = error{ SystemResources, FileLocksUnsupported, diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index fb76002201..124f886515 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -2361,7 +2361,7 @@ fn dirCreateFilePosix( .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when accessing procfs. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -2670,7 +2670,7 @@ fn dirOpenFilePosix( .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when opening procfs files. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -3287,7 +3287,7 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when accessing procfs. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -5548,7 +5548,6 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: [][]u8) File. switch (e) { .INVAL => |err| return errnoBug(err), .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => |err| { if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. @@ -5672,7 +5671,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: [][]u8, offs switch (e) { .INVAL => |err| return errnoBug(err), .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => |err| { if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. @@ -6312,7 +6310,6 @@ fn fileWriteStreaming( switch (e) { .INVAL => return error.InvalidArgument, .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => return error.NotOpenForWriting, // Can be a race condition. .DESTADDRREQ => |err| return errnoBug(err), // `connect` was never called. diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 3f25bc6a26..63ae6d93a0 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -2835,7 +2835,7 @@ test "discarding sendFile" { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [256]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); @@ -2857,7 +2857,7 @@ test "allocating sendFile" { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); @@ -2881,7 +2881,7 @@ test sendFileReading { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); diff --git a/lib/std/Io/net/test.zig b/lib/std/Io/net/test.zig index 5818f6c3f7..c9ed0d3284 100644 --- a/lib/std/Io/net/test.zig +++ b/lib/std/Io/net/test.zig @@ -278,7 +278,7 @@ test "listen on a unix socket, send bytes, receive bytes" { defer testing.allocator.free(socket_path); const socket_addr = try net.UnixAddress.init(socket_path); - defer std.fs.cwd().deleteFile(socket_path) catch {}; + defer Io.Dir.cwd().deleteFile(socket_path) catch {}; var server = try socket_addr.listen(io, .{}); defer server.socket.close(io); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index 9f21fe50e7..e731dc18d7 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -27,7 +27,7 @@ test "write a file, read it, then delete it" { random.bytes(data[0..]); const tmp_file_name = "temp_test_file.txt"; { - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var file_writer = file.writer(&.{}); @@ -40,7 +40,7 @@ test "write a file, read it, then delete it" { { // Make sure the exclusive flag is honored. - try expectError(File.OpenError.PathAlreadyExists, tmp.dir.createFile(tmp_file_name, .{ .exclusive = true })); + try expectError(File.OpenError.PathAlreadyExists, tmp.dir.createFile(io, tmp_file_name, .{ .exclusive = true })); } { @@ -70,7 +70,7 @@ test "File seek ops" { const io = testing.io; const tmp_file_name = "temp_test_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); try file.writeAll(&([_]u8{0x55} ** 8192)); @@ -96,7 +96,7 @@ test "setEndPos" { defer tmp.cleanup(); const tmp_file_name = "temp_test_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); // Verify that the file size changes and the file offset is not moved @@ -121,7 +121,7 @@ test "updateTimes" { defer tmp.cleanup(); const tmp_file_name = "just_a_temporary_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); + var file = try tmp.dir.createFile(io, tmp_file_name, .{ .read = true }); defer file.close(io); const stat_old = try file.stat(); diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 102bb59415..8453bc4c81 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -208,7 +208,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { var buf: [32]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); - const file = try std.fs.cwd().openFile(io, path, .{ .mode = .write_only }); + const file = try Io.Dir.cwd().openFile(io, path, .{ .mode = .write_only }); defer file.close(io); try file.writeAll(name); @@ -325,7 +325,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co var threaded: std.Io.Threaded = .init_single_threaded; const io = threaded.ioBasic(); - const file = try std.fs.cwd().openFile(io, path, .{}); + const file = try Io.Dir.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.readerStreaming(io, &.{}); diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index 473505ac51..444d8da675 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -19,7 +19,7 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanM _ = io; // TODO migrate file system to use std.Io for (keychain_paths) |keychain_path| { - const bytes = std.fs.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { + const bytes = Io.Dir.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { error.StreamTooLong => return error.FileTooBig, else => |e| return e, }; diff --git a/lib/std/crypto/codecs/asn1/test.zig b/lib/std/crypto/codecs/asn1/test.zig index ff854fcbde..3dbedb9f80 100644 --- a/lib/std/crypto/codecs/asn1/test.zig +++ b/lib/std/crypto/codecs/asn1/test.zig @@ -73,8 +73,8 @@ test AllTypes { try std.testing.expectEqualSlices(u8, encoded, buf); // Use this to update test file. - // const dir = try std.fs.cwd().openDir("lib/std/crypto/asn1", .{}); - // var file = try dir.createFile(path, .{}); + // const dir = try Io.Dir.cwd().openDir("lib/std/crypto/asn1", .{}); + // var file = try dir.createFile(io, path, .{}); // defer file.close(io); // try file.writeAll(buf); } diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 97741ecb40..5df0eef2d5 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -60,7 +60,7 @@ pub const cpu_context = @import("debug/cpu_context.zig"); /// }; /// /// Only required if `can_unwind == true`. Unwinds a single stack frame, returning the frame's /// /// return address, or 0 if the end of the stack has been reached. -/// pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) SelfInfoError!usize; +/// pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, io: Io, context: *UnwindContext) SelfInfoError!usize; /// ``` pub const SelfInfo = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "SelfInfo")) root.debug.SelfInfo @@ -558,9 +558,9 @@ pub fn defaultPanic( stderr.print("{s}\n", .{msg}) catch break :trace; if (@errorReturnTrace()) |t| if (t.index > 0) { - stderr.writeAll("error return context:\n") catch break :trace; + stderr.writeStreamingAll("error return context:\n") catch break :trace; writeStackTrace(t, stderr, tty_config) catch break :trace; - stderr.writeAll("\nstack trace:\n") catch break :trace; + stderr.writeStreamingAll("\nstack trace:\n") catch break :trace; }; writeCurrentStackTrace(.{ .first_address = first_trace_addr orelse @returnAddress(), @@ -575,7 +575,7 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - File.stderr().writeAll("aborting due to recursive panic\n") catch {}; + File.stderr().writeStreamingAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } @@ -960,7 +960,7 @@ const StackIterator = union(enum) { }, }; - fn next(it: *StackIterator) Result { + fn next(it: *StackIterator, io: Io) Result { switch (it.*) { .ctx_first => |context_ptr| { // After the first frame, start actually unwinding. @@ -976,7 +976,7 @@ const StackIterator = union(enum) { .di => |*unwind_context| { const di = getSelfDebugInfo() catch unreachable; const di_gpa = getDebugInfoAllocator(); - const ret_addr = di.unwindFrame(di_gpa, unwind_context) catch |err| { + const ret_addr = di.unwindFrame(di_gpa, io, unwind_context) catch |err| { const pc = unwind_context.pc; const fp = unwind_context.getFp(); it.* = .{ .fp = fp }; @@ -1297,7 +1297,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("line_overlaps_page_boundary.zig", .{}); + const file = try test_dir.dir.createFile(io, "line_overlaps_page_boundary.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "line_overlaps_page_boundary.zig" }); defer gpa.free(path); @@ -1316,7 +1316,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("file_ends_on_page_boundary.zig", .{}); + const file = try test_dir.dir.createFile(io, "file_ends_on_page_boundary.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" }); defer gpa.free(path); @@ -1330,7 +1330,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("very_long_first_line_spanning_multiple_pages.zig", .{}); + const file = try test_dir.dir.createFile(io, "very_long_first_line_spanning_multiple_pages.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" }); defer gpa.free(path); @@ -1356,7 +1356,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("file_of_newlines.zig", .{}); + const file = try test_dir.dir.createFile(io, "file_of_newlines.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" }); defer gpa.free(path); diff --git a/lib/std/debug/ElfFile.zig b/lib/std/debug/ElfFile.zig index a0f1188ade..203ee8effb 100644 --- a/lib/std/debug/ElfFile.zig +++ b/lib/std/debug/ElfFile.zig @@ -375,7 +375,7 @@ fn loadSeparateDebugFile( args: anytype, ) Allocator.Error!?[]align(std.heap.page_size_min) const u8 { const path = try std.fmt.allocPrint(arena, fmt, args); - const elf_file = std.fs.cwd().openFile(io, path, .{}) catch return null; + const elf_file = Io.Dir.cwd().openFile(io, path, .{}) catch return null; defer elf_file.close(io); const result = loadInner(arena, elf_file, opt_crc) catch |err| switch (err) { diff --git a/lib/std/debug/MachOFile.zig b/lib/std/debug/MachOFile.zig index ae904c0aec..18126a1c29 100644 --- a/lib/std/debug/MachOFile.zig +++ b/lib/std/debug/MachOFile.zig @@ -512,7 +512,7 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { + const file = Io.Dir.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig index 213389bf04..6ed18bcb80 100644 --- a/lib/std/debug/SelfInfo/Elf.zig +++ b/lib/std/debug/SelfInfo/Elf.zig @@ -29,13 +29,12 @@ pub fn deinit(si: *SelfInfo, gpa: Allocator) void { } pub fn getSymbol(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!std.debug.Symbol { - _ = io; const module = try si.findModule(gpa, address, .exclusive); defer si.rwlock.unlock(); const vaddr = address - module.load_offset; - const loaded_elf = try module.getLoadedElf(gpa); + const loaded_elf = try module.getLoadedElf(gpa, io); if (loaded_elf.file.dwarf) |*dwarf| { if (!loaded_elf.scanned_dwarf) { dwarf.open(gpa, native_endian) catch |err| switch (err) { @@ -180,7 +179,7 @@ comptime { } } pub const UnwindContext = Dwarf.SelfUnwinder; -pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error!usize { +pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, io: Io, context: *UnwindContext) Error!usize { comptime assert(can_unwind); { @@ -201,7 +200,7 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error @memset(si.unwind_cache.?, .empty); } - const unwind_sections = try module.getUnwindSections(gpa); + const unwind_sections = try module.getUnwindSections(gpa, io); for (unwind_sections) |*unwind| { if (context.computeRules(gpa, unwind, module.load_offset, null)) |entry| { entry.populate(si.unwind_cache.?); @@ -261,12 +260,12 @@ const Module = struct { }; /// Assumes we already hold an exclusive lock. - fn getUnwindSections(mod: *Module, gpa: Allocator) Error![]Dwarf.Unwind { - if (mod.unwind == null) mod.unwind = loadUnwindSections(mod, gpa); + fn getUnwindSections(mod: *Module, gpa: Allocator, io: Io) Error![]Dwarf.Unwind { + if (mod.unwind == null) mod.unwind = loadUnwindSections(mod, gpa, io); const us = &(mod.unwind.? catch |err| return err); return us.buf[0..us.len]; } - fn loadUnwindSections(mod: *Module, gpa: Allocator) Error!UnwindSections { + fn loadUnwindSections(mod: *Module, gpa: Allocator, io: Io) Error!UnwindSections { var us: UnwindSections = .{ .buf = undefined, .len = 0, @@ -284,7 +283,7 @@ const Module = struct { } else { // There is no `.eh_frame_hdr` section. There may still be an `.eh_frame` or `.debug_frame` // section, but we'll have to load the binary to get at it. - const loaded = try mod.getLoadedElf(gpa); + const loaded = try mod.getLoadedElf(gpa, io); // If both are present, we can't just pick one -- the info could be split between them. // `.debug_frame` is likely to be the more complete section, so we'll prioritize that one. if (loaded.file.debug_frame) |*debug_frame| { @@ -325,7 +324,7 @@ const Module = struct { } fn loadElf(mod: *Module, gpa: Allocator, io: Io) Error!LoadedElf { const load_result = if (mod.name.len > 0) res: { - var file = std.fs.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; + var file = Io.Dir.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(mod.name)); } else res: { @@ -334,7 +333,7 @@ const Module = struct { else => return error.ReadFailed, }; defer gpa.free(path); - var file = std.fs.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; + var file = Io.Dir.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(path)); }; diff --git a/lib/std/debug/SelfInfo/MachO.zig b/lib/std/debug/SelfInfo/MachO.zig index 15da616f3b..db8e5334e6 100644 --- a/lib/std/debug/SelfInfo/MachO.zig +++ b/lib/std/debug/SelfInfo/MachO.zig @@ -616,7 +616,7 @@ test { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { + const file = Io.Dir.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index f0ac30cca2..9874efd497 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -432,7 +432,7 @@ const Module = struct { break :pdb null; }; const pdb_file_open_result = if (fs.path.isAbsolute(path)) res: { - break :res std.fs.cwd().openFile(io, path, .{}); + break :res Io.Dir.cwd().openFile(io, path, .{}); } else res: { const self_dir = std.process.executableDirPathAlloc(io, gpa) catch |err| switch (err) { error.OutOfMemory, error.Unexpected => |e| return e, @@ -441,7 +441,7 @@ const Module = struct { defer gpa.free(self_dir); const abs_path = try fs.path.join(gpa, &.{ self_dir, path }); defer gpa.free(abs_path); - break :res std.fs.cwd().openFile(io, abs_path, .{}); + break :res Io.Dir.cwd().openFile(io, abs_path, .{}); }; const pdb_file = pdb_file_open_result catch |err| switch (err) { error.FileNotFound, error.IsDir => break :pdb null, diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 7db177ad70..a1801d00d0 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -160,7 +160,7 @@ pub const ElfDynLib = struct { fn openPath(path: []const u8, io: Io) !Io.Dir { if (path.len == 0) return error.NotDir; var parts = std.mem.tokenizeScalar(u8, path, '/'); - var parent = if (path[0] == '/') try std.fs.cwd().openDir("/", .{}) else std.fs.cwd(); + var parent = if (path[0] == '/') try Io.Dir.cwd().openDir("/", .{}) else Io.Dir.cwd(); while (parts.next()) |part| { const child = try parent.openDir(part, .{}); parent.close(io); @@ -174,7 +174,7 @@ pub const ElfDynLib = struct { while (paths.next()) |p| { var dir = openPath(p) catch continue; defer dir.close(io); - const fd = posix.openat(dir.fd, file_name, .{ + const fd = posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true, }, 0) catch continue; @@ -184,9 +184,9 @@ pub const ElfDynLib = struct { } fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t { - var dir = std.fs.cwd().openDir(dir_path, .{}) catch return null; + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch return null; defer dir.close(io); - return posix.openat(dir.fd, file_name, .{ + return posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true, }, 0) catch null; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index f4bdecf89d..aab86d40a6 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -46,7 +46,7 @@ const PathType = enum { // The final path may not actually exist which would cause realpath to fail. // So instead, we get the path of the dir and join it with the relative path. var fd_path_buf: [fs.max_path_bytes]u8 = undefined; - const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf); + const dir_path = try std.os.getFdPath(dir.handle, &fd_path_buf); return fs.path.joinZ(allocator, &.{ dir_path, relative_path }); } }.transform, @@ -55,7 +55,7 @@ const PathType = enum { // Any drive absolute path (C:\foo) can be converted into a UNC path by // using '127.0.0.1' as the server name and '$' as the share name. var fd_path_buf: [fs.max_path_bytes]u8 = undefined; - const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf); + const dir_path = try std.os.getFdPath(dir.handle, &fd_path_buf); const windows_path_type = windows.getWin32PathType(u8, dir_path); switch (windows_path_type) { .unc_absolute => return fs.path.joinZ(allocator, &.{ dir_path, relative_path }), @@ -256,7 +256,7 @@ fn testReadLinkW(allocator: mem.Allocator, dir: Dir, target_path: []const u8, sy const target_path_w = try std.unicode.wtf8ToWtf16LeAlloc(allocator, target_path); defer allocator.free(target_path_w); // Calling the W functions directly requires the path to be NT-prefixed - const symlink_path_w = try std.os.windows.sliceToPrefixedFileW(dir.fd, symlink_path); + const symlink_path_w = try std.os.windows.sliceToPrefixedFileW(dir.handle, symlink_path); const wtf16_buffer = try allocator.alloc(u16, target_path_w.len); defer allocator.free(wtf16_buffer); const actual = try dir.readLinkW(symlink_path_w.span(), wtf16_buffer); @@ -288,9 +288,11 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { var symlink: Dir = switch (builtin.target.os.tag) { .windows => windows_symlink: { - const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink"); + const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.handle, "symlink"); - var handle: windows.HANDLE = undefined; + var result: Dir = .{ + .handle = undefined, + }; const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2)); var nt_name = windows.UNICODE_STRING{ @@ -300,26 +302,16 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { }; var attr: windows.OBJECT_ATTRIBUTES = .{ .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), - .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd, - .Attributes = .{}, + .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.handle, + .Attributes = 0, .ObjectName = &nt_name, .SecurityDescriptor = null, .SecurityQualityOfService = null, }; var io_status_block: windows.IO_STATUS_BLOCK = undefined; const rc = windows.ntdll.NtCreateFile( - &handle, - .{ - .SPECIFIC = .{ .FILE_DIRECTORY = .{ - .READ_EA = true, - .TRAVERSE = true, - .READ_ATTRIBUTES = true, - } }, - .STANDARD = .{ - .RIGHTS = .READ, - .SYNCHRONIZE = true, - }, - }, + &result.handle, + windows.STANDARD_RIGHTS_READ | windows.FILE_READ_ATTRIBUTES | windows.FILE_READ_EA | windows.SYNCHRONIZE | windows.FILE_TRAVERSE, &attr, &io_status_block, null, @@ -337,7 +329,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { ); switch (rc) { - .SUCCESS => break :windows_symlink .{ .fd = handle }, + .SUCCESS => break :windows_symlink .{ .fd = result.handle }, else => return windows.unexpectedStatus(rc), } }, @@ -351,8 +343,8 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { .ACCMODE = .RDONLY, .CLOEXEC = true, }; - const fd = try posix.openatZ(ctx.dir.fd, &sub_path_c, flags, 0); - break :linux_symlink Dir{ .fd = fd }; + const fd = try posix.openatZ(ctx.dir.handle, &sub_path_c, flags, 0); + break :linux_symlink .{ .handle = fd }; }, else => unreachable, }; @@ -456,7 +448,7 @@ test "openDirAbsolute" { test "openDir cwd parent '..'" { const io = testing.io; - var dir = fs.cwd().openDir("..", .{}) catch |err| { + var dir = Io.Dir.cwd().openDir("..", .{}) catch |err| { if (native_os == .wasi and err == error.PermissionDenied) { return; // This is okay. WASI disallows escaping from the fs sandbox } @@ -534,7 +526,7 @@ test "Dir.Iterator" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -570,7 +562,7 @@ test "Dir.Iterator many entries" { var buf: [4]u8 = undefined; // Enough to store "1024". while (i < num) : (i += 1) { const name = try std.fmt.bufPrint(&buf, "{}", .{i}); - const file = try tmp_dir.dir.createFile(name, .{}); + const file = try tmp_dir.dir.createFile(io, name, .{}); file.close(io); } @@ -603,7 +595,7 @@ test "Dir.Iterator twice" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -638,7 +630,7 @@ test "Dir.Iterator reset" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -769,7 +761,7 @@ test "readFileAlloc" { var tmp_dir = tmpDir(.{}); defer tmp_dir.cleanup(); - var file = try tmp_dir.dir.createFile("test_file", .{ .read = true }); + var file = try tmp_dir.dir.createFile(io, "test_file", .{ .read = true }); defer file.close(io); const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); @@ -843,7 +835,7 @@ test "directory operations on files" { const test_file_name = try ctx.transformPath("test_file"); - var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); @@ -876,7 +868,7 @@ test "file operations on directories" { try ctx.dir.makeDir(test_dir_name); - try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{})); + try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); switch (native_os) { .dragonfly, .netbsd => { @@ -969,7 +961,7 @@ test "Dir.rename files" { // Renaming files const test_file_name = try ctx.transformPath("test_file"); const renamed_test_file_name = try ctx.transformPath("test_file_renamed"); - var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try ctx.dir.rename(test_file_name, renamed_test_file_name); @@ -983,7 +975,7 @@ test "Dir.rename files" { // Rename to existing file succeeds const existing_file_path = try ctx.transformPath("existing_file"); - var existing_file = try ctx.dir.createFile(existing_file_path, .{ .read = true }); + var existing_file = try ctx.dir.createFile(io, existing_file_path, .{ .read = true }); existing_file.close(io); try ctx.dir.rename(renamed_test_file_name, existing_file_path); @@ -1017,7 +1009,7 @@ test "Dir.rename directories" { var dir = try ctx.dir.openDir(test_dir_renamed_path, .{}); // Put a file in the directory - var file = try dir.createFile("test_file", .{ .read = true }); + var file = try dir.createFile(io, "test_file", .{ .read = true }); file.close(io); dir.close(io); @@ -1070,7 +1062,7 @@ test "Dir.rename directory onto non-empty dir" { try ctx.dir.makeDir(test_dir_path); var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); - var file = try target_dir.createFile("test_file", .{ .read = true }); + var file = try target_dir.createFile(io, "test_file", .{ .read = true }); file.close(io); target_dir.close(io); @@ -1094,7 +1086,7 @@ test "Dir.rename file <-> dir" { const test_file_path = try ctx.transformPath("test_file"); const test_dir_path = try ctx.transformPath("test_dir"); - var file = try ctx.dir.createFile(test_file_path, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_path, .{ .read = true }); file.close(io); try ctx.dir.makeDir(test_dir_path); try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, test_dir_path)); @@ -1115,7 +1107,7 @@ test "rename" { // Renaming files const test_file_name = "test_file"; const renamed_test_file_name = "test_file_renamed"; - var file = try tmp_dir1.dir.createFile(test_file_name, .{ .read = true }); + var file = try tmp_dir1.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); @@ -1149,7 +1141,7 @@ test "renameAbsolute" { // Renaming files const test_file_name = "test_file"; const renamed_test_file_name = "test_file_renamed"; - var file = try tmp_dir.dir.createFile(test_file_name, .{ .read = true }); + var file = try tmp_dir.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try fs.renameAbsolute( try fs.path.join(allocator, &.{ base_path, test_file_name }), @@ -1454,7 +1446,7 @@ test "writev, readv" { var write_vecs: [2][]const u8 = .{ line1, line2 }; var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; - var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); + var src_file = try tmp.dir.createFile(io, "test.txt", .{ .read = true }); defer src_file.close(io); var writer = src_file.writerStreaming(&.{}); @@ -1484,7 +1476,7 @@ test "pwritev, preadv" { var buf2: [line2.len]u8 = undefined; var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; - var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); + var src_file = try tmp.dir.createFile(io, "test.txt", .{ .read = true }); defer src_file.close(io); var writer = src_file.writer(&.{}); @@ -1584,14 +1576,14 @@ test "sendfile" { const line2 = "second line\n"; var vecs = [_][]const u8{ line1, line2 }; - var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); + var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); defer src_file.close(io); { var fw = src_file.writer(&.{}); try fw.interface.writeVecAll(&vecs); } - var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); + var dest_file = try dir.createFile(io, "sendfile2.txt", .{ .read = true }); defer dest_file.close(io); const header1 = "header1\n"; @@ -1627,12 +1619,12 @@ test "sendfile with buffered data" { var dir = try tmp.dir.openDir("os_test_tmp", .{}); defer dir.close(io); - var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); + var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); defer src_file.close(io); try src_file.writeAll("AAAABBBB"); - var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); + var dest_file = try dir.createFile(io, "sendfile2.txt", .{ .read = true }); defer dest_file.close(io); var src_buffer: [32]u8 = undefined; @@ -1718,10 +1710,10 @@ test "open file with exclusive nonblocking lock twice" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1735,10 +1727,10 @@ test "open file with shared and exclusive nonblocking lock" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .shared, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1752,10 +1744,10 @@ test "open file with exclusive and shared nonblocking lock" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .shared, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1769,13 +1761,13 @@ test "open file with exclusive lock twice, make sure second lock waits" { const io = ctx.io; const filename = try ctx.transformPath("file_lock_test.txt"); - const file = try ctx.dir.createFile(filename, .{ .lock = .exclusive }); + const file = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive }); errdefer file.close(io); const S = struct { fn checkFn(dir: *Io.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { started.set(); - const file1 = try dir.createFile(path, .{ .lock = .exclusive }); + const file1 = try dir.createFile(io, path, .{ .lock = .exclusive }); locked.set(); file1.close(io); @@ -1847,13 +1839,13 @@ test "read from locked file" { const filename = try ctx.transformPath("read_lock_file_test.txt"); { - const f = try ctx.dir.createFile(filename, .{ .read = true }); + const f = try ctx.dir.createFile(io, filename, .{ .read = true }); defer f.close(io); var buffer: [1]u8 = undefined; _ = try f.read(&buffer); } { - const f = try ctx.dir.createFile(filename, .{ + const f = try ctx.dir.createFile(io, filename, .{ .read = true, .lock = .exclusive, }); @@ -2037,7 +2029,7 @@ test "'.' and '..' in Io.Dir functions" { var created_subdir = try ctx.dir.openDir(subdir_path, .{}); created_subdir.close(io); - const created_file = try ctx.dir.createFile(file_path, .{}); + const created_file = try ctx.dir.createFile(io, file_path, .{}); created_file.close(io); try ctx.dir.access(file_path, .{}); @@ -2103,7 +2095,7 @@ test "chmod" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile("test_file", .{ .mode = 0o600 }); + const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 }); defer file.close(io); try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777); @@ -2127,7 +2119,7 @@ test "chown" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile("test_file", .{}); + const file = try tmp.dir.createFile(io, "test_file", .{}); defer file.close(io); try file.chown(null, null); @@ -2228,7 +2220,7 @@ test "read file non vectored" { const contents = "hello, world!\n"; - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); { var file_writer: File.Writer = .init(file, &.{}); @@ -2260,7 +2252,7 @@ test "seek keeping partial buffer" { const contents = "0123456789"; - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); { var file_writer: File.Writer = .init(file, &.{}); @@ -2321,7 +2313,7 @@ test "seekTo flushes buffered data" { const contents = "data"; - const file = try tmp.dir.createFile("seek.bin", .{ .read = true }); + const file = try tmp.dir.createFile(io, "seek.bin", .{ .read = true }); defer file.close(io); { var buf: [16]u8 = undefined; @@ -2350,7 +2342,7 @@ test "File.Writer sendfile with buffered contents" { try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); const in = try tmp_dir.dir.openFile(io, "a", .{}); defer in.close(io); - const out = try tmp_dir.dir.createFile("b", .{}); + const out = try tmp_dir.dir.createFile(io, "b", .{}); defer out.close(io); var in_buf: [2]u8 = undefined; @@ -2397,7 +2389,7 @@ test "readlinkat" { // create a symbolic link if (native_os == .windows) { std.os.windows.CreateSymbolicLink( - tmp.dir.fd, + tmp.dir.handle, &[_]u16{ 'l', 'i', 'n', 'k' }, &[_:0]u16{ 'f', 'i', 'l', 'e', '.', 't', 'x', 't' }, false, @@ -2407,7 +2399,7 @@ test "readlinkat" { else => return err, }; } else { - try posix.symlinkat("file.txt", tmp.dir.fd, "link"); + try posix.symlinkat("file.txt", tmp.dir.handle, "link"); } // read the link diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index c7d3f35d40..0972a302da 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -1991,7 +1991,7 @@ test "writev/fsync/readv" { defer tmp.cleanup(); const path = "test_io_uring_writev_fsync_readv"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2062,7 +2062,7 @@ test "write/read" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); const path = "test_io_uring_write_read"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2110,12 +2110,12 @@ test "splice/read" { var tmp = std.testing.tmpDir(.{}); const path_src = "test_io_uring_splice_src"; - const file_src = try tmp.dir.createFile(path_src, .{ .read = true, .truncate = true }); + const file_src = try tmp.dir.createFile(io, path_src, .{ .read = true, .truncate = true }); defer file_src.close(io); const fd_src = file_src.handle; const path_dst = "test_io_uring_splice_dst"; - const file_dst = try tmp.dir.createFile(path_dst, .{ .read = true, .truncate = true }); + const file_dst = try tmp.dir.createFile(io, path_dst, .{ .read = true, .truncate = true }); defer file_dst.close(io); const fd_dst = file_dst.handle; @@ -2185,7 +2185,7 @@ test "write_fixed/read_fixed" { defer tmp.cleanup(); const path = "test_io_uring_write_read_fixed"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2306,7 +2306,7 @@ test "close" { defer tmp.cleanup(); const path = "test_io_uring_close"; - const file = try tmp.dir.createFile(path, .{}); + const file = try tmp.dir.createFile(io, path, .{}); errdefer file.close(io); const sqe_close = try ring.close(0x44444444, file.handle); @@ -2652,7 +2652,7 @@ test "fallocate" { defer tmp.cleanup(); const path = "test_io_uring_fallocate"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try testing.expectEqual(@as(u64, 0), (try file.stat()).size); @@ -2699,7 +2699,7 @@ test "statx" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); const path = "test_io_uring_statx"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try testing.expectEqual(@as(u64, 0), (try file.stat()).size); @@ -2969,7 +2969,7 @@ test "renameat" { // Write old file with data - const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 }); + const old_file = try tmp.dir.createFile(io, old_path, .{ .truncate = true, .mode = 0o666 }); defer old_file.close(io); try old_file.writeAll("hello"); @@ -3028,7 +3028,7 @@ test "unlinkat" { // Write old file with data - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); // Submit unlinkat @@ -3125,7 +3125,7 @@ test "symlinkat" { const path = "test_io_uring_symlinkat"; const link_path = "test_io_uring_symlinkat_link"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); // Submit symlinkat @@ -3177,7 +3177,7 @@ test "linkat" { // Write file with data - const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 }); + const first_file = try tmp.dir.createFile(io, first_path, .{ .truncate = true, .mode = 0o666 }); defer first_file.close(io); try first_file.writeAll("hello"); diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index 39606ddfac..d7cfb4e138 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -18,7 +18,7 @@ test "fallocate" { defer tmp.cleanup(); const path = "test_fallocate"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try expect((try file.stat()).size == 0); @@ -85,7 +85,7 @@ test "statx" { defer tmp.cleanup(); const tmp_file_name = "just_a_temporary_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var buf: linux.Statx = undefined; @@ -121,7 +121,7 @@ test "fadvise" { defer tmp.cleanup(); const tmp_file_name = "temp_posix_fadvise.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var buf: [2048]u8 = undefined; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 6b5b678b20..ba5282256f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -4639,8 +4639,8 @@ pub fn wToPrefixedFileW(dir: ?HANDLE, path: [:0]const u16) Wtf16ToPrefixedFileWE break :path_to_get path; } // We can also skip GetFinalPathNameByHandle if the handle matches - // the handle returned by fs.cwd() - if (dir.? == std.fs.cwd().fd) { + // the handle returned by Io.Dir.cwd() + if (dir.? == Io.Dir.cwd().fd) { break :path_to_get path; } // At this point, we know we have a relative path that had too many diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 392987ec50..f4aa970413 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -15,15 +15,16 @@ //! deal with the exception. const builtin = @import("builtin"); -const root = @import("root"); +const native_os = builtin.os.tag; + const std = @import("std.zig"); +const Io = std.Io; const mem = std.mem; const fs = std.fs; -const max_path_bytes = fs.max_path_bytes; +const max_path_bytes = std.fs.max_path_bytes; const maxInt = std.math.maxInt; const cast = std.math.cast; const assert = std.debug.assert; -const native_os = builtin.os.tag; const page_size_min = std.heap.page_size_min; test { @@ -797,7 +798,6 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { .INTR => continue, .INVAL => unreachable, .FAULT => unreachable, - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .CANCELED => return error.Canceled, .BADF => return error.NotOpenForReading, // Can be a race condition. @@ -917,7 +917,6 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { .INTR => continue, .INVAL => return error.InvalidArgument, .FAULT => unreachable, - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => return error.NotOpenForWriting, // can be a race condition. .DESTADDRREQ => unreachable, // `connect` was never called. @@ -985,7 +984,8 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t { .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + // Can happen on Linux when opening procfs files. + .SRCH => return error.FileNotFound, .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -1560,7 +1560,7 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void { pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void { _ = mode; const sub_dir_handle = windows.OpenFile(dir_path_w, .{ - .dir = fs.cwd().fd, + .dir = Io.Dir.cwd().handle, .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true }, .GENERIC = .{ .READ = true }, diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 0071a72a26..dc63be6e14 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -148,7 +148,7 @@ test "linkat with different directories" { try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "example" }); // Test 1: link from file in subdir back up to target in parent directory - try posix.linkat(tmp.dir.fd, target_name, subdir.fd, link_name, 0); + try posix.linkat(tmp.dir.handle, target_name, subdir.handle, link_name, 0); const efd = try tmp.dir.openFile(io, target_name, .{}); defer efd.close(io); @@ -164,7 +164,7 @@ test "linkat with different directories" { } // Test 2: remove link - try posix.unlinkat(subdir.fd, link_name, 0); + try posix.unlinkat(subdir.handle, link_name, 0); _, const elink = try getLinkInfo(efd.handle); try testing.expectEqual(@as(posix.nlink_t, 1), elink); } @@ -373,7 +373,7 @@ test "mmap" { // Create a file used for testing mmap() calls with a file descriptor { - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); var stream = file.writer(&.{}); @@ -444,7 +444,7 @@ test "fcntl" { const test_out_file = "os_tmp_test"; - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); // Note: The test assumes createFile opens the file with CLOEXEC @@ -495,7 +495,7 @@ test "fsync" { defer tmp.cleanup(); const test_out_file = "os_tmp_test"; - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); try posix.fsync(file.handle); @@ -617,7 +617,7 @@ test "dup & dup2" { defer tmp.cleanup(); { - var file = try tmp.dir.createFile("os_dup_test", .{}); + var file = try tmp.dir.createFile(io, "os_dup_test", .{}); defer file.close(io); var duped = Io.File{ .handle = try posix.dup(file.handle) }; @@ -659,7 +659,7 @@ test "writev longer than IOV_MAX" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pwritev", .{}); + var file = try tmp.dir.createFile(io, "pwritev", .{}); defer file.close(io); const iovecs = [_]posix.iovec_const{.{ .base = "a", .len = 1 }} ** (posix.IOV_MAX + 1); @@ -684,7 +684,7 @@ test "POSIX file locking with fcntl" { defer tmp.cleanup(); // Create a temporary lock file - var file = try tmp.dir.createFile("lock", .{ .read = true }); + var file = try tmp.dir.createFile(io, "lock", .{ .read = true }); defer file.close(io); try file.setEndPos(2); const fd = file.handle; @@ -881,7 +881,7 @@ test "isatty" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("foo", .{}); + var file = try tmp.dir.createFile(io, "foo", .{}); defer file.close(io); try expectEqual(posix.isatty(file.handle), false); @@ -893,7 +893,7 @@ test "pread with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pread_empty", .{ .read = true }); + var file = try tmp.dir.createFile(io, "pread_empty", .{ .read = true }); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -909,7 +909,7 @@ test "write with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("write_empty", .{}); + var file = try tmp.dir.createFile(io, "write_empty", .{}); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -925,7 +925,7 @@ test "pwrite with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pwrite_empty", .{}); + var file = try tmp.dir.createFile(io, "pwrite_empty", .{}); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -965,35 +965,35 @@ test "fchmodat smoke test" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try expectError(error.FileNotFound, posix.fchmodat(tmp.dir.fd, "regfile", 0o666, 0)); + try expectError(error.FileNotFound, posix.fchmodat(tmp.dir.handle, "regfile", 0o666, 0)); const fd = try posix.openat( - tmp.dir.fd, + tmp.dir.handle, "regfile", .{ .ACCMODE = .WRONLY, .CREAT = true, .EXCL = true, .TRUNC = true }, 0o644, ); posix.close(fd); - try posix.symlinkat("regfile", tmp.dir.fd, "symlink"); - const sym_mode = try getFileMode(tmp.dir.fd, "symlink"); + try posix.symlinkat("regfile", tmp.dir.handle, "symlink"); + const sym_mode = try getFileMode(tmp.dir.handle, "symlink"); - try posix.fchmodat(tmp.dir.fd, "regfile", 0o640, 0); - try expectMode(tmp.dir.fd, "regfile", 0o640); - try posix.fchmodat(tmp.dir.fd, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW); - try expectMode(tmp.dir.fd, "regfile", 0o600); + try posix.fchmodat(tmp.dir.handle, "regfile", 0o640, 0); + try expectMode(tmp.dir.handle, "regfile", 0o640); + try posix.fchmodat(tmp.dir.handle, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW); + try expectMode(tmp.dir.handle, "regfile", 0o600); - try posix.fchmodat(tmp.dir.fd, "symlink", 0o640, 0); - try expectMode(tmp.dir.fd, "regfile", 0o640); - try expectMode(tmp.dir.fd, "symlink", sym_mode); + try posix.fchmodat(tmp.dir.handle, "symlink", 0o640, 0); + try expectMode(tmp.dir.handle, "regfile", 0o640); + try expectMode(tmp.dir.handle, "symlink", sym_mode); var test_link = true; - posix.fchmodat(tmp.dir.fd, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) { + posix.fchmodat(tmp.dir.handle, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) { error.OperationNotSupported => test_link = false, else => |e| return e, }; if (test_link) - try expectMode(tmp.dir.fd, "symlink", 0o600); - try expectMode(tmp.dir.fd, "regfile", 0o640); + try expectMode(tmp.dir.handle, "symlink", 0o600); + try expectMode(tmp.dir.handle, "regfile", 0o640); } const CommonOpenFlags = packed struct { diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index b774303901..33faeef061 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -677,7 +677,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); if (self.cwd_dir) |cwd| { - posix.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err); + posix.fchdir(cwd.handle) catch |err| forkChildErrReport(err_pipe[1], err); } else if (self.cwd) |cwd| { posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err); } diff --git a/lib/std/std.zig b/lib/std/std.zig index 106811859b..1690c0575c 100644 --- a/lib/std/std.zig +++ b/lib/std/std.zig @@ -114,7 +114,7 @@ pub const options: Options = if (@hasDecl(root, "std_options")) root.std_options pub const Options = struct { enable_segfault_handler: bool = debug.default_enable_segfault_handler, - /// Function used to implement `std.fs.cwd` for WASI. + /// Function used to implement `std.Io.Dir.cwd` for WASI. wasiCwd: fn () os.wasi.fd_t = os.defaultWasiCwd, /// The current log level. diff --git a/lib/std/tar.zig b/lib/std/tar.zig index d861314fec..8a0bbb342f 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -610,7 +610,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } }, .file => { - if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| { + if (createDirAndFile(io, dir, file_name, fileMode(file.mode, options))) |fs_file| { defer fs_file.close(io); var file_writer = fs_file.writer(&file_contents_buffer); try it.streamRemaining(file, &file_writer.interface); @@ -638,12 +638,12 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } } -fn createDirAndFile(dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { - const fs_file = dir.createFile(file_name, .{ .exclusive = true, .mode = mode }) catch |err| { +fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { + const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { try dir.makePath(dir_name); - return try dir.createFile(file_name, .{ .exclusive = true, .mode = mode }); + return try dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }); } } return err; @@ -880,9 +880,9 @@ test "create file and symlink" { var root = testing.tmpDir(.{}); defer root.cleanup(); - var file = try createDirAndFile(root.dir, "file1", default_mode); + var file = try createDirAndFile(io, root.dir, "file1", default_mode); file.close(io); - file = try createDirAndFile(root.dir, "a/b/c/file2", default_mode); + file = try createDirAndFile(io, root.dir, "a/b/c/file2", default_mode); file.close(io); createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { @@ -894,7 +894,7 @@ test "create file and symlink" { // Danglink symlnik, file created later try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); - file = try createDirAndFile(root.dir, "g/h/i/file4", default_mode); + file = try createDirAndFile(io, root.dir, "g/h/i/file4", default_mode); file.close(io); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 19038543a6..99d67ec132 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -628,7 +628,7 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir { var sub_path: [TmpDir.sub_path_len]u8 = undefined; _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes); - const cwd = std.fs.cwd(); + const cwd = Io.Dir.cwd(); var cache_dir = cwd.makeOpenPath(".zig-cache", .{}) catch @panic("unable to make tmp dir for testing: unable to make and open .zig-cache dir"); defer cache_dir.close(io); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index c8bde2ab02..80317850df 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -57,7 +57,7 @@ pub fn parse( } } - const contents = try std.fs.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize))); + const contents = try Io.Dir.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize))); defer allocator.free(contents); var it = std.mem.tokenizeScalar(u8, contents, '\n'); @@ -337,7 +337,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F // search in reverse order const search_path_untrimmed = search_paths.items[search_paths.items.len - path_i - 1]; const search_path = std.mem.trimStart(u8, search_path_untrimmed, " "); - var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) { + var search_dir = Io.Dir.cwd().openDir(search_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -392,7 +392,7 @@ fn findNativeIncludeDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -440,7 +440,7 @@ fn findNativeCrtDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -508,7 +508,7 @@ fn findNativeKernel32LibDir( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -544,7 +544,7 @@ fn findNativeMsvcIncludeDir( const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" }); errdefer allocator.free(dir_path); - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig index 6b6e4fa9f7..dca474020a 100644 --- a/lib/std/zig/WindowsSdk.zig +++ b/lib/std/zig/WindowsSdk.zig @@ -828,7 +828,7 @@ const MsvcLibDir = struct { try lib_dir_buf.appendSlice("VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); var default_tools_version_buf: [512]u8 = undefined; - const default_tools_version_contents = std.fs.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch { + const default_tools_version_contents = Io.Dir.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch { return error.PathNotFound; }; var tokenizer = std.mem.tokenizeAny(u8, default_tools_version_contents, " \r\n"); diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index d3bafc16f2..9fa0546c3b 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -1,11 +1,12 @@ const builtin = @import("builtin"); +const native_endian = builtin.cpu.arch.endian(); + const std = @import("../std.zig"); const mem = std.mem; const elf = std.elf; const fs = std.fs; const assert = std.debug.assert; const Target = std.Target; -const native_endian = builtin.cpu.arch.endian(); const posix = std.posix; const Io = std.Io; @@ -69,7 +70,7 @@ pub fn getExternalExecutor( if (os_match and cpu_ok) native: { if (options.link_libc) { if (candidate.dynamic_linker.get()) |candidate_dl| { - fs.cwd().access(candidate_dl, .{}) catch { + Io.Dir.cwd().access(candidate_dl, .{}) catch { bad_result = .{ .bad_dl = candidate_dl }; break :native; }; @@ -710,6 +711,7 @@ fn abiAndDynamicLinkerFromFile( error.SystemResources, error.FileSystem, error.SymLinkLoop, + error.Canceled, error.Unexpected, => |e| return e, }; diff --git a/lib/std/zig/system/darwin/macos.zig b/lib/std/zig/system/darwin/macos.zig index 9bb4e34e3b..4ff6846a09 100644 --- a/lib/std/zig/system/darwin/macos.zig +++ b/lib/std/zig/system/darwin/macos.zig @@ -1,9 +1,10 @@ -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const mem = std.mem; const testing = std.testing; - const Target = std.Target; /// Detect macOS version. @@ -54,7 +55,7 @@ pub fn detect(target_os: *Target.Os) !void { // approx. 4 times historical file size var buf: [2048]u8 = undefined; - if (std.fs.cwd().readFile(path, &buf)) |bytes| { + if (Io.Dir.cwd().readFile(path, &buf)) |bytes| { if (parseSystemVersion(bytes)) |ver| { // never return non-canonical `10.(16+)` if (!(ver.major == 10 and ver.minor >= 16)) { diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 0ca77c98a1..9d08847092 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -564,9 +564,9 @@ pub const Iterator = struct { defer parent_dir.close(io); const basename = std.fs.path.basename(filename); - break :blk try parent_dir.createFile(basename, .{ .exclusive = true }); + break :blk try parent_dir.createFile(io, basename, .{ .exclusive = true }); } - break :blk try dest.createFile(filename, .{ .exclusive = true }); + break :blk try dest.createFile(io, filename, .{ .exclusive = true }); }; defer out_file.close(io); var out_file_buffer: [1024]u8 = undefined; diff --git a/src/Compilation.zig b/src/Compilation.zig index 24b994f608..5f15ef5f74 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -450,7 +450,7 @@ pub const Path = struct { const dir = switch (p.root) { .none => { const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); - return .{ fs.cwd(), cwd_sub_path }; + return .{ Io.Dir.cwd(), cwd_sub_path }; }, .zig_lib => dirs.zig_lib.handle, .global_cache => dirs.global_cache.handle, @@ -723,7 +723,7 @@ pub const Directories = struct { pub fn deinit(dirs: *Directories, io: Io) void { // The local and global caches could be the same. - const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; + const close_local = dirs.local_cache.handle.handle != dirs.global_cache.handle.handle; dirs.global_cache.handle.close(io); if (close_local) dirs.local_cache.handle.close(io); @@ -814,7 +814,7 @@ pub const Directories = struct { return .{ .path = if (std.mem.eql(u8, name, ".")) null else name, .handle = .{ - .fd = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), + .handle = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), }, }; } @@ -824,8 +824,8 @@ pub const Directories = struct { }; const nonempty_path = if (path.len == 0) "." else path; const handle_or_err = switch (thing) { - .@"zig lib" => fs.cwd().openDir(nonempty_path, .{}), - .@"global cache", .@"local cache" => fs.cwd().makeOpenPath(nonempty_path, .{}), + .@"zig lib" => Io.Dir.cwd().openDir(nonempty_path, .{}), + .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}), }; return .{ .path = if (path.len == 0) null else path, @@ -1104,7 +1104,7 @@ pub const CObject = struct { const source_line = source_line: { if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; - const file = fs.cwd().openFile(io, file_name, .{}) catch break :source_line 0; + const file = Io.Dir.cwd().openFile(io, file_name, .{}) catch break :source_line 0; defer file.close(io); var buffer: [1024]u8 = undefined; var file_reader = file.reader(io, &buffer); @@ -1179,7 +1179,7 @@ pub const CObject = struct { }; var buffer: [1024]u8 = undefined; - const file = try fs.cwd().openFile(io, path, .{}); + const file = try Io.Dir.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.reader(io, &buffer); var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); @@ -2109,7 +2109,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, }, }; // These correspond to std.zig.Server.Message.PathPrefix. - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(options.dirs.zig_lib); cache.addPrefix(options.dirs.local_cache); cache.addPrefix(options.dirs.global_cache); @@ -5220,7 +5220,7 @@ fn createDepFile( binfile: Cache.Path, ) anyerror!void { var buf: [4096]u8 = undefined; - var af = try std.fs.cwd().atomicFile(depfile, .{ .write_buffer = &buf }); + var af = try Io.Dir.cwd().atomicFile(depfile, .{ .write_buffer = &buf }); defer af.deinit(); comp.writeDepFile(binfile, &af.file_writer.interface) catch return af.file_writer.err.?; @@ -5284,7 +5284,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { }; } - var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| { + var tar_file = out_dir.createFile(io, "sources.tar", .{}) catch |err| { return comp.lockAndSetMiscFailure( .docs_copy, "unable to create '{f}/sources.tar': {s}", diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 3bd05120ff..8a30529bc5 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -383,14 +383,14 @@ pub fn run(f: *Fetch) RunError!void { }, .remote => |remote| remote, .path_or_url => |path_or_url| { - if (fs.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| { + if (Io.Dir.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| { var resource: Resource = .{ .dir = dir }; return f.runResource(path_or_url, &resource, null); } else |dir_err| { var server_header_buffer: [init_resource_buffer_size]u8 = undefined; const file_err = if (dir_err == error.NotDir) e: { - if (fs.cwd().openFile(io, path_or_url, .{})) |file| { + if (Io.Dir.cwd().openFile(io, path_or_url, .{})) |file| { var resource: Resource = .{ .file = file.reader(io, &server_header_buffer) }; return f.runResource(path_or_url, &resource, null); } else |err| break :e err; @@ -1303,7 +1303,7 @@ fn unzip( const random_integer = std.crypto.random.int(u64); zip_path[prefix.len..][0..random_len].* = std.fmt.hex(random_integer); - break cache_root.handle.createFile(&zip_path, .{ + break cache_root.handle.createFile(io, &zip_path, .{ .exclusive = true, .read = true, }) catch |err| switch (err) { @@ -1365,7 +1365,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U { var pack_dir = try out_dir.makeOpenPath(".git", .{}); defer pack_dir.close(io); - var pack_file = try pack_dir.createFile("pkg.pack", .{ .read = true }); + var pack_file = try pack_dir.createFile(io, "pkg.pack", .{ .read = true }); defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = b: { @@ -1376,7 +1376,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U break :b pack_file_writer.moveToReader(io); }; - var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true }); + var index_file = try pack_dir.createFile(io, "pkg.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); @@ -2235,7 +2235,7 @@ test "set executable bit based on file content" { fn saveEmbedFile(io: Io, comptime tarball_name: []const u8, dir: Io.Dir) !void { //const tarball_name = "duplicate_paths_excluded.tar.gz"; const tarball_content = @embedFile("Fetch/testdata/" ++ tarball_name); - var tmp_file = try dir.createFile(tarball_name, .{}); + var tmp_file = try dir.createFile(io, tarball_name, .{}); defer tmp_file.close(io); try tmp_file.writeAll(tarball_content); } diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index ccae9440e2..7b08a89cae 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -264,7 +264,7 @@ pub const Repository = struct { try repository.odb.seekOid(entry.oid); const file_object = try repository.odb.readObject(); if (file_object.type != .blob) return error.InvalidFile; - var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| { + var file = dir.createFile(io, entry.name, .{ .exclusive = true }) catch |e| { const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name }); errdefer diagnostics.allocator.free(file_name); try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{ @@ -1584,14 +1584,14 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u var git_dir = testing.tmpDir(.{}); defer git_dir.cleanup(); - var pack_file = try git_dir.dir.createFile("testrepo.pack", .{ .read = true }); + var pack_file = try git_dir.dir.createFile(io, "testrepo.pack", .{ .read = true }); defer pack_file.close(io); try pack_file.writeAll(testrepo_pack); var pack_file_buffer: [2000]u8 = undefined; var pack_file_reader = pack_file.reader(io, &pack_file_buffer); - var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); + var index_file = try git_dir.dir.createFile(io, "testrepo.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); @@ -1714,20 +1714,20 @@ pub fn main() !void { const format = std.meta.stringToEnum(Oid.Format, args[1]) orelse return error.InvalidFormat; - var pack_file = try std.fs.cwd().openFile(io, args[2], .{}); + var pack_file = try Io.Dir.cwd().openFile(io, args[2], .{}); defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = pack_file.reader(io, &pack_file_buffer); const commit = try Oid.parse(format, args[3]); - var worktree = try std.fs.cwd().makeOpenPath(args[4], .{}); + var worktree = try Io.Dir.cwd().makeOpenPath(args[4], .{}); defer worktree.close(io); var git_dir = try worktree.makeOpenPath(".git", .{}); defer git_dir.close(io); std.debug.print("Starting index...\n", .{}); - var index_file = try git_dir.createFile("idx", .{ .read = true }); + var index_file = try git_dir.createFile(io, "idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [4096]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 45b1302138..9a75b2096e 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -170,7 +170,7 @@ pub fn updateFile( // version. Likewise if we're working on AstGen and another process asks for // the cached file, they'll get it. const cache_file = while (true) { - break zir_dir.createFile(&hex_digest, .{ + break zir_dir.createFile(io, &hex_digest, .{ .read = true, .truncate = false, .lock = lock, @@ -196,7 +196,7 @@ pub fn updateFile( cache_directory, }); } - break zir_dir.createFile(&hex_digest, .{ + break zir_dir.createFile(io, &hex_digest, .{ .read = true, .truncate = false, .lock = lock, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index cb4fe0459f..4fc58c2c4b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1,19 +1,22 @@ -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const Allocator = std.mem.Allocator; const log = std.log.scoped(.codegen); const math = std.math; const DW = std.dwarf; - const Builder = std.zig.llvm.Builder; + +const build_options = @import("build_options"); const llvm = if (build_options.have_llvm) @import("llvm/bindings.zig") else @compileError("LLVM unavailable"); + const link = @import("../link.zig"); const Compilation = @import("../Compilation.zig"); -const build_options = @import("build_options"); const Zcu = @import("../Zcu.zig"); const InternPool = @import("../InternPool.zig"); const Package = @import("../Package.zig"); @@ -964,7 +967,7 @@ pub const Object = struct { if (std.mem.eql(u8, path, "-")) { o.builder.dump(); } else { - o.builder.printToFilePath(std.fs.cwd(), path) catch |err| { + o.builder.printToFilePath(Io.Dir.cwd(), path) catch |err| { log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); }; } @@ -978,7 +981,7 @@ pub const Object = struct { o.builder.clearAndFree(); if (options.pre_bc_path) |path| { - var file = std.fs.cwd().createFile(path, .{}) catch |err| + var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); defer file.close(io); @@ -991,7 +994,7 @@ pub const Object = struct { options.post_ir_path == null and options.post_bc_path == null) return; if (options.post_bc_path) |path| { - var file = std.fs.cwd().createFile(path, .{}) catch |err| + var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); defer file.close(io); @@ -2711,7 +2714,7 @@ pub const Object = struct { } fn allocTypeName(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error![:0]const u8 { - var aw: std.Io.Writer.Allocating = .init(o.gpa); + var aw: Io.Writer.Allocating = .init(o.gpa); defer aw.deinit(); ty.print(&aw.writer, pt, null) catch |err| switch (err) { error.WriteFailed => return error.OutOfMemory, diff --git a/src/fmt.zig b/src/fmt.zig index ce8a31fa4c..36a3833986 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -182,11 +182,11 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! // Mark any excluded files/directories as already seen, // so that they are skipped later during actual processing for (excluded_files.items) |file_path| { - const stat = fs.cwd().statFile(file_path) catch |err| switch (err) { + const stat = Io.Dir.cwd().statFile(file_path) catch |err| switch (err) { error.FileNotFound => continue, // On Windows, statFile does not work for directories error.IsDir => dir: { - var dir = try fs.cwd().openDir(file_path, .{}); + var dir = try Io.Dir.cwd().openDir(file_path, .{}); defer dir.close(io); break :dir try dir.stat(); }, @@ -196,7 +196,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! } for (input_files.items) |file_path| { - try fmtPath(&fmt, file_path, check_flag, fs.cwd(), file_path); + try fmtPath(&fmt, file_path, check_flag, Io.Dir.cwd(), file_path); } try fmt.stdout_writer.interface.flush(); if (fmt.any_error) { diff --git a/src/introspect.zig b/src/introspect.zig index d2faa9a55c..04ddf47e8a 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -82,7 +82,7 @@ pub fn findZigLibDirFromSelfExe( cwd_path: []const u8, self_exe_path: []const u8, ) error{ OutOfMemory, FileNotFound }!Cache.Directory { - const cwd = fs.cwd(); + const cwd = Io.Dir.cwd(); var cur_path: []const u8 = self_exe_path; while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { var base_dir = cwd.openDir(dirname, .{}) catch continue; @@ -206,7 +206,7 @@ pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator var cur_dir = cwd; while (true) { const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); - if (fs.cwd().access(joined, .{})) |_| { + if (Io.Dir.cwd().access(joined, .{})) |_| { return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); } else |err| switch (err) { error.FileNotFound => { diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index 8c5e0afe4b..cfd8d5554c 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -446,7 +446,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -468,7 +468,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -986,7 +986,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -1014,7 +1014,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.getSoVersion(&target.os), + so_files.dir_path.sub_path, path.sep, lib.name, lib.getSoVersion(&target.os), }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index bec20ff3d4..e3d8ce1f7f 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -681,7 +681,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -703,7 +703,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -775,7 +775,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye try stubs_asm.appendSlice(".text\n"); var sym_i: usize = 0; - var sym_name_buf: std.Io.Writer.Allocating = .init(arena); + var sym_name_buf: Io.Writer.Allocating = .init(arena); var opt_symbol_name: ?[]const u8 = null; var versions_buffer: [32]u8 = undefined; var versions_len: usize = undefined; @@ -796,7 +796,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye // twice, which causes a "duplicate symbol" assembler error. var versions_written = std.AutoArrayHashMap(Version, void).init(arena); - var inc_reader: std.Io.Reader = .fixed(metadata.inclusions); + var inc_reader: Io.Reader = .fixed(metadata.inclusions); const fn_inclusions_len = try inc_reader.takeInt(u16, .little); @@ -1130,7 +1130,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -1156,7 +1156,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover, + so_files.dir_path.sub_path, path.sep, lib.name, lib.sover, }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 005696e1fc..b3ca51e833 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -1,7 +1,8 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; -const path = std.fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const log = std.log.scoped(.mingw); @@ -259,7 +260,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -304,7 +305,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { .output = .{ .to_list = .{ .arena = .init(gpa) } }, }; defer diagnostics.deinit(); - var aro_comp = aro.Compilation.init(gpa, arena, io, &diagnostics, std.fs.cwd()); + var aro_comp = aro.Compilation.init(gpa, arena, io, &diagnostics, Io.Dir.cwd()); defer aro_comp.deinit(); aro_comp.target = .fromZigTarget(target.*); @@ -343,7 +344,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { } const members = members: { - var aw: std.Io.Writer.Allocating = .init(gpa); + var aw: Io.Writer.Allocating = .init(gpa); errdefer aw.deinit(); try pp.prettyPrintTokens(&aw.writer, .result_only); @@ -376,7 +377,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { errdefer gpa.free(lib_final_path); { - const lib_final_file = try o_dir.createFile(final_lib_basename, .{ .truncate = true }); + const lib_final_file = try o_dir.createFile(io, final_lib_basename, .{ .truncate = true }); defer lib_final_file.close(io); var buffer: [1024]u8 = undefined; var file_writer = lib_final_file.writer(&buffer); @@ -442,7 +443,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{ lib_path, lib_name }); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -459,7 +460,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -476,7 +477,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index 67e6a2f903..cb6a80d69d 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -387,7 +387,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -409,7 +409,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -640,7 +640,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -661,7 +661,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover, + so_files.dir_path.sub_path, path.sep, lib.name, lib.sover, }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/link/C.zig b/src/link/C.zig index 04c92443e5..a001f8fdd9 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -136,7 +136,7 @@ pub fn createEmpty( assert(!use_lld); assert(!use_llvm); - const file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ // Truncation is done on `flush`. .truncate = false, }); @@ -792,7 +792,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { } const directory = emit_h.loc.directory orelse zcu.comp.local_cache_directory; - const file = try directory.handle.createFile(emit_h.loc.basename, .{ + const file = try directory.handle.createFile(io, emit_h.loc.basename, .{ // We set the end position explicitly below; by not truncating the file, we possibly // make it easier on the file system by doing 1 reallocation instead of two. .truncate = false, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index e1d52fb7c4..009e59ed0d 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -631,12 +631,14 @@ fn create( else => return error.UnsupportedCOFFArchitecture, }; + const io = comp.io; + const coff = try arena.create(Coff); - const file = try path.root_dir.handle.createFile(comp.io, path.sub_path, .{ + const file = try path.root_dir.handle.createFile(io, path.sub_path, .{ .read = true, .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), }); - errdefer file.close(comp.io); + errdefer file.close(io); coff.* = .{ .base = .{ .tag = .coff2, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 584a50c7f2..53812a37ec 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -313,9 +313,11 @@ pub fn createEmpty( const is_obj = output_mode == .Obj; const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .static); + const io = comp.io; + // What path should this ELF linker code output to? const sub_path = emit.sub_path; - self.base.file = try emit.root_dir.handle.createFile(sub_path, .{ + self.base.file = try emit.root_dir.handle.createFile(io, sub_path, .{ .truncate = true, .read = true, .mode = link.File.determineMode(output_mode, link_mode), diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 49f6d3f7c7..b25b9da9d9 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1572,7 +1572,7 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { // report a nice error here with the file path if it fails instead of // just returning the error code. // chmod does not interact with umask, so we use a conservative -rwxr--r-- here. - std.posix.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) { + std.posix.fchmodat(Io.Dir.cwd().handle, full_out_path, 0o744, 0) catch |err| switch (err) { error.OperationNotSupported => unreachable, // Not a symlink. else => |e| return e, }; @@ -1624,7 +1624,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi const rand_int = std.crypto.random.int(u64); const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; - const rsp_file = try comp.dirs.local_cache.handle.createFile(rsp_path, .{}); + const rsp_file = try comp.dirs.local_cache.handle.createFile(io, rsp_path, .{}); defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); { diff --git a/src/link/MachO.zig b/src/link/MachO.zig index e837cc853a..0f6127e10e 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -219,7 +219,9 @@ pub fn createEmpty( }; errdefer self.base.destroy(); - self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const io = comp.io; + + self.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, .mode = link.File.determineMode(output_mode, link_mode), @@ -1082,7 +1084,7 @@ fn accessLibPath( test_path.clearRetainingCapacity(); try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1110,7 +1112,7 @@ fn accessFrameworkPath( ext, }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1191,7 +1193,7 @@ fn parseDependentDylibs(self: *MachO) !void { try test_path.print("{s}{s}", .{ path, ext }); } try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -3289,7 +3291,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{}); defer d_sym_bundle.close(io); - self.d_sym.?.file = try d_sym_bundle.createFile(fs.path.basename(self.base.emit.sub_path), .{ + self.d_sym.?.file = try d_sym_bundle.createFile(io, fs.path.basename(self.base.emit.sub_path), .{ .truncate = false, .read = true, }); @@ -4370,7 +4372,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi // The file/property is also available with vendored libc. fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 { const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" }); - const contents = try fs.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16))); + const contents = try Io.Dir.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16))); const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{}); if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string; return error.SdkVersionFailure; diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index 5f9a9ecac9..814faf234a 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -247,7 +247,7 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void { } pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void { - const inner = try fs.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32))); + const inner = try Io.Dir.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32))); self.entitlements = .{ .inner = inner }; } diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 7e28dc0a8b..d13caaa315 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -33,6 +33,7 @@ pub fn createEmpty( options: link.File.OpenOptions, ) !*Linker { const gpa = comp.gpa; + const io = comp.io; const target = &comp.root_mod.resolved_target.result; assert(!comp.config.use_lld); // Caught by Compilation.Config.resolve @@ -78,7 +79,7 @@ pub fn createEmpty( }; errdefer linker.deinit(); - linker.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + linker.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, }); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 7ab1e0eb4b..5f89625d56 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2997,7 +2997,9 @@ pub fn createEmpty( .named => |name| (try wasm.internString(name)).toOptional(), }; - wasm.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const io = comp.io; + + wasm.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, .mode = if (fs.has_executable_bit) diff --git a/src/main.zig b/src/main.zig index b040b6c8ef..67b7384b57 100644 --- a/src/main.zig +++ b/src/main.zig @@ -713,7 +713,7 @@ const Emit = union(enum) { } else e: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3304,7 +3304,7 @@ fn buildOutputType( } else emit: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3389,7 +3389,7 @@ fn buildOutputType( // file will not run and this temp file will be leaked. The filename // will be a hash of its contents — so multiple invocations of // `zig cc -` will result in the same temp file name. - var f = try dirs.local_cache.handle.createFile(dump_path, .{}); + var f = try dirs.local_cache.handle.createFile(io, dump_path, .{}); defer f.close(io); // Re-using the hasher from Cache, since the functional requirements @@ -4773,7 +4773,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! var ok_count: usize = 0; for (template_paths) |template_path| { - if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { + if (templates.write(arena, Io.Dir.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { std.log.info("created {s}", .{template_path}); ok_count += 1; } else |err| switch (err) { @@ -5227,7 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) if (system_pkg_dir_path) |p| { job_queue.global_cache = .{ .path = p, - .handle = fs.cwd().openDir(p, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(p, .{}) catch |err| { fatal("unable to open system package directory '{s}': {s}", .{ p, @errorName(err), }); @@ -5823,7 +5823,7 @@ const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, /// Initialize the arguments from a Response File. "*.rsp" fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile { const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit - const cmd_line = try fs.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes)); + const cmd_line = try Io.Dir.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes)); errdefer allocator.free(cmd_line); return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line); @@ -6187,7 +6187,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { const display_path = zig_source_path orelse ""; const source: [:0]const u8 = s: { var f = if (zig_source_path) |p| file: { - break :file fs.cwd().openFile(io, p, .{}) catch |err| { + break :file Io.Dir.cwd().openFile(io, p, .{}) catch |err| { fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); }; } else Io.File.stdin(); @@ -6494,7 +6494,7 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { const cache_file = args[0]; - var f = fs.cwd().openFile(io, cache_file, .{}) catch |err| { + var f = Io.Dir.cwd().openFile(io, cache_file, .{}) catch |err| { fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) }); }; defer f.close(io); @@ -6541,7 +6541,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { const new_source_path = args[1]; const old_source = source: { - var f = fs.cwd().openFile(io, old_source_path, .{}) catch |err| + var f = Io.Dir.cwd().openFile(io, old_source_path, .{}) catch |err| fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); @@ -6549,7 +6549,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); }; const new_source = source: { - var f = fs.cwd().openFile(io, new_source_path, .{}) catch |err| + var f = Io.Dir.cwd().openFile(io, new_source_path, .{}) catch |err| fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); @@ -6845,7 +6845,7 @@ fn accessFrameworkPath( framework_dir_path, framework_name, framework_name, ext, }); try checked_paths.print("\n {s}", .{test_path.items}); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{ ext, test_path.items, @errorName(e), @@ -6957,7 +6957,7 @@ fn cmdFetch( var global_cache_directory: Directory = l: { const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); break :l .{ - .handle = try fs.cwd().makeOpenPath(p, .{}), + .handle = try Io.Dir.cwd().makeOpenPath(p, .{}), .path = p, }; }; @@ -7260,7 +7260,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { if (options.build_file) |bf| { if (fs.path.dirname(bf)) |dirname| { - const dir = fs.cwd().openDir(dirname, .{}) catch |err| { + const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7272,7 +7272,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { return .{ .build_zig_basename = build_zig_basename, - .directory = .{ .path = null, .handle = fs.cwd() }, + .directory = .{ .path = null, .handle = Io.Dir.cwd() }, .cleanup_build_dir = null, }; } @@ -7280,8 +7280,8 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { var dirname: []const u8 = cwd_path; while (true) { const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); - if (fs.cwd().access(joined_path, .{})) |_| { - const dir = fs.cwd().openDir(dirname, .{}) catch |err| { + if (Io.Dir.cwd().access(joined_path, .{})) |_| { + const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7443,7 +7443,7 @@ const Templates = struct { } }; fn writeSimpleTemplateFile(io: Io, file_name: []const u8, comptime fmt: []const u8, args: anytype) !void { - const f = try fs.cwd().createFile(file_name, .{ .exclusive = true }); + const f = try Io.Dir.cwd().createFile(io, file_name, .{ .exclusive = true }); defer f.close(io); var buf: [4096]u8 = undefined; var fw = f.writer(&buf); @@ -7591,7 +7591,7 @@ fn addLibDirectoryWarn2( ignore_not_found: bool, ) void { lib_directories.appendAssumeCapacity(.{ - .handle = fs.cwd().openDir(path, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(path, .{}) catch |err| { if (err == error.FileNotFound and ignore_not_found) return; warn("unable to open library directory '{s}': {s}", .{ path, @errorName(err) }); return; -- cgit v1.2.3 From 264d714321d3e5f1f189af393e1fb24d101a7e91 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 13:46:29 -0800 Subject: update all openDir() sites to accept io instance --- lib/compiler/aro/aro/Driver/Filesystem.zig | 4 +-- lib/compiler/aro/aro/Toolchain.zig | 2 +- lib/compiler/resinator/compile.zig | 14 ++++---- lib/compiler/std-docs.zig | 4 +-- lib/std/Build.zig | 3 +- lib/std/Build/Cache/Path.zig | 3 +- lib/std/Build/Step/InstallArtifact.zig | 2 +- lib/std/Build/Step/WriteFile.zig | 2 +- lib/std/Io/Dir.zig | 10 +++--- lib/std/crypto/Certificate/Bundle.zig | 2 +- lib/std/crypto/codecs/asn1/test.zig | 2 +- lib/std/dynamic_library.zig | 6 ++-- lib/std/fs/test.zig | 54 ++++++++++++++++-------------- lib/std/os/linux/IoUring.zig | 4 ++- lib/std/zig/LibCInstallation.zig | 10 +++--- src/Compilation.zig | 23 ++++++++----- src/Package/Fetch.zig | 5 +-- src/Package/Fetch/git.zig | 2 +- src/fmt.zig | 4 +-- src/introspect.zig | 6 ++-- src/main.zig | 37 ++++++++++---------- 21 files changed, 107 insertions(+), 92 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Driver/Filesystem.zig b/lib/compiler/aro/aro/Driver/Filesystem.zig index b0bdbb7e21..001f10f27c 100644 --- a/lib/compiler/aro/aro/Driver/Filesystem.zig +++ b/lib/compiler/aro/aro/Driver/Filesystem.zig @@ -223,9 +223,9 @@ pub const Filesystem = union(enum) { }; } - pub fn openDir(fs: Filesystem, dir_name: []const u8) std.Io.Dir.OpenError!Dir { + pub fn openDir(fs: Filesystem, io: Io, dir_name: []const u8) std.Io.Dir.OpenError!Dir { return switch (fs) { - .real => |cwd| .{ .dir = try cwd.openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) }, + .real => |cwd| .{ .dir = try cwd.openDir(io, dir_name, .{ .access_sub_paths = false, .iterate = true }) }, .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } }, }; } diff --git a/lib/compiler/aro/aro/Toolchain.zig b/lib/compiler/aro/aro/Toolchain.zig index 95a8baba77..0328c264d0 100644 --- a/lib/compiler/aro/aro/Toolchain.zig +++ b/lib/compiler/aro/aro/Toolchain.zig @@ -509,7 +509,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { } var search_path = d.aro_name; while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) { - var base_dir = d.comp.cwd.openDir(dirname, .{}) catch continue; + var base_dir = d.comp.cwd.openDir(io, dirname, .{}) catch continue; defer base_dir.close(io); base_dir.access("include/stddef.h", .{}) catch continue; diff --git a/lib/compiler/resinator/compile.zig b/lib/compiler/resinator/compile.zig index 3e046a10c1..2d6ea87efb 100644 --- a/lib/compiler/resinator/compile.zig +++ b/lib/compiler/resinator/compile.zig @@ -106,13 +106,13 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io // If dirname returns null, then the root path will be the same as // the cwd so we don't need to add it as a distinct search path. if (std.fs.path.dirname(root_path)) |root_dir_path| { - var root_dir = try options.cwd.openDir(root_dir_path, .{}); + var root_dir = try options.cwd.openDir(io, root_dir_path, .{}); errdefer root_dir.close(io); try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) }); } } // Re-open the passed in cwd since we want to be able to close it (Io.Dir.cwd() shouldn't be closed) - const cwd_dir = options.cwd.openDir(".", .{}) catch |err| { + const cwd_dir = options.cwd.openDir(io, ".", .{}) catch |err| { try options.diagnostics.append(.{ .err = .failed_to_open_cwd, .token = .{ @@ -132,7 +132,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io }; try search_dirs.append(allocator, .{ .dir = cwd_dir, .path = null }); for (options.extra_include_paths) |extra_include_path| { - var dir = openSearchPathDir(options.cwd, extra_include_path) catch { + var dir = openSearchPathDir(options.cwd, io, extra_include_path) catch { // TODO: maybe a warning that the search path is skipped? continue; }; @@ -140,7 +140,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) }); } for (options.system_include_paths) |system_include_path| { - var dir = openSearchPathDir(options.cwd, system_include_path) catch { + var dir = openSearchPathDir(options.cwd, io, system_include_path) catch { // TODO: maybe a warning that the search path is skipped? continue; }; @@ -159,7 +159,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io }; var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter); while (it.next()) |search_path| { - var dir = openSearchPathDir(options.cwd, search_path) catch continue; + var dir = openSearchPathDir(options.cwd, io, search_path) catch continue; errdefer dir.close(io); try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) }); } @@ -2896,11 +2896,11 @@ pub const Compiler = struct { pub const OpenSearchPathError = std.Io.Dir.OpenError; -fn openSearchPathDir(dir: std.Io.Dir, path: []const u8) OpenSearchPathError!std.Io.Dir { +fn openSearchPathDir(dir: std.Io.Dir, io: Io, path: []const u8) OpenSearchPathError!std.Io.Dir { // Validate the search path to avoid possible unreachable on invalid paths, // see https://github.com/ziglang/zig/issues/15607 for why this is currently necessary. try validateSearchPath(path); - return dir.openDir(path, .{}); + return dir.openDir(io, path, .{}); } /// Very crude attempt at validating a path. This is imperfect diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 87c4da9faa..37e72d49e5 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -40,7 +40,7 @@ pub fn main() !void { const zig_exe_path = argv.next().?; const global_cache_path = argv.next().?; - var lib_dir = try Io.Dir.cwd().openDir(zig_lib_directory, .{}); + var lib_dir = try Io.Dir.cwd().openDir(io, zig_lib_directory, .{}); defer lib_dir.close(io); var listen_port: u16 = 0; @@ -206,7 +206,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { }, }); - var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true }); + var std_dir = try context.lib_dir.openDir(io, "std", .{ .iterate = true }); defer std_dir.close(io); var walker = try std_dir.walk(gpa); diff --git a/lib/std/Build.zig b/lib/std/Build.zig index cc2f70fd2f..3d0e8b8dbc 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2184,6 +2184,7 @@ fn dependencyInner( pkg_deps: AvailableDeps, args: anytype, ) *Dependency { + const io = b.graph.io; const user_input_options = userInputOptionsFromArgs(b.allocator, args); if (b.graph.dependency_cache.getContext(.{ .build_root_string = build_root_string, @@ -2193,7 +2194,7 @@ fn dependencyInner( const build_root: std.Build.Cache.Directory = .{ .path = build_root_string, - .handle = Io.Dir.cwd().openDir(build_root_string, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(io, build_root_string, .{}) catch |err| { std.debug.print("unable to open '{s}': {s}\n", .{ build_root_string, @errorName(err), }); diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 60211670de..93e0c0d792 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -71,6 +71,7 @@ pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.File.OpenFlags) pub fn openDir( p: Path, + io: Io, sub_path: []const u8, args: Io.Dir.OpenOptions, ) Io.Dir.OpenError!Io.Dir { @@ -80,7 +81,7 @@ pub fn openDir( p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.openDir(joined_path, args); + return p.root_dir.handle.openDir(io, joined_path, args); } pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir { diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig index 1cdb232770..4c1506aa33 100644 --- a/lib/std/Build/Step/InstallArtifact.zig +++ b/lib/std/Build/Step/InstallArtifact.zig @@ -164,7 +164,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const src_dir_path = dir.source.getPath3(b, step); const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path); - var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { + var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { return step.fail("unable to open source directory '{f}': {s}", .{ src_dir_path, @errorName(err), }); diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 2834f18564..353c85fecf 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -218,7 +218,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const need_derived_inputs = try step.addDirectoryWatchInput(dir.source); const src_dir_path = dir.source.getPath3(b, step); - var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { + var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { return step.fail("unable to open source directory '{f}': {s}", .{ src_dir_path, @errorName(err), }); diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 3b552a556a..9189a4c609 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -234,7 +234,7 @@ pub const SelectiveWalker = struct { return; } - var new_dir = entry.dir.openDir(entry.basename, .{ .iterate = true }) catch |err| { + var new_dir = entry.dir.openDir(io, entry.basename, .{ .iterate = true }) catch |err| { switch (err) { error.NameTooLong => unreachable, else => |e| return e, @@ -1326,7 +1326,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { var treat_as_dir = true; handle_entry: while (true) { if (treat_as_dir) { - break :iterable_dir parent_dir.openDir(name, .{ + break :iterable_dir parent_dir.openDir(io, name, .{ .follow_symlinks = false, .iterate = true, }) catch |err| switch (err) { @@ -1430,7 +1430,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, var treat_as_dir = entry.kind == .directory; handle_entry: while (true) { if (treat_as_dir) { - const new_dir = dir.openDir(entry.name, .{ + const new_dir = dir.openDir(io, entry.name, .{ .follow_symlinks = false, .iterate = true, }) catch |err| switch (err) { @@ -1520,14 +1520,14 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, } /// On successful delete, returns null. -fn deleteTreeOpenInitialSubpath(dir: Dir, sub_path: []const u8, kind_hint: File.Kind) !?Dir { +fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hint: File.Kind) !?Dir { return iterable_dir: { // Treat as a file by default var treat_as_dir = kind_hint == .directory; handle_entry: while (true) { if (treat_as_dir) { - break :iterable_dir dir.openDir(sub_path, .{ + break :iterable_dir dir.openDir(io, sub_path, .{ .follow_symlinks = false, .iterate = true, }) catch |err| switch (err) { diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index d4a9f1e757..1b87c97949 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -180,7 +180,7 @@ pub fn addCertsFromDirPath( dir: Io.Dir, sub_dir_path: []const u8, ) AddCertsFromDirPathError!void { - var iterable_dir = try dir.openDir(sub_dir_path, .{ .iterate = true }); + var iterable_dir = try dir.openDir(io, sub_dir_path, .{ .iterate = true }); defer iterable_dir.close(io); return addCertsFromDir(cb, gpa, io, iterable_dir); } diff --git a/lib/std/crypto/codecs/asn1/test.zig b/lib/std/crypto/codecs/asn1/test.zig index 3dbedb9f80..bdfb47e2df 100644 --- a/lib/std/crypto/codecs/asn1/test.zig +++ b/lib/std/crypto/codecs/asn1/test.zig @@ -73,7 +73,7 @@ test AllTypes { try std.testing.expectEqualSlices(u8, encoded, buf); // Use this to update test file. - // const dir = try Io.Dir.cwd().openDir("lib/std/crypto/asn1", .{}); + // const dir = try Io.Dir.cwd().openDir(io, "lib/std/crypto/asn1", .{}); // var file = try dir.createFile(io, path, .{}); // defer file.close(io); // try file.writeAll(buf); diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index a1801d00d0..b1965b60ee 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -160,9 +160,9 @@ pub const ElfDynLib = struct { fn openPath(path: []const u8, io: Io) !Io.Dir { if (path.len == 0) return error.NotDir; var parts = std.mem.tokenizeScalar(u8, path, '/'); - var parent = if (path[0] == '/') try Io.Dir.cwd().openDir("/", .{}) else Io.Dir.cwd(); + var parent = if (path[0] == '/') try Io.Dir.cwd().openDir(io, "/", .{}) else Io.Dir.cwd(); while (parts.next()) |part| { - const child = try parent.openDir(part, .{}); + const child = try parent.openDir(io, part, .{}); parent.close(io); parent = child; } @@ -184,7 +184,7 @@ pub const ElfDynLib = struct { } fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t { - var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch return null; + var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch return null; defer dir.close(io); return posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index aab86d40a6..9924cafaf8 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -367,7 +367,7 @@ test "openDir" { for ([_][]const u8{ "", ".", ".." }) |sub_path| { const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path }); - var dir = try ctx.dir.openDir(dir_path, .{}); + var dir = try ctx.dir.openDir(io, dir_path, .{}); defer dir.close(io); } } @@ -448,7 +448,7 @@ test "openDirAbsolute" { test "openDir cwd parent '..'" { const io = testing.io; - var dir = Io.Dir.cwd().openDir("..", .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(io, "..", .{}) catch |err| { if (native_os == .wasi and err == error.PermissionDenied) { return; // This is okay. WASI disallows escaping from the fs sandbox } @@ -471,7 +471,7 @@ test "openDir non-cwd parent '..'" { var subdir = try tmp.dir.makeOpenPath("subdir", .{}); defer subdir.close(io); - var dir = try subdir.openDir("..", .{}); + var dir = try subdir.openDir(io, "..", .{}); defer dir.close(io); const expected_path = try tmp.dir.realpathAlloc(testing.allocator, "."); @@ -839,7 +839,7 @@ test "directory operations on files" { file.close(io); try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); - try testing.expectError(error.NotDir, ctx.dir.openDir(test_file_name, .{})); + try testing.expectError(error.NotDir, ctx.dir.openDir(io, test_file_name, .{})); try testing.expectError(error.NotDir, ctx.dir.deleteDir(test_file_name)); if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) { @@ -902,7 +902,7 @@ test "file operations on directories" { } // ensure the directory still exists as a sanity check - var dir = try ctx.dir.openDir(test_dir_name, .{}); + var dir = try ctx.dir.openDir(io, test_dir_name, .{}); dir.close(io); } }.impl); @@ -918,7 +918,7 @@ test "makeOpenPath parent dirs do not exist" { dir.close(io); // double check that the full directory structure was created - var dir_verification = try tmp_dir.dir.openDir("root_dir/parent_dir/some_dir", .{}); + var dir_verification = try tmp_dir.dir.openDir(io, "root_dir/parent_dir/some_dir", .{}); dir_verification.close(io); } @@ -1005,8 +1005,8 @@ test "Dir.rename directories" { try ctx.dir.rename(test_dir_path, test_dir_renamed_path); // Ensure the directory was renamed - try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{})); - var dir = try ctx.dir.openDir(test_dir_renamed_path, .{}); + try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{})); + var dir = try ctx.dir.openDir(io, test_dir_renamed_path, .{}); // Put a file in the directory var file = try dir.createFile(io, "test_file", .{ .read = true }); @@ -1017,8 +1017,8 @@ test "Dir.rename directories" { try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path); // Ensure the directory was renamed and the file still exists in it - try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_renamed_path, .{})); - dir = try ctx.dir.openDir(test_dir_renamed_again_path, .{}); + try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_renamed_path, .{})); + dir = try ctx.dir.openDir(io, test_dir_renamed_again_path, .{}); file = try dir.openFile(io, "test_file", .{}); file.close(io); dir.close(io); @@ -1042,8 +1042,8 @@ test "Dir.rename directory onto empty dir" { try ctx.dir.rename(test_dir_path, target_dir_path); // Ensure the directory was renamed - try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{})); - var dir = try ctx.dir.openDir(target_dir_path, .{}); + try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{})); + var dir = try ctx.dir.openDir(io, target_dir_path, .{}); dir.close(io); } }.impl); @@ -1070,7 +1070,7 @@ test "Dir.rename directory onto non-empty dir" { try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path)); // Ensure the directory was not renamed - var dir = try ctx.dir.openDir(test_dir_path, .{}); + var dir = try ctx.dir.openDir(io, test_dir_path, .{}); dir.close(io); } }.impl); @@ -1165,8 +1165,8 @@ test "renameAbsolute" { ); // ensure the directory was renamed - try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(test_dir_name, .{})); - var dir = try tmp_dir.dir.openDir(renamed_test_dir_name, .{}); + try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(io, test_dir_name, .{})); + var dir = try tmp_dir.dir.openDir(io, renamed_test_dir_name, .{}); dir.close(io); } @@ -1234,6 +1234,7 @@ test "deleteTree on a symlink" { test "makePath, put some files in it, deleteTree" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); @@ -1248,7 +1249,7 @@ test "makePath, put some files in it, deleteTree" { }); try ctx.dir.deleteTree(dir_path); - try testing.expectError(error.FileNotFound, ctx.dir.openDir(dir_path, .{})); + try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, dir_path, .{})); } }.impl); } @@ -1256,6 +1257,7 @@ test "makePath, put some files in it, deleteTree" { test "makePath, put some files in it, deleteTreeMinStackSize" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); @@ -1270,7 +1272,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" { }); try ctx.dir.deleteTreeMinStackSize(dir_path); - try testing.expectError(error.FileNotFound, ctx.dir.openDir(dir_path, .{})); + try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, dir_path, .{})); } }.impl); } @@ -1296,7 +1298,7 @@ test "makePath but sub_path contains pre-existing file" { } fn expectDir(io: Io, dir: Dir, path: []const u8) !void { - var d = try dir.openDir(path, .{}); + var d = try dir.openDir(io, path, .{}); d.close(io); } @@ -1307,7 +1309,7 @@ test "makepath existing directories" { defer tmp.cleanup(); try tmp.dir.makeDir("A"); - var tmpA = try tmp.dir.openDir("A", .{}); + var tmpA = try tmp.dir.openDir(io, "A", .{}); defer tmpA.close(io); try tmpA.makeDir("B"); @@ -1569,7 +1571,7 @@ test "sendfile" { try tmp.dir.makePath("os_test_tmp"); - var dir = try tmp.dir.openDir("os_test_tmp", .{}); + var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); const line1 = "line1\n"; @@ -1616,7 +1618,7 @@ test "sendfile with buffered data" { try tmp.dir.makePath("os_test_tmp"); - var dir = try tmp.dir.openDir("os_test_tmp", .{}); + var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); @@ -1913,7 +1915,7 @@ test "walker" { return err; }; // make sure that the entry.dir is the containing dir - var entry_dir = try entry.dir.openDir(entry.basename, .{}); + var entry_dir = try entry.dir.openDir(io, entry.basename, .{}); defer entry_dir.close(io); num_walked += 1; } @@ -1981,7 +1983,7 @@ test "selective walker, skip entries that start with ." { }; // make sure that the entry.dir is the containing dir - var entry_dir = try entry.dir.openDir(entry.basename, .{}); + var entry_dir = try entry.dir.openDir(io, entry.basename, .{}); defer entry_dir.close(io); num_walked += 1; } @@ -2026,7 +2028,7 @@ test "'.' and '..' in Io.Dir functions" { try ctx.dir.makeDir(subdir_path); try ctx.dir.access(subdir_path, .{}); - var created_subdir = try ctx.dir.openDir(subdir_path, .{}); + var created_subdir = try ctx.dir.openDir(io, subdir_path, .{}); created_subdir.close(io); const created_file = try ctx.dir.createFile(io, file_path, .{}); @@ -2103,7 +2105,7 @@ test "chmod" { try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat()).mode & 0o7777); try tmp.dir.makeDir("test_dir"); - var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); + var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); try dir.chmod(0o700); @@ -2125,7 +2127,7 @@ test "chown" { try tmp.dir.makeDir("test_dir"); - var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); + var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); try dir.chown(null, null); } diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index 0972a302da..167c6ef398 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -3066,6 +3066,8 @@ test "unlinkat" { test "mkdirat" { if (!is_linux) return error.SkipZigTest; + const io = testing.io; + var ring = IoUring.init(1, 0) catch |err| switch (err) { error.SystemOutdated => return error.SkipZigTest, error.PermissionDenied => return error.SkipZigTest, @@ -3104,7 +3106,7 @@ test "mkdirat" { }, cqe); // Validate that the directory exist - _ = try tmp.dir.openDir(path, .{}); + _ = try tmp.dir.openDir(io, path, .{}); } test "symlinkat" { diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index 80317850df..a5c55d3522 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -337,7 +337,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F // search in reverse order const search_path_untrimmed = search_paths.items[search_paths.items.len - path_i - 1]; const search_path = std.mem.trimStart(u8, search_path_untrimmed, " "); - var search_dir = Io.Dir.cwd().openDir(search_path, .{}) catch |err| switch (err) { + var search_dir = Io.Dir.cwd().openDir(io, search_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -392,7 +392,7 @@ fn findNativeIncludeDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); - var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -440,7 +440,7 @@ fn findNativeCrtDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -508,7 +508,7 @@ fn findNativeKernel32LibDir( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(io, result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -544,7 +544,7 @@ fn findNativeMsvcIncludeDir( const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" }); errdefer allocator.free(dir_path); - var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, diff --git a/src/Compilation.zig b/src/Compilation.zig index 5f15ef5f74..ef01fbb07c 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -745,6 +745,7 @@ pub const Directories = struct { /// Uses `std.process.fatal` on error conditions. pub fn init( arena: Allocator, + io: Io, override_zig_lib: ?[]const u8, override_global_cache: ?[]const u8, local_cache_strat: union(enum) { @@ -768,7 +769,7 @@ pub const Directories = struct { }; const zig_lib: Cache.Directory = d: { - if (override_zig_lib) |path| break :d openUnresolved(arena, cwd, path, .@"zig lib"); + if (override_zig_lib) |path| break :d openUnresolved(arena, io, cwd, path, .@"zig lib"); if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib"); break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| { fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); @@ -776,22 +777,22 @@ pub const Directories = struct { }; const global_cache: Cache.Directory = d: { - if (override_global_cache) |path| break :d openUnresolved(arena, cwd, path, .@"global cache"); + if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache"); if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache"); const path = introspect.resolveGlobalCacheDir(arena) catch |err| { fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); }; - break :d openUnresolved(arena, cwd, path, .@"global cache"); + break :d openUnresolved(arena, io, cwd, path, .@"global cache"); }; const local_cache: Cache.Directory = switch (local_cache_strat) { - .override => |path| openUnresolved(arena, cwd, path, .@"local cache"), + .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"), .search => d: { const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| { fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); }; const path = maybe_path orelse break :d global_cache; - break :d openUnresolved(arena, cwd, path, .@"local cache"); + break :d openUnresolved(arena, io, cwd, path, .@"local cache"); }, .global => global_cache, }; @@ -818,13 +819,19 @@ pub const Directories = struct { }, }; } - fn openUnresolved(arena: Allocator, cwd: []const u8, unresolved_path: []const u8, thing: enum { @"zig lib", @"global cache", @"local cache" }) Cache.Directory { + fn openUnresolved( + arena: Allocator, + io: Io, + cwd: []const u8, + unresolved_path: []const u8, + thing: enum { @"zig lib", @"global cache", @"local cache" }, + ) Cache.Directory { const path = introspect.resolvePath(arena, cwd, &.{unresolved_path}) catch |err| { fatal("unable to resolve {s} directory: {s}", .{ @tagName(thing), @errorName(err) }); }; const nonempty_path = if (path.len == 0) "." else path; const handle_or_err = switch (thing) { - .@"zig lib" => Io.Dir.cwd().openDir(nonempty_path, .{}), + .@"zig lib" => Io.Dir.cwd().openDir(io, nonempty_path, .{}), .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}), }; return .{ @@ -5331,7 +5338,7 @@ fn docsCopyModule( const root = module.root; var mod_dir = d: { const root_dir, const sub_path = root.openInfo(comp.dirs); - break :d root_dir.openDir(sub_path, .{ .iterate = true }); + break :d root_dir.openDir(io, sub_path, .{ .iterate = true }); } catch |err| { return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err }); }; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 8a30529bc5..a651107bf5 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -383,7 +383,7 @@ pub fn run(f: *Fetch) RunError!void { }, .remote => |remote| remote, .path_or_url => |path_or_url| { - if (Io.Dir.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| { + if (Io.Dir.cwd().openDir(io, path_or_url, .{ .iterate = true })) |dir| { var resource: Resource = .{ .dir = dir }; return f.runResource(path_or_url, &resource, null); } else |dir_err| { @@ -2311,8 +2311,9 @@ const TestFetchBuilder = struct { } fn packageDir(self: *TestFetchBuilder) !Io.Dir { + const io = self.job_queue.io; const root = self.fetch.package_root; - return try root.root_dir.handle.openDir(root.sub_path, .{ .iterate = true }); + return try root.root_dir.handle.openDir(io, root.sub_path, .{ .iterate = true }); } // Test helper, asserts thet package dir constains expected_files. diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 7b08a89cae..3f0ffb04cd 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -254,7 +254,7 @@ pub const Repository = struct { switch (entry.type) { .directory => { try dir.makeDir(entry.name); - var subdir = try dir.openDir(entry.name, .{}); + var subdir = try dir.openDir(io, entry.name, .{}); defer subdir.close(io); const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name }); defer repository.odb.allocator.free(sub_path); diff --git a/src/fmt.zig b/src/fmt.zig index 36a3833986..dc67619d54 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -186,7 +186,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! error.FileNotFound => continue, // On Windows, statFile does not work for directories error.IsDir => dir: { - var dir = try Io.Dir.cwd().openDir(file_path, .{}); + var dir = try Io.Dir.cwd().openDir(io, file_path, .{}); defer dir.close(io); break :dir try dir.stat(); }, @@ -224,7 +224,7 @@ fn fmtPathDir( ) !void { const io = fmt.io; - var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true }); + var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true }); defer dir.close(io); const stat = try dir.stat(); diff --git a/src/introspect.zig b/src/introspect.zig index 04ddf47e8a..a56a214cbe 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -21,7 +21,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { zig_dir: { // Try lib/zig/std/std.zig const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; - var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir; + var test_zig_dir = base_dir.openDir(io, lib_zig, .{}) catch break :zig_dir; const file = test_zig_dir.openFile(io, test_index_file, .{}) catch { test_zig_dir.close(io); break :zig_dir; @@ -31,7 +31,7 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { } // Try lib/std/std.zig - var test_zig_dir = base_dir.openDir("lib", .{}) catch return null; + var test_zig_dir = base_dir.openDir(io, "lib", .{}) catch return null; const file = test_zig_dir.openFile(io, test_index_file, .{}) catch { test_zig_dir.close(io); return null; @@ -85,7 +85,7 @@ pub fn findZigLibDirFromSelfExe( const cwd = Io.Dir.cwd(); var cur_path: []const u8 = self_exe_path; while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { - var base_dir = cwd.openDir(dirname, .{}) catch continue; + var base_dir = cwd.openDir(io, dirname, .{}) catch continue; defer base_dir.close(io); const sub_directory = testZigInstallPrefix(io, base_dir) orelse continue; diff --git a/src/main.zig b/src/main.zig index 67b7384b57..fe48efa2fd 100644 --- a/src/main.zig +++ b/src/main.zig @@ -713,7 +713,7 @@ const Emit = union(enum) { } else e: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3304,7 +3304,7 @@ fn buildOutputType( } else emit: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3959,14 +3959,14 @@ fn createModule( if (fs.path.isAbsolute(lib_dir_arg)) { const stripped_dir = lib_dir_arg[fs.path.parsePath(lib_dir_arg).root.len..]; const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir }); - addLibDirectoryWarn(&create_module.lib_directories, full_path); + addLibDirectoryWarn(io, &create_module.lib_directories, full_path); } else { - addLibDirectoryWarn(&create_module.lib_directories, lib_dir_arg); + addLibDirectoryWarn(io, &create_module.lib_directories, lib_dir_arg); } } } else { for (create_module.lib_dir_args.items) |lib_dir_arg| { - addLibDirectoryWarn(&create_module.lib_directories, lib_dir_arg); + addLibDirectoryWarn(io, &create_module.lib_directories, lib_dir_arg); } } create_module.lib_dir_args = undefined; // From here we use lib_directories instead. @@ -4002,7 +4002,7 @@ fn createModule( try create_module.rpath_list.appendSlice(arena, paths.rpaths.items); try create_module.lib_directories.ensureUnusedCapacity(arena, paths.lib_dirs.items.len); - for (paths.lib_dirs.items) |path| addLibDirectoryWarn2(&create_module.lib_directories, path, true); + for (paths.lib_dirs.items) |path| addLibDirectoryWarn2(io, &create_module.lib_directories, path, true); } if (create_module.libc_paths_file) |paths_file| { @@ -4026,8 +4026,8 @@ fn createModule( }; } try create_module.lib_directories.ensureUnusedCapacity(arena, 2); - addLibDirectoryWarn(&create_module.lib_directories, create_module.libc_installation.?.msvc_lib_dir.?); - addLibDirectoryWarn(&create_module.lib_directories, create_module.libc_installation.?.kernel32_lib_dir.?); + addLibDirectoryWarn(io, &create_module.lib_directories, create_module.libc_installation.?.msvc_lib_dir.?); + addLibDirectoryWarn(io, &create_module.lib_directories, create_module.libc_installation.?.kernel32_lib_dir.?); } // Destructively mutates but does not transfer ownership of `unresolved_link_inputs`. @@ -5118,7 +5118,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) process.raiseFileDescriptorLimit(); const cwd_path = try introspect.getResolvedCwd(arena); - const build_root = try findBuildRoot(arena, .{ + const build_root = try findBuildRoot(arena, io, .{ .cwd_path = cwd_path, .build_file = build_file, }); @@ -5227,7 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) if (system_pkg_dir_path) |p| { job_queue.global_cache = .{ .path = p, - .handle = Io.Dir.cwd().openDir(p, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(io, p, .{}) catch |err| { fatal("unable to open system package directory '{s}': {s}", .{ p, @errorName(err), }); @@ -7039,7 +7039,7 @@ fn cmdFetch( const cwd_path = try introspect.getResolvedCwd(arena); - var build_root = try findBuildRoot(arena, .{ + var build_root = try findBuildRoot(arena, io, .{ .cwd_path = cwd_path, }); defer build_root.deinit(); @@ -7251,7 +7251,7 @@ const FindBuildRootOptions = struct { cwd_path: ?[]const u8 = null, }; -fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { +fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !BuildRoot { const cwd_path = options.cwd_path orelse try introspect.getResolvedCwd(arena); const build_zig_basename = if (options.build_file) |bf| fs.path.basename(bf) @@ -7260,7 +7260,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { if (options.build_file) |bf| { if (fs.path.dirname(bf)) |dirname| { - const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { + const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| { fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7281,7 +7281,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { while (true) { const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); if (Io.Dir.cwd().access(joined_path, .{})) |_| { - const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { + const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| { fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7464,7 +7464,7 @@ fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates { const s = fs.path.sep_str; const template_sub_path = "init"; - const template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| { + const template_dir = zig_lib_directory.handle.openDir(io, template_sub_path, .{}) catch |err| { const path = zig_lib_directory.path orelse "."; fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ path, s, template_sub_path, @errorName(err), @@ -7581,17 +7581,18 @@ fn anyObjectLinkInputs(link_inputs: []const link.UnresolvedInput) bool { return false; } -fn addLibDirectoryWarn(lib_directories: *std.ArrayList(Directory), path: []const u8) void { - return addLibDirectoryWarn2(lib_directories, path, false); +fn addLibDirectoryWarn(io: Io, lib_directories: *std.ArrayList(Directory), path: []const u8) void { + return addLibDirectoryWarn2(io, lib_directories, path, false); } fn addLibDirectoryWarn2( + io: Io, lib_directories: *std.ArrayList(Directory), path: []const u8, ignore_not_found: bool, ) void { lib_directories.appendAssumeCapacity(.{ - .handle = Io.Dir.cwd().openDir(path, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(io, path, .{}) catch |err| { if (err == error.FileNotFound and ignore_not_found) return; warn("unable to open library directory '{s}': {s}", .{ path, @errorName(err) }); return; -- cgit v1.2.3 From 9f4d40b1f9bffc4137055b8a07f042ecfa398124 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 14:17:52 -0800 Subject: update all stat() to stat(io) --- lib/compiler/objcopy.zig | 2 +- lib/compiler/resinator/utils.zig | 2 +- lib/compiler/std-docs.zig | 2 +- lib/std/Build/Cache.zig | 9 ++++---- lib/std/Build/WebServer.zig | 2 +- lib/std/Io/test.zig | 4 ++-- lib/std/dynamic_library.zig | 2 +- lib/std/fs/test.zig | 22 ++++++++++---------- lib/std/os/linux/IoUring.zig | 6 +++--- lib/std/os/linux/test.zig | 4 ++-- src/Compilation.zig | 2 +- src/Zcu.zig | 2 +- src/Zcu/PerThread.zig | 4 ++-- src/fmt.zig | 6 +++--- src/link.zig | 6 +++--- src/link/Elf.zig | 5 +++-- src/link/Elf/Archive.zig | 45 +++++++++++++++++++++------------------- src/link/Elf/Object.zig | 7 +++++-- src/link/MachO.zig | 3 ++- src/link/MachO/Archive.zig | 3 ++- src/link/MachO/Object.zig | 4 +++- src/link/MachO/relocatable.zig | 2 +- src/link/tapi.zig | 4 ++-- 23 files changed, 80 insertions(+), 68 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index e48f76a6a6..6473a10dd0 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -155,7 +155,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void const input_file = Io.Dir.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); defer input_file.close(io); - const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); + const stat = input_file.stat(io) catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); var in: File.Reader = .initSize(input_file, io, &input_buffer, stat.size); diff --git a/lib/compiler/resinator/utils.zig b/lib/compiler/resinator/utils.zig index 3f03b73c54..285342ad74 100644 --- a/lib/compiler/resinator/utils.zig +++ b/lib/compiler/resinator/utils.zig @@ -38,7 +38,7 @@ pub fn openFileNotDir( errdefer file.close(io); // https://github.com/ziglang/zig/issues/5732 if (builtin.os.tag != .windows) { - const stat = try file.stat(); + const stat = try file.stat(io); if (stat.kind == .directory) return error.IsDir; diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 37e72d49e5..d5beab5f17 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -227,7 +227,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { } var file = try entry.dir.openFile(io, entry.basename, .{}); defer file.close(io); - const stat = try file.stat(); + const stat = try file.stat(io); var file_reader: std.Io.File.Reader = .{ .file = file, .interface = std.Io.File.Reader.initInterface(&.{}), diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index fdcb2ab714..0176d71a1c 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -775,7 +775,7 @@ pub const Manifest = struct { }; defer this_file.close(io); - const actual_stat = this_file.stat() catch |err| { + const actual_stat = this_file.stat(io) catch |err| { self.diagnostic = .{ .file_stat = .{ .file_index = idx, .err = err, @@ -883,7 +883,7 @@ pub const Manifest = struct { defer file.close(io); // Save locally and also save globally (we still hold the global lock). - const stat = file.stat() catch |err| switch (err) { + const stat = file.stat(io) catch |err| switch (err) { error.Canceled => return error.Canceled, else => return true, }; @@ -909,7 +909,8 @@ pub const Manifest = struct { } fn populateFileHashHandle(self: *Manifest, ch_file: *File, handle: Io.File) !void { - const actual_stat = try handle.stat(); + const io = self.cache.io; + const actual_stat = try handle.stat(io); ch_file.stat = .{ .size = actual_stat.size, .mtime = actual_stat.mtime, @@ -1333,7 +1334,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { dir.deleteFile(test_out_file) catch {}; } - return (try file.stat()).mtime; + return (try file.stat(io)).mtime; } test "cache file and then recall it" { diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index 9938d5e1b0..472e87b05a 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -509,7 +509,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons continue; }; defer file.close(io); - const stat = try file.stat(); + const stat = try file.stat(io); var read_buffer: [1024]u8 = undefined; var file_reader: Io.File.Reader = .initSize(file, io, &read_buffer, stat.size); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index e731dc18d7..8b9d714ee8 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -124,13 +124,13 @@ test "updateTimes" { var file = try tmp.dir.createFile(io, tmp_file_name, .{ .read = true }); defer file.close(io); - const stat_old = try file.stat(); + const stat_old = try file.stat(io); // Set atime and mtime to 5s before try file.updateTimes( stat_old.atime.subDuration(.fromSeconds(5)), stat_old.mtime.subDuration(.fromSeconds(5)), ); - const stat_new = try file.stat(); + const stat_new = try file.stat(io); try expect(stat_new.atime.nanoseconds < stat_old.atime.nanoseconds); try expect(stat_new.mtime.nanoseconds < stat_old.mtime.nanoseconds); } diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index b1965b60ee..f02caa1f5b 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -226,7 +226,7 @@ pub const ElfDynLib = struct { defer posix.close(fd); const file: Io.File = .{ .handle = fd }; - const stat = try file.stat(); + const stat = try file.stat(io); const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig; const page_size = std.heap.pageSize(); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 9924cafaf8..7b12ba4271 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -350,7 +350,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { }; defer symlink.close(io); - const stat = try symlink.stat(); + const stat = try symlink.stat(io); try testing.expectEqual(File.Kind.sym_link, stat.kind); } }.impl); @@ -396,7 +396,7 @@ test "openDirAbsolute" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const tmp_ino = (try tmp.dir.stat()).inode; + const tmp_ino = (try tmp.dir.stat(io)).inode; try tmp.dir.makeDir("subdir"); const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir"); @@ -406,7 +406,7 @@ test "openDirAbsolute" { var tmp_sub = try fs.openDirAbsolute(sub_path, .{}); defer tmp_sub.close(io); - const sub_ino = (try tmp_sub.stat()).inode; + const sub_ino = (try tmp_sub.stat(io)).inode; { // Can open sub_path + ".." @@ -416,7 +416,7 @@ test "openDirAbsolute" { var dir = try fs.openDirAbsolute(dir_path, .{}); defer dir.close(io); - const ino = (try dir.stat()).inode; + const ino = (try dir.stat(io)).inode; try testing.expectEqual(tmp_ino, ino); } @@ -428,7 +428,7 @@ test "openDirAbsolute" { var dir = try fs.openDirAbsolute(dir_path, .{}); defer dir.close(io); - const ino = (try dir.stat()).inode; + const ino = (try dir.stat(io)).inode; try testing.expectEqual(sub_ino, ino); } @@ -440,7 +440,7 @@ test "openDirAbsolute" { var dir = try fs.openDirAbsolute(dir_path, .{}); defer dir.close(io); - const ino = (try dir.stat()).inode; + const ino = (try dir.stat(io)).inode; try testing.expectEqual(tmp_ino, ino); } } @@ -849,7 +849,7 @@ test "directory operations on files" { // ensure the file still exists and is a file as a sanity check file = try ctx.dir.openFile(io, test_file_name, .{}); - const stat = try file.stat(); + const stat = try file.stat(io); try testing.expectEqual(File.Kind.file, stat.kind); file.close(io); } @@ -1151,7 +1151,7 @@ test "renameAbsolute" { // ensure the file was renamed try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(io, test_file_name, .{})); file = try tmp_dir.dir.openFile(io, renamed_test_file_name, .{}); - const stat = try file.stat(); + const stat = try file.stat(io); try testing.expectEqual(File.Kind.file, stat.kind); file.close(io); @@ -2099,17 +2099,17 @@ test "chmod" { const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 }); defer file.close(io); - try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777); + try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat(io)).mode & 0o7777); try file.chmod(0o644); - try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat()).mode & 0o7777); + try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat(io)).mode & 0o7777); try tmp.dir.makeDir("test_dir"); var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); try dir.chmod(0o700); - try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat()).mode & 0o7777); + try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat(io)).mode & 0o7777); } test "chown" { diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index 167c6ef398..3c9a313a4a 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -2655,7 +2655,7 @@ test "fallocate" { const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); - try testing.expectEqual(@as(u64, 0), (try file.stat()).size); + try testing.expectEqual(@as(u64, 0), (try file.stat(io)).size); const len: u64 = 65536; const sqe = try ring.fallocate(0xaaaaaaaa, file.handle, 0, 0, len); @@ -2681,7 +2681,7 @@ test "fallocate" { .flags = 0, }, cqe); - try testing.expectEqual(len, (try file.stat()).size); + try testing.expectEqual(len, (try file.stat(io)).size); } test "statx" { @@ -2702,7 +2702,7 @@ test "statx" { const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); - try testing.expectEqual(@as(u64, 0), (try file.stat()).size); + try testing.expectEqual(@as(u64, 0), (try file.stat(io)).size); try file.writeAll("foobar"); diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index d7cfb4e138..cfafebe826 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -21,7 +21,7 @@ test "fallocate" { const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); - try expect((try file.stat()).size == 0); + try expect((try file.stat(io)).size == 0); const len: i64 = 65536; switch (linux.errno(linux.fallocate(file.handle, 0, 0, len))) { @@ -31,7 +31,7 @@ test "fallocate" { else => |errno| std.debug.panic("unhandled errno: {}", .{errno}), } - try expect((try file.stat()).size == len); + try expect((try file.stat(io)).size == len); } test "getpid" { diff --git a/src/Compilation.zig b/src/Compilation.zig index ef01fbb07c..3a48705880 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5367,7 +5367,7 @@ fn docsCopyModule( }); }; defer file.close(io); - const stat = try file.stat(); + const stat = try file.stat(io); var file_reader: Io.File.Reader = .initSize(file, io, &buffer, stat.size); archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime) catch |err| { diff --git a/src/Zcu.zig b/src/Zcu.zig index d2634a8962..1f2fe89236 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1080,7 +1080,7 @@ pub const File = struct { }; defer f.close(io); - const stat = f.stat() catch |err| switch (err) { + const stat = f.stat(io) catch |err| switch (err) { error.Streaming => { // Since `file.stat` is populated, this was previously a file stream; since it is // now not a file stream, it must have changed. diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 9a75b2096e..74196705c3 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -98,7 +98,7 @@ pub fn updateFile( }; defer source_file.close(io); - const stat = try source_file.stat(); + const stat = try source_file.stat(io); const want_local_cache = switch (file.path.root) { .none, .local_cache => true, @@ -2470,7 +2470,7 @@ fn updateEmbedFileInner( }; defer file.close(io); - const stat: Cache.File.Stat = .fromFs(try file.stat()); + const stat: Cache.File.Stat = .fromFs(try file.stat(io)); if (ef.val != .none) { const old_stat = ef.stat; diff --git a/src/fmt.zig b/src/fmt.zig index dc67619d54..1a1e5298e2 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -188,7 +188,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! error.IsDir => dir: { var dir = try Io.Dir.cwd().openDir(io, file_path, .{}); defer dir.close(io); - break :dir try dir.stat(); + break :dir try dir.stat(io); }, else => |e| return e, }; @@ -227,7 +227,7 @@ fn fmtPathDir( var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true }); defer dir.close(io); - const stat = try dir.stat(); + const stat = try dir.stat(io); if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; var dir_it = dir.iterate(); @@ -266,7 +266,7 @@ fn fmtPathFile( var file_closed = false; errdefer if (!file_closed) source_file.close(io); - const stat = try source_file.stat(); + const stat = try source_file.stat(io); if (stat.kind == .directory) return error.IsDir; diff --git a/src/link.zig b/src/link.zig index 073ec632c6..06d18ec2d5 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1112,10 +1112,10 @@ pub const File = struct { fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: Io.File) anyerror!void { const comp = base.comp; + const io = comp.io; const diags = &comp.link_diags; const gpa = comp.gpa; - const io = comp.io; - const stat = try file.stat(); + const stat = try file.stat(io); const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig; const buf = try gpa.alloc(u8, size); defer gpa.free(buf); @@ -2180,7 +2180,7 @@ fn resolvePathInputLib( // Appears to be an ELF or archive file. return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); } - const stat = file.stat() catch |err| + const stat = file.stat(io) catch |err| fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) }); const size = std.math.cast(u32, stat.size) orelse fatal("{f}: linker script too big", .{test_path}); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 53812a37ec..13a624a295 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -742,7 +742,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { .dso_exact => @panic("TODO"), .object => |obj| try parseObject(self, obj), .archive => |obj| try parseArchive(gpa, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib), - .dso => |dso| try parseDso(gpa, diags, dso, &self.shared_objects, &self.files, target), + .dso => |dso| try parseDso(gpa, io, diags, dso, &self.shared_objects, &self.files, target), } } @@ -1136,6 +1136,7 @@ fn parseArchive( fn parseDso( gpa: Allocator, + io: Io, diags: *Diags, dso: link.Input.Dso, shared_objects: *std.StringArrayHashMapUnmanaged(File.Index), @@ -1147,7 +1148,7 @@ fn parseDso( const handle = dso.file; - const stat = Stat.fromFs(try handle.stat()); + const stat = Stat.fromFs(try handle.stat(io)); var header = try SharedObject.parseHeader(gpa, diags, dso.path, handle, stat, target); defer header.deinit(gpa); diff --git a/src/link/Elf/Archive.zig b/src/link/Elf/Archive.zig index a9961bf8f9..0f786c1a47 100644 --- a/src/link/Elf/Archive.zig +++ b/src/link/Elf/Archive.zig @@ -1,3 +1,21 @@ +const Archive = @This(); + +const std = @import("std"); +const Io = std.Io; +const assert = std.debug.assert; +const elf = std.elf; +const fs = std.fs; +const log = std.log.scoped(.link); +const mem = std.mem; +const Path = std.Build.Cache.Path; +const Allocator = std.mem.Allocator; + +const Diags = @import("../../link.zig").Diags; +const Elf = @import("../Elf.zig"); +const File = @import("file.zig").File; +const Object = @import("Object.zig"); +const StringTable = @import("../StringTable.zig"); + objects: []const Object, /// '\n'-delimited strtab: []const u8, @@ -10,6 +28,7 @@ pub fn deinit(a: *Archive, gpa: Allocator) void { pub fn parse( gpa: Allocator, + io: Io, diags: *Diags, file_handles: *const std.ArrayList(File.Handle), path: Path, @@ -25,7 +44,7 @@ pub fn parse( pos += magic_buffer.len; } - const size = (try handle.stat()).size; + const size = (try handle.stat(io)).size; var objects: std.ArrayList(Object) = .empty; defer objects.deinit(gpa); @@ -120,7 +139,7 @@ pub fn setArHdr(opts: struct { @memset(mem.asBytes(&hdr), 0x20); { - var writer: std.Io.Writer = .fixed(&hdr.ar_name); + var writer: Io.Writer = .fixed(&hdr.ar_name); switch (opts.name) { .symtab => writer.print("{s}", .{elf.SYM64NAME}) catch unreachable, .strtab => writer.print("//", .{}) catch unreachable, @@ -133,7 +152,7 @@ pub fn setArHdr(opts: struct { hdr.ar_gid[0] = '0'; hdr.ar_mode[0] = '0'; { - var writer: std.Io.Writer = .fixed(&hdr.ar_size); + var writer: Io.Writer = .fixed(&hdr.ar_size); writer.print("{d}", .{opts.size}) catch unreachable; } hdr.ar_fmag = elf.ARFMAG.*; @@ -206,7 +225,7 @@ pub const ArSymtab = struct { ar: ArSymtab, elf_file: *Elf, - fn default(f: Format, writer: *std.Io.Writer) std.Io.Writer.Error!void { + fn default(f: Format, writer: *Io.Writer) Io.Writer.Error!void { const ar = f.ar; const elf_file = f.elf_file; for (ar.symtab.items, 0..) |entry, i| { @@ -261,7 +280,7 @@ pub const ArStrtab = struct { try writer.writeAll(ar.buffer.items); } - pub fn format(ar: ArStrtab, writer: *std.Io.Writer) std.Io.Writer.Error!void { + pub fn format(ar: ArStrtab, writer: *Io.Writer) Io.Writer.Error!void { try writer.print("{f}", .{std.ascii.hexEscape(ar.buffer.items, .lower)}); } }; @@ -277,19 +296,3 @@ pub const ArState = struct { /// Total size of the contributing object (excludes ar_hdr). size: u64 = 0, }; - -const std = @import("std"); -const assert = std.debug.assert; -const elf = std.elf; -const fs = std.fs; -const log = std.log.scoped(.link); -const mem = std.mem; -const Path = std.Build.Cache.Path; -const Allocator = std.mem.Allocator; - -const Diags = @import("../../link.zig").Diags; -const Archive = @This(); -const Elf = @import("../Elf.zig"); -const File = @import("file.zig").File; -const Object = @import("Object.zig"); -const StringTable = @import("../StringTable.zig"); diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index c0dde4176a..7dacfb3a62 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -122,13 +122,14 @@ pub fn parse( pub fn parseCommon( self: *Object, gpa: Allocator, + io: Io, diags: *Diags, path: Path, handle: Io.File, target: *const std.Target, ) !void { const offset = if (self.archive) |ar| ar.offset else 0; - const file_size = (try handle.stat()).size; + const file_size = (try handle.stat(io)).size; const header_buffer = try Elf.preadAllAlloc(gpa, handle, offset, @sizeOf(elf.Elf64_Ehdr)); defer gpa.free(header_buffer); @@ -1122,9 +1123,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf } pub fn updateArSize(self: *Object, elf_file: *Elf) !void { + const comp = elf_file.base.comp; + const io = comp.io; self.output_ar_state.size = if (self.archive) |ar| ar.size else size: { const handle = elf_file.fileHandle(self.file_handle); - break :size (try handle.stat()).size; + break :size (try handle.stat(io)).size; }; } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 0f6127e10e..78e035e2ad 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -925,6 +925,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u const comp = self.base.comp; const gpa = comp.gpa; + const io = comp.io; const abs_path = try std.fs.path.resolvePosix(gpa, &.{ comp.dirs.cwd, @@ -934,7 +935,7 @@ fn addObject(self: *MachO, path: Path, handle_index: File.HandleIndex, offset: u errdefer gpa.free(abs_path); const file = self.getFileHandle(handle_index); - const stat = try file.stat(); + const stat = try file.stat(io); const mtime = stat.mtime.toSeconds(); const index: File.Index = @intCast(try self.files.addOne(gpa)); self.files.set(index, .{ .object = .{ diff --git a/src/link/MachO/Archive.zig b/src/link/MachO/Archive.zig index d1962412c4..122a408533 100644 --- a/src/link/MachO/Archive.zig +++ b/src/link/MachO/Archive.zig @@ -6,6 +6,7 @@ pub fn deinit(self: *Archive, allocator: Allocator) void { pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File.HandleIndex, fat_arch: ?fat.Arch) !void { const comp = macho_file.base.comp; + const io = comp.io; const gpa = comp.gpa; const diags = &comp.link_diags; @@ -14,7 +15,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File const handle = macho_file.getFileHandle(handle_index); const offset = if (fat_arch) |ar| ar.offset else 0; - const end_pos = if (fat_arch) |ar| offset + ar.size else (try handle.stat()).size; + const end_pos = if (fat_arch) |ar| offset + ar.size else (try handle.stat(io)).size; var pos: usize = offset + SARMAG; while (true) { diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 5fc77fe763..1a1799f551 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -1689,9 +1689,11 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M } pub fn updateArSize(self: *Object, macho_file: *MachO) !void { + const comp = macho_file.base.comp; + const io = comp.io; self.output_ar_state.size = if (self.in_archive) |ar| ar.size else size: { const file = macho_file.getFileHandle(self.file_handle); - break :size (try file.stat()).size; + break :size (try file.stat(io)).size; }; } diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index 0f42442640..e9f78a8ef2 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -22,7 +22,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat const path = positionals.items[0].path().?; const in_file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err| return diags.fail("failed to open {f}: {s}", .{ path, @errorName(err) }); - const stat = in_file.stat() catch |err| + const stat = in_file.stat(io) catch |err| return diags.fail("failed to stat {f}: {s}", .{ path, @errorName(err) }); const amt = in_file.copyRangeAll(0, macho_file.base.file.?, 0, stat.size) catch |err| return diags.fail("failed to copy range of file {f}: {s}", .{ path, @errorName(err) }); diff --git a/src/link/tapi.zig b/src/link/tapi.zig index fff25b7544..046f43eae2 100644 --- a/src/link/tapi.zig +++ b/src/link/tapi.zig @@ -139,9 +139,9 @@ pub const LibStub = struct { /// Typed contents of the tbd file. inner: []Tbd, - pub fn loadFromFile(allocator: Allocator, file: Io.File) TapiError!LibStub { + pub fn loadFromFile(allocator: Allocator, io: Io, file: Io.File) TapiError!LibStub { const filesize = blk: { - const stat = file.stat() catch break :blk std.math.maxInt(u32); + const stat = file.stat(io) catch break :blk std.math.maxInt(u32); break :blk @min(stat.size, std.math.maxInt(u32)); }; const source = try allocator.alloc(u8, filesize); -- cgit v1.2.3 From 9ccd68de0b79c3723bd11071fd836bc24ff25b33 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 16:13:51 -0800 Subject: std: move abort and exit from posix into process and delete the unit tests that called fork() no forking allowed in the std lib, including unit tests, except to implement child process spawning. --- lib/compiler/translate-c/main.zig | 2 +- lib/std/Build.zig | 9 ++-- lib/std/Build/Cache/Path.zig | 4 +- lib/std/Build/Step/ConfigHeader.zig | 3 +- lib/std/Build/Step/ObjCopy.zig | 3 +- lib/std/Build/Step/Run.zig | 7 +-- lib/std/Build/Step/UpdateSourceFiles.zig | 2 +- lib/std/Build/Step/WriteFile.zig | 6 +-- lib/std/debug.zig | 12 +++-- lib/std/fs/test.zig | 45 ++++++++++------- lib/std/os/linux/IoUring.zig | 26 ---------- lib/std/posix.zig | 87 -------------------------------- lib/std/posix/test.zig | 67 ------------------------ lib/std/process.zig | 86 ++++++++++++++++++++++++++++++- lib/std/process/Child.zig | 2 +- lib/std/start.zig | 6 +-- lib/std/tar.zig | 16 +++--- lib/std/zip.zig | 6 +-- src/Compilation.zig | 10 ++-- src/Package/Fetch.zig | 5 +- src/main.zig | 11 ++-- 21 files changed, 167 insertions(+), 248 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index d0a873fd78..d140145032 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -253,7 +253,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration if (d.output_name) |path| blk: { if (std.mem.eql(u8, path, "-")) break :blk; if (std.fs.path.dirname(path)) |dirname| { - Io.Dir.cwd().makePath(dirname) catch |err| + Io.Dir.cwd().makePath(io, dirname) catch |err| return d.fatal("failed to create path to '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); } out_file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| { diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 3d0e8b8dbc..1eff8813e5 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1706,7 +1706,7 @@ pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Di var src_file = cwd.createFile(io, dest_path, .{}) catch |err| switch (err) { error.FileNotFound => blk: { if (fs.path.dirname(dest_path)) |dirname| { - try cwd.makePath(dirname); + try cwd.makePath(io, dirname); } break :blk try cwd.createFile(io, dest_path, .{}); }, @@ -2634,13 +2634,12 @@ pub const InstallDir = union(enum) { /// source of API breakage in the future, so keep that in mind when using this /// function. pub fn makeTempPath(b: *Build) []const u8 { + const io = b.graph.io; const rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); const result_path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch @panic("OOM"); - b.cache_root.handle.makePath(tmp_dir_sub_path) catch |err| { - std.debug.print("unable to make tmp path '{s}': {s}\n", .{ - result_path, @errorName(err), - }); + b.cache_root.handle.makePath(io, tmp_dir_sub_path) catch |err| { + std.debug.print("unable to make tmp path '{s}': {t}\n", .{ result_path, err }); }; return result_path; } diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 93e0c0d792..941948a9cd 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -128,14 +128,14 @@ pub fn access(p: Path, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void return p.root_dir.handle.access(joined_path, flags); } -pub fn makePath(p: Path, sub_path: []const u8) !void { +pub fn makePath(p: Path, io: Io, sub_path: []const u8) !void { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.makePath(joined_path); + return p.root_dir.handle.makePath(io, joined_path); } pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 { diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index ea7d9d99ff..f377959610 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -184,6 +184,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const gpa = b.allocator; const arena = b.allocator; + const io = b.graph.io; var man = b.graph.cache.obtain(); defer man.deinit(); @@ -257,7 +258,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path }); const sub_path_dirname = std.fs.path.dirname(sub_path).?; - b.cache_root.handle.makePath(sub_path_dirname) catch |err| { + b.cache_root.handle.makePath(io, sub_path_dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, sub_path_dirname, @errorName(err), }); diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index 4aa1c0a9dc..b81f59b9a1 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -143,6 +143,7 @@ pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath { fn make(step: *Step, options: Step.MakeOptions) !void { const prog_node = options.progress_node; const b = step.owner; + const io = b.graph.io; const objcopy: *ObjCopy = @fieldParentPtr("step", step); try step.singleUnchangingWatchInput(objcopy.input_file); @@ -176,7 +177,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const cache_path = "o" ++ fs.path.sep_str ++ digest; const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, objcopy.basename }); const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{objcopy.basename}) }); - b.cache_root.handle.makePath(cache_path) catch |err| { + b.cache_root.handle.makePath(io, cache_path) catch |err| { return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) }); }; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index af6bc20438..54e77bd614 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -973,7 +973,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .output_directory => output_sub_path, else => unreachable, }; - b.cache_root.handle.makePath(output_sub_dir_path) catch |err| { + b.cache_root.handle.makePath(io, output_sub_dir_path) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, output_sub_dir_path, @errorName(err), }); @@ -1005,7 +1005,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .output_directory => output_sub_path, else => unreachable, }; - b.cache_root.handle.makePath(output_sub_dir_path) catch |err| { + b.cache_root.handle.makePath(io, output_sub_dir_path) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, output_sub_dir_path, @errorName(err), }); @@ -1241,6 +1241,7 @@ fn runCommand( const b = step.owner; const arena = b.allocator; const gpa = options.gpa; + const io = b.graph.io; const cwd: ?[]const u8 = if (run.cwd) |lazy_cwd| lazy_cwd.getPath2(b, step) else null; @@ -1470,7 +1471,7 @@ fn runCommand( const sub_path = b.pathJoin(&output_components); const sub_path_dirname = fs.path.dirname(sub_path).?; - b.cache_root.handle.makePath(sub_path_dirname) catch |err| { + b.cache_root.handle.makePath(io, sub_path_dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, sub_path_dirname, @errorName(err), }); diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig index f5d95182e9..44c6ae1ed4 100644 --- a/lib/std/Build/Step/UpdateSourceFiles.zig +++ b/lib/std/Build/Step/UpdateSourceFiles.zig @@ -78,7 +78,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { var any_miss = false; for (usf.output_source_files.items) |output_source_file| { if (fs.path.dirname(output_source_file.sub_path)) |dirname| { - b.build_root.handle.makePath(dirname) catch |err| { + b.build_root.handle.makePath(io, dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {t}", .{ b.build_root, dirname, err }); }; } diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 85dc9b3fa2..21346959e7 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -268,7 +268,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { for (write_file.files.items) |file| { if (fs.path.dirname(file.sub_path)) |dirname| { - cache_dir.makePath(dirname) catch |err| { + cache_dir.makePath(io, dirname) catch |err| { return step.fail("unable to make path '{f}{s}{c}{s}': {t}", .{ b.cache_root, cache_path, fs.path.sep, dirname, err, }); @@ -303,7 +303,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const dest_dirname = dir.sub_path; if (dest_dirname.len != 0) { - cache_dir.makePath(dest_dirname) catch |err| { + cache_dir.makePath(io, dest_dirname) catch |err| { return step.fail("unable to make path '{f}{s}{c}{s}': {s}", .{ b.cache_root, cache_path, fs.path.sep, dest_dirname, @errorName(err), }); @@ -318,7 +318,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const src_entry_path = try src_dir_path.join(arena, entry.path); const dest_path = b.pathJoin(&.{ dest_dirname, entry.path }); switch (entry.kind) { - .directory => try cache_dir.makePath(dest_path), + .directory => try cache_dir.makePath(io, dest_path), .file => { const prev_status = Io.Dir.updateFile( src_entry_path.root_dir.handle, diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 5df0eef2d5..7ede172d86 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -522,7 +522,7 @@ pub fn defaultPanic( } @trap(); }, - .cuda, .amdhsa => std.posix.abort(), + .cuda, .amdhsa => std.process.abort(), .plan9 => { var status: [std.os.plan9.ERRMAX]u8 = undefined; const len = @min(msg.len, status.len - 1); @@ -575,12 +575,13 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - File.stderr().writeStreamingAll("aborting due to recursive panic\n") catch {}; + const stderr, _ = lockStderrWriter(&.{}); + stderr.writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } - posix.abort(); + std.process.abort(); } /// Must be called only after adding 1 to `panicking`. There are three callsites. @@ -1596,7 +1597,8 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex // A segfault happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - File.stderr().writeAll("aborting due to recursive panic\n") catch {}; + const stderr, _ = lockStderrWriter(&.{}); + stderr().writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } @@ -1604,7 +1606,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex // We cannot allow the signal handler to return because when it runs the original instruction // again, the memory may be mapped and undefined behavior would occur rather than repeating // the segfault. So we simply abort here. - posix.abort(); + std.process.abort(); } pub fn dumpStackPointerAddr(prefix: []const u8) void { diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index e044a97620..bc84500419 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -674,7 +674,7 @@ test "Dir.Iterator but dir is deleted during iteration" { var iterator = subdir.iterate(); // Create something to iterate over within the subdir - try tmp.dir.makePath("subdir" ++ fs.path.sep_str ++ "b"); + try tmp.dir.makePath(io, "subdir" ++ fs.path.sep_str ++ "b"); // Then, before iterating, delete the directory that we're iterating. // This is a contrived reproduction, but this could happen outside of the program, in another thread, etc. @@ -1196,7 +1196,7 @@ test "deleteTree does not follow symlinks" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath("b"); + try tmp.dir.makePath(io, "b"); { var a = try tmp.dir.makeOpenPath("a", .{}); defer a.close(io); @@ -1211,6 +1211,8 @@ test "deleteTree does not follow symlinks" { } test "deleteTree on a symlink" { + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); @@ -1223,7 +1225,7 @@ test "deleteTree on a symlink" { try tmp.dir.access("file", .{}); // Symlink to a directory - try tmp.dir.makePath("dir"); + try tmp.dir.makePath(io, "dir"); try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true }); try tmp.dir.deleteTree("dirlink"); @@ -1238,7 +1240,7 @@ test "makePath, put some files in it, deleteTree" { const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); - try ctx.dir.makePath(try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); + try ctx.dir.makePath(io, try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); try ctx.dir.writeFile(.{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", @@ -1261,7 +1263,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" { const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); - try ctx.dir.makePath(try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); + try ctx.dir.makePath(io, try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); try ctx.dir.writeFile(.{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", @@ -1280,21 +1282,25 @@ test "makePath, put some files in it, deleteTreeMinStackSize" { test "makePath in a directory that no longer exists" { if (native_os == .windows) return error.SkipZigTest; // Windows returns FileBusy if attempting to remove an open dir + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); try tmp.parent_dir.deleteTree(&tmp.sub_path); - try testing.expectError(error.FileNotFound, tmp.dir.makePath("sub-path")); + try testing.expectError(error.FileNotFound, tmp.dir.makePath(io, "sub-path")); } test "makePath but sub_path contains pre-existing file" { + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); try tmp.dir.makeDir("foo"); try tmp.dir.writeFile(.{ .sub_path = "foo/bar", .data = "" }); - try testing.expectError(error.NotDir, tmp.dir.makePath("foo/bar/baz")); + try testing.expectError(error.NotDir, tmp.dir.makePath(io, "foo/bar/baz")); } fn expectDir(io: Io, dir: Dir, path: []const u8) !void { @@ -1314,7 +1320,7 @@ test "makepath existing directories" { try tmpA.makeDir("B"); const testPath = "A" ++ fs.path.sep_str ++ "B" ++ fs.path.sep_str ++ "C"; - try tmp.dir.makePath(testPath); + try tmp.dir.makePath(io, testPath); try expectDir(io, tmp.dir, testPath); } @@ -1328,7 +1334,7 @@ test "makepath through existing valid symlink" { try tmp.dir.makeDir("realfolder"); try setupSymlink(tmp.dir, "." ++ fs.path.sep_str ++ "realfolder", "working-symlink", .{}); - try tmp.dir.makePath("working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); + try tmp.dir.makePath(io, "working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); try expectDir(io, tmp.dir, "realfolder" ++ fs.path.sep_str ++ "in-realfolder"); } @@ -1344,7 +1350,7 @@ test "makepath relative walks" { }); defer testing.allocator.free(relPath); - try tmp.dir.makePath(relPath); + try tmp.dir.makePath(io, relPath); // How .. is handled is different on Windows than non-Windows switch (native_os) { @@ -1383,7 +1389,7 @@ test "makepath ignores '.'" { }); defer testing.allocator.free(expectedPath); - try tmp.dir.makePath(dotPath); + try tmp.dir.makePath(io, dotPath); try expectDir(io, tmp.dir, expectedPath); } @@ -1550,10 +1556,11 @@ test "setEndPos" { test "access file" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const dir_path = try ctx.transformPath("os_test_tmp"); const file_path = try ctx.transformPath("os_test_tmp" ++ fs.path.sep_str ++ "file.txt"); - try ctx.dir.makePath(dir_path); + try ctx.dir.makePath(io, dir_path); try testing.expectError(error.FileNotFound, ctx.dir.access(file_path, .{})); try ctx.dir.writeFile(.{ .sub_path = file_path, .data = "" }); @@ -1569,7 +1576,7 @@ test "sendfile" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath("os_test_tmp"); + try tmp.dir.makePath(io, "os_test_tmp"); var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); @@ -1616,7 +1623,7 @@ test "sendfile with buffered data" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath("os_test_tmp"); + try tmp.dir.makePath(io, "os_test_tmp"); var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); @@ -1894,7 +1901,7 @@ test "walker" { }); for (expected_paths.keys()) |key| { - try tmp.dir.makePath(key); + try tmp.dir.makePath(io, key); } var walker = try tmp.dir.walk(testing.allocator); @@ -1956,7 +1963,7 @@ test "selective walker, skip entries that start with ." { }); for (paths_to_create) |path| { - try tmp.dir.makePath(path); + try tmp.dir.makePath(io, path); } var walker = try tmp.dir.walkSelectively(testing.allocator); @@ -1991,6 +1998,8 @@ test "selective walker, skip entries that start with ." { } test "walker without fully iterating" { + const io = testing.io; + var tmp = tmpDir(.{ .iterate = true }); defer tmp.cleanup(); @@ -2000,8 +2009,8 @@ test "walker without fully iterating" { // Create 2 directories inside the tmp directory, but then only iterate once before breaking. // This ensures that walker doesn't try to close the initial directory when not fully iterating. - try tmp.dir.makePath("a"); - try tmp.dir.makePath("b"); + try tmp.dir.makePath(io, "a"); + try tmp.dir.makePath(io, "b"); var num_walked: usize = 0; while (try walker.next()) |_| { diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index 3c9a313a4a..72b8369d68 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -4090,32 +4090,6 @@ test "openat_direct/close_direct" { try ring.unregister_files(); } -test "waitid" { - try skipKernelLessThan(.{ .major = 6, .minor = 7, .patch = 0 }); - - var ring = IoUring.init(16, 0) catch |err| switch (err) { - error.SystemOutdated => return error.SkipZigTest, - error.PermissionDenied => return error.SkipZigTest, - else => return err, - }; - defer ring.deinit(); - - const pid = try posix.fork(); - if (pid == 0) { - posix.exit(7); - } - - var siginfo: posix.siginfo_t = undefined; - _ = try ring.waitid(0, .PID, pid, &siginfo, posix.W.EXITED, 0); - - try testing.expectEqual(1, try ring.submit()); - - const cqe_waitid = try ring.copy_cqe(); - try testing.expectEqual(0, cqe_waitid.res); - try testing.expectEqual(pid, siginfo.fields.common.first.piduid.pid); - try testing.expectEqual(7, siginfo.fields.common.second.sigchld.status); -} - /// For use in tests. Returns SkipZigTest if kernel version is less than required. inline fn skipKernelLessThan(required: std.SemanticVersion) !void { if (!is_linux) return error.SkipZigTest; diff --git a/lib/std/posix.zig b/lib/std/posix.zig index f4aa970413..42429a4993 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -615,66 +615,6 @@ fn getRandomBytesDevURandom(buf: []u8) GetRandomError!void { } } -/// Causes abnormal process termination. -/// If linking against libc, this calls the abort() libc function. Otherwise -/// it raises SIGABRT followed by SIGKILL and finally lo -/// Invokes the current signal handler for SIGABRT, if any. -pub fn abort() noreturn { - @branchHint(.cold); - // MSVCRT abort() sometimes opens a popup window which is undesirable, so - // even when linking libc on Windows we use our own abort implementation. - // See https://github.com/ziglang/zig/issues/2071 for more details. - if (native_os == .windows) { - if (builtin.mode == .Debug and windows.peb().BeingDebugged != 0) { - @breakpoint(); - } - windows.ntdll.RtlExitUserProcess(3); - } - if (!builtin.link_libc and native_os == .linux) { - // The Linux man page says that the libc abort() function - // "first unblocks the SIGABRT signal", but this is a footgun - // for user-defined signal handlers that want to restore some state in - // some program sections and crash in others. - // So, the user-installed SIGABRT handler is run, if present. - raise(.ABRT) catch {}; - - // Disable all signal handlers. - const filledset = linux.sigfillset(); - sigprocmask(SIG.BLOCK, &filledset, null); - - // Only one thread may proceed to the rest of abort(). - if (!builtin.single_threaded) { - const global = struct { - var abort_entered: bool = false; - }; - while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .seq_cst, .seq_cst)) |_| {} - } - - // Install default handler so that the tkill below will terminate. - const sigact = Sigaction{ - .handler = .{ .handler = SIG.DFL }, - .mask = sigemptyset(), - .flags = 0, - }; - sigaction(.ABRT, &sigact, null); - - _ = linux.tkill(linux.gettid(), .ABRT); - - var sigabrtmask = sigemptyset(); - sigaddset(&sigabrtmask, .ABRT); - sigprocmask(SIG.UNBLOCK, &sigabrtmask, null); - - // Beyond this point should be unreachable. - @as(*allowzero volatile u8, @ptrFromInt(0)).* = 0; - raise(.KILL) catch {}; - exit(127); // Pid 1 might not be signalled in some containers. - } - switch (native_os) { - .uefi, .wasi, .emscripten, .cuda, .amdhsa => @trap(), - else => system.abort(), - } -} - pub const RaiseError = UnexpectedError; pub fn raise(sig: SIG) RaiseError!void { @@ -715,33 +655,6 @@ pub fn kill(pid: pid_t, sig: SIG) KillError!void { } } -/// Exits all threads of the program with the specified status code. -pub fn exit(status: u8) noreturn { - if (builtin.link_libc) { - std.c.exit(status); - } - if (native_os == .windows) { - windows.ntdll.RtlExitUserProcess(status); - } - if (native_os == .wasi) { - wasi.proc_exit(status); - } - if (native_os == .linux and !builtin.single_threaded) { - linux.exit_group(status); - } - if (native_os == .uefi) { - const uefi = std.os.uefi; - // exit() is only available if exitBootServices() has not been called yet. - // This call to exit should not fail, so we catch-ignore errors. - if (uefi.system_table.boot_services) |bs| { - bs.exit(uefi.handle, @enumFromInt(status), null) catch {}; - } - // If we can't exit, reboot the system instead. - uefi.system_table.runtime_services.resetSystem(.cold, @enumFromInt(status), null); - } - system.exit(status); -} - pub const ReadError = std.Io.File.Reader.Error; /// Returns the number of bytes that were read, which can be less than diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index dc63be6e14..169c5a70c2 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -667,73 +667,6 @@ test "writev longer than IOV_MAX" { try testing.expectEqual(@as(usize, posix.IOV_MAX), amt); } -test "POSIX file locking with fcntl" { - if (native_os == .windows or native_os == .wasi) { - // Not POSIX. - return error.SkipZigTest; - } - - if (true) { - // https://github.com/ziglang/zig/issues/11074 - return error.SkipZigTest; - } - - const io = testing.io; - - var tmp = tmpDir(.{}); - defer tmp.cleanup(); - - // Create a temporary lock file - var file = try tmp.dir.createFile(io, "lock", .{ .read = true }); - defer file.close(io); - try file.setEndPos(2); - const fd = file.handle; - - // Place an exclusive lock on the first byte, and a shared lock on the second byte: - var struct_flock = std.mem.zeroInit(posix.Flock, .{ .type = posix.F.WRLCK }); - _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)); - struct_flock.start = 1; - struct_flock.type = posix.F.RDLCK; - _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)); - - // Check the locks in a child process: - const pid = try posix.fork(); - if (pid == 0) { - // child expects be denied the exclusive lock: - struct_flock.start = 0; - struct_flock.type = posix.F.WRLCK; - try expectError(error.Locked, posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock))); - // child expects to get the shared lock: - struct_flock.start = 1; - struct_flock.type = posix.F.RDLCK; - _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)); - // child waits for the exclusive lock in order to test deadlock: - struct_flock.start = 0; - struct_flock.type = posix.F.WRLCK; - _ = try posix.fcntl(fd, posix.F.SETLKW, @intFromPtr(&struct_flock)); - // child exits without continuing: - posix.exit(0); - } else { - // parent waits for child to get shared lock: - std.Thread.sleep(1 * std.time.ns_per_ms); - // parent expects deadlock when attempting to upgrade the shared lock to exclusive: - struct_flock.start = 1; - struct_flock.type = posix.F.WRLCK; - try expectError(error.DeadLock, posix.fcntl(fd, posix.F.SETLKW, @intFromPtr(&struct_flock))); - // parent releases exclusive lock: - struct_flock.start = 0; - struct_flock.type = posix.F.UNLCK; - _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)); - // parent releases shared lock: - struct_flock.start = 1; - struct_flock.type = posix.F.UNLCK; - _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)); - // parent waits for child: - const result = posix.waitpid(pid, 0); - try expect(result.status == 0 * 256); - } -} - test "rename smoke test" { if (native_os == .wasi) return error.SkipZigTest; if (native_os == .windows) return error.SkipZigTest; diff --git a/lib/std/process.zig b/lib/std/process.zig index 5d60190c2b..f7ecf5fdc2 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -16,8 +16,6 @@ const unicode = std.unicode; const max_path_bytes = std.fs.max_path_bytes; pub const Child = @import("process/Child.zig"); -pub const abort = posix.abort; -pub const exit = posix.exit; pub const changeCurDir = posix.chdir; pub const changeCurDirZ = posix.chdirZ; @@ -2208,3 +2206,87 @@ pub const OpenExecutableError = File.OpenError || ExecutablePathError || File.Lo pub fn openExecutable(io: Io, flags: File.OpenFlags) OpenExecutableError!File { return io.vtable.processExecutableOpen(io.userdata, flags); } + +/// Causes abnormal process termination. +/// +/// If linking against libc, this calls `std.c.abort`. Otherwise it raises +/// SIGABRT followed by SIGKILL. +/// +/// Invokes the current signal handler for SIGABRT, if any. +pub fn abort() noreturn { + @branchHint(.cold); + // MSVCRT abort() sometimes opens a popup window which is undesirable, so + // even when linking libc on Windows we use our own abort implementation. + // See https://github.com/ziglang/zig/issues/2071 for more details. + if (native_os == .windows) { + if (builtin.mode == .Debug and windows.peb().BeingDebugged != 0) { + @breakpoint(); + } + windows.ntdll.RtlExitUserProcess(3); + } + if (!builtin.link_libc and native_os == .linux) { + // The Linux man page says that the libc abort() function + // "first unblocks the SIGABRT signal", but this is a footgun + // for user-defined signal handlers that want to restore some state in + // some program sections and crash in others. + // So, the user-installed SIGABRT handler is run, if present. + posix.raise(.ABRT) catch {}; + + // Disable all signal handlers. + const filledset = std.os.linux.sigfillset(); + posix.sigprocmask(posix.SIG.BLOCK, &filledset, null); + + // Only one thread may proceed to the rest of abort(). + if (!builtin.single_threaded) { + const global = struct { + var abort_entered: bool = false; + }; + while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .seq_cst, .seq_cst)) |_| {} + } + + // Install default handler so that the tkill below will terminate. + const sigact: posix.Sigaction = .{ + .handler = .{ .handler = posix.SIG.DFL }, + .mask = posix.sigemptyset(), + .flags = 0, + }; + posix.sigaction(.ABRT, &sigact, null); + + _ = std.os.linux.tkill(std.os.linux.gettid(), .ABRT); + + var sigabrtmask = posix.sigemptyset(); + posix.sigaddset(&sigabrtmask, .ABRT); + posix.sigprocmask(posix.SIG.UNBLOCK, &sigabrtmask, null); + + // Beyond this point should be unreachable. + @as(*allowzero volatile u8, @ptrFromInt(0)).* = 0; + posix.raise(.KILL) catch {}; + exit(127); // Pid 1 might not be signalled in some containers. + } + switch (native_os) { + .uefi, .wasi, .emscripten, .cuda, .amdhsa => @trap(), + else => posix.system.abort(), + } +} + +/// Exits all threads of the program with the specified status code. +pub fn exit(status: u8) noreturn { + if (builtin.link_libc) { + std.c.exit(status); + } else switch (native_os) { + .windows => windows.ntdll.RtlExitUserProcess(status), + .wasi => std.os.wasi.proc_exit(status), + .linux => if (!builtin.single_threaded) std.os.linux.exit_group(status), + .uefi => { + const uefi = std.os.uefi; + // exit() is only available if exitBootServices() has not been called yet. + // This call to exit should not fail, so we catch-ignore errors. + if (uefi.system_table.boot_services) |bs| { + bs.exit(uefi.handle, @enumFromInt(status), null) catch {}; + } + // If we can't exit, reboot the system instead. + uefi.system_table.runtime_services.resetSystem(.cold, @enumFromInt(status), null); + }, + else => posix.system.exit(status), + } +} diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index 33faeef061..4521cd511f 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -1050,7 +1050,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { // The _exit(2) function does nothing but make the exit syscall, unlike exit(3) std.c._exit(1); } - posix.exit(1); + posix.system.exit(1); } fn writeIntFd(fd: i32, value: ErrInt) !void { diff --git a/lib/std/start.zig b/lib/std/start.zig index a5bec41231..64a1c17175 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -110,7 +110,7 @@ fn main2() callconv(.c) c_int { } fn _start2() callconv(.withStackAlign(.c, 1)) noreturn { - std.posix.exit(callMain()); + std.process.exit(callMain()); } fn spirvMain2() callconv(.kernel) void { @@ -118,7 +118,7 @@ fn spirvMain2() callconv(.kernel) void { } fn wWinMainCRTStartup2() callconv(.c) noreturn { - std.posix.exit(callMain()); + std.process.exit(callMain()); } //////////////////////////////////////////////////////////////////////////////// @@ -627,7 +627,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { for (slice) |func| func(); } - std.posix.exit(callMainWithArgs(argc, argv, envp)); + std.process.exit(callMainWithArgs(argc, argv, envp)); } fn expandStackSize(phdrs: []elf.Phdr) void { diff --git a/lib/std/tar.zig b/lib/std/tar.zig index 8a0bbb342f..b2a5306458 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -606,7 +606,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp switch (file.kind) { .directory => { if (file_name.len > 0 and !options.exclude_empty_directories) { - try dir.makePath(file_name); + try dir.makePath(io, file_name); } }, .file => { @@ -625,7 +625,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp }, .sym_link => { const link_name = file.link_name; - createDirAndSymlink(dir, link_name, file_name) catch |err| { + createDirAndSymlink(io, dir, link_name, file_name) catch |err| { const d = options.diagnostics orelse return error.UnableToCreateSymLink; try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{ .code = err, @@ -642,7 +642,7 @@ fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mo const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { - try dir.makePath(dir_name); + try dir.makePath(io, dir_name); return try dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }); } } @@ -652,11 +652,11 @@ fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mo } // Creates a symbolic link at path `file_name` which points to `link_name`. -fn createDirAndSymlink(dir: Io.Dir, link_name: []const u8, file_name: []const u8) !void { +fn createDirAndSymlink(io: Io, dir: Io.Dir, link_name: []const u8, file_name: []const u8) !void { dir.symLink(link_name, file_name, .{}) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { - try dir.makePath(dir_name); + try dir.makePath(io, dir_name); return try dir.symLink(link_name, file_name, .{}); } } @@ -885,15 +885,15 @@ test "create file and symlink" { file = try createDirAndFile(io, root.dir, "a/b/c/file2", default_mode); file.close(io); - createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { + createDirAndSymlink(io, root.dir, "a/b/c/file2", "symlink1") catch |err| { // On Windows when developer mode is not enabled if (err == error.AccessDenied) return error.SkipZigTest; return err; }; - try createDirAndSymlink(root.dir, "../../../file1", "d/e/f/symlink2"); + try createDirAndSymlink(io, root.dir, "../../../file1", "d/e/f/symlink2"); // Danglink symlnik, file created later - try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); + try createDirAndSymlink(io, root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); file = try createDirAndFile(io, root.dir, "g/h/i/file4", default_mode); file.close(io); } diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 9d08847092..acb3fc65ab 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -464,6 +464,8 @@ pub const Iterator = struct { filename_buf: []u8, dest: Io.Dir, ) !void { + const io = stream.io; + if (filename_buf.len < self.filename_len) return error.ZipInsufficientBuffer; switch (self.compression_method) { @@ -552,12 +554,10 @@ pub const Iterator = struct { if (filename[filename.len - 1] == '/') { if (self.uncompressed_size != 0) return error.ZipBadDirectorySize; - try dest.makePath(filename[0 .. filename.len - 1]); + try dest.makePath(io, filename[0 .. filename.len - 1]); return; } - const io = stream.io; - const out_file = blk: { if (std.fs.path.dirname(filename)) |dirname| { var parent_dir = try dest.makeOpenPath(dirname, .{}); diff --git a/src/Compilation.zig b/src/Compilation.zig index 3a48705880..280d34cdbf 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3180,7 +3180,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE const s = fs.path.sep_str; const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); const o_sub_path = "o" ++ s ++ hex_digest; - renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| { + renameTmpIntoCache(io, comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| { return comp.setMiscFailure( .rename_results, "failed to rename compilation results ('{f}{s}') into local cache ('{f}{s}'): {t}", @@ -3399,17 +3399,19 @@ fn flush( /// implementation at the bottom of this function. /// This function is only called when CacheMode is `whole`. fn renameTmpIntoCache( + io: Io, cache_directory: Cache.Directory, tmp_dir_sub_path: []const u8, o_sub_path: []const u8, ) !void { var seen_eaccess = false; while (true) { - fs.rename( + Io.Dir.rename( cache_directory.handle, tmp_dir_sub_path, cache_directory.handle, o_sub_path, + io, ) catch |err| switch (err) { // On Windows, rename fails with `AccessDenied` rather than `PathAlreadyExists`. // See https://github.com/ziglang/zig/issues/8362 @@ -3427,7 +3429,7 @@ fn renameTmpIntoCache( continue; }, error.FileNotFound => { - try cache_directory.handle.makePath("o"); + try cache_directory.handle.makePath(io, "o"); continue; }, else => |e| return e, @@ -5816,7 +5818,7 @@ pub fn translateC( const o_sub_path = "o" ++ fs.path.sep_str ++ hex_digest; if (comp.verbose_cimport) log.info("renaming {s} to {s}", .{ tmp_sub_path, o_sub_path }); - try renameTmpIntoCache(comp.dirs.local_cache, tmp_sub_path, o_sub_path); + try renameTmpIntoCache(io, comp.dirs.local_cache, tmp_sub_path, o_sub_path); return .{ .digest = bin_digest, diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index a651107bf5..e54dcb9914 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -1414,6 +1414,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void { const gpa = f.arena.child_allocator; + const io = f.job_queue.io; // Recursive directory copy. var it = try dir.walk(gpa); defer it.deinit(); @@ -1428,7 +1429,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void .{}, ) catch |err| switch (err) { error.FileNotFound => { - if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(dirname); + if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); try dir.copyFile(entry.path, tmp_dir, entry.path, .{}); }, else => |e| return e, @@ -1441,7 +1442,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void // the destination directory, fail with an error instead. tmp_dir.symLink(link_name, entry.path, .{}) catch |err| switch (err) { error.FileNotFound => { - if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(dirname); + if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); try tmp_dir.symLink(link_name, entry.path, .{}); }, else => |e| return e, diff --git a/src/main.zig b/src/main.zig index fe48efa2fd..a063591b64 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3382,7 +3382,7 @@ fn buildOutputType( const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ std.crypto.random.int(u64), ext.canonicalName(target), }); - try dirs.local_cache.handle.makePath("tmp"); + try dirs.local_cache.handle.makePath(io, "tmp"); // Note that in one of the happy paths, execve() is used to switch to // clang in which case any cleanup logic that exists for this temporary @@ -4773,7 +4773,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! var ok_count: usize = 0; for (template_paths) |template_path| { - if (templates.write(arena, Io.Dir.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { + if (templates.write(arena, io, Io.Dir.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { std.log.info("created {s}", .{template_path}); ok_count += 1; } else |err| switch (err) { @@ -7394,20 +7394,21 @@ const Templates = struct { fn write( templates: *Templates, arena: Allocator, + io: Io, out_dir: Io.Dir, root_name: []const u8, template_path: []const u8, fingerprint: Package.Fingerprint, ) !void { if (fs.path.dirname(template_path)) |dirname| { - out_dir.makePath(dirname) catch |err| { - fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) }); + out_dir.makePath(io, dirname) catch |err| { + fatal("unable to make path '{s}': {t}", .{ dirname, err }); }; } const max_bytes = 10 * 1024 * 1024; const contents = templates.dir.readFileAlloc(template_path, arena, .limited(max_bytes)) catch |err| { - fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); + fatal("unable to read template file '{s}': {t}", .{ template_path, err }); }; templates.buffer.clearRetainingCapacity(); try templates.buffer.ensureUnusedCapacity(contents.len); -- cgit v1.2.3 From 950d18ef695bb7a28397e080dc3c201559ec4ee2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 17:14:31 -0800 Subject: update all access() to access(io) --- lib/compiler/aro/aro/Driver.zig | 6 +-- lib/compiler/aro/aro/Driver/Filesystem.zig | 8 ++-- lib/compiler/aro/aro/Toolchain.zig | 13 ++++--- lib/compiler/aro/backend/Assembly.zig | 4 +- lib/compiler/resinator/cli.zig | 10 ++--- lib/compiler/resinator/main.zig | 6 +-- lib/compiler/std-docs.zig | 8 ++-- lib/compiler/translate-c/main.zig | 4 +- lib/std/Build.zig | 2 +- lib/std/Build/Cache/Path.zig | 4 +- lib/std/Build/Step.zig | 12 +++--- lib/std/Build/Step/InstallDir.zig | 2 +- lib/std/Build/Step/Run.zig | 47 ++++++++++++----------- lib/std/Build/Step/WriteFile.zig | 9 ++--- lib/std/Io.zig | 4 +- lib/std/Io/Dir.zig | 16 ++++---- lib/std/Io/Threaded.zig | 13 +++++-- lib/std/Io/test.zig | 2 +- lib/std/debug.zig | 8 ++-- lib/std/fs/test.zig | 24 ++++++------ lib/std/posix.zig | 61 ------------------------------ lib/std/posix/test.zig | 12 +++--- lib/std/zig/LibCInstallation.zig | 10 ++--- lib/std/zig/llvm/Builder.zig | 4 +- lib/std/zig/system.zig | 3 +- src/Compilation.zig | 2 +- src/Package/Fetch.zig | 5 ++- src/introspect.zig | 4 +- src/libs/mingw.zig | 12 +++--- src/link/C.zig | 3 +- src/link/Lld.zig | 9 +++-- src/link/MachO.zig | 21 +++++----- src/main.zig | 8 ++-- 33 files changed, 159 insertions(+), 197 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index fec3cea0f8..b344cc8a9d 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -1333,7 +1333,7 @@ fn processSource( Io.File.stdout(); defer if (dep_file_name != null) file.close(io); - var file_writer = file.writer(&writer_buf); + var file_writer = file.writer(io, &writer_buf); dep_file.write(&file_writer.interface) catch return d.fatal("unable to write dependency file: {s}", .{errorDescription(file_writer.err.?)}); } @@ -1358,7 +1358,7 @@ fn processSource( Io.File.stdout(); defer if (d.output_name != null) file.close(io); - var file_writer = file.writer(&writer_buf); + var file_writer = file.writer(io, &writer_buf); pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch return d.fatal("unable to write result: {s}", .{errorDescription(file_writer.err.?)}); @@ -1459,7 +1459,7 @@ fn processSource( return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(io); - var file_writer = out_file.writer(&writer_buf); + var file_writer = out_file.writer(io, &writer_buf); obj.finish(&file_writer.interface) catch return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(file_writer.err.?) }); } diff --git a/lib/compiler/aro/aro/Driver/Filesystem.zig b/lib/compiler/aro/aro/Driver/Filesystem.zig index 001f10f27c..c229dfd831 100644 --- a/lib/compiler/aro/aro/Driver/Filesystem.zig +++ b/lib/compiler/aro/aro/Driver/Filesystem.zig @@ -57,8 +57,8 @@ fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool { return false; } -fn canExecutePosix(path: []const u8) bool { - std.posix.access(path, std.posix.X_OK) catch return false; +fn canExecutePosix(io: Io, path: []const u8) bool { + Io.Dir.accessAbsolute(io, path, .{ .execute = true }) catch return false; // Todo: ensure path is not a directory return true; } @@ -172,10 +172,10 @@ pub const Filesystem = union(enum) { } }; - pub fn exists(fs: Filesystem, path: []const u8) bool { + pub fn exists(fs: Filesystem, io: Io, path: []const u8) bool { switch (fs) { .real => |cwd| { - cwd.access(path, .{}) catch return false; + cwd.access(io, path, .{}) catch return false; return true; }, .fake => |paths| return existsFake(paths, path), diff --git a/lib/compiler/aro/aro/Toolchain.zig b/lib/compiler/aro/aro/Toolchain.zig index 0328c264d0..0aa9d76fc8 100644 --- a/lib/compiler/aro/aro/Toolchain.zig +++ b/lib/compiler/aro/aro/Toolchain.zig @@ -501,7 +501,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { try d.includes.ensureUnusedCapacity(gpa, 1); if (d.resource_dir) |resource_dir| { const path = try std.fs.path.join(arena, &.{ resource_dir, "include" }); - comp.cwd.access(path, .{}) catch { + comp.cwd.access(io, path, .{}) catch { return d.fatal("Aro builtin headers not found in provided -resource-dir", .{}); }; d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path }); @@ -512,7 +512,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { var base_dir = d.comp.cwd.openDir(io, dirname, .{}) catch continue; defer base_dir.close(io); - base_dir.access("include/stddef.h", .{}) catch continue; + base_dir.access(io, "include/stddef.h", .{}) catch continue; const path = try std.fs.path.join(arena, &.{ dirname, "include" }); d.includes.appendAssumeCapacity(.{ .kind = .system, .path = path }); break; @@ -524,12 +524,14 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned pub fn readFile(tc: *const Toolchain, path: []const u8, buf: []u8) ?[]const u8 { const comp = tc.driver.comp; - return comp.cwd.readFile(comp.io, path, buf) catch null; + const io = comp.io; + return comp.cwd.readFile(io, path, buf) catch null; } pub fn exists(tc: *const Toolchain, path: []const u8) bool { const comp = tc.driver.comp; - comp.cwd.access(comp.io, path, .{}) catch return false; + const io = comp.io; + comp.cwd.access(io, path, .{}) catch return false; return true; } @@ -547,7 +549,8 @@ pub fn canExecute(tc: *const Toolchain, path: []const u8) bool { } const comp = tc.driver.comp; - comp.cwd.access(comp.io, path, .{ .execute = true }) catch return false; + const io = comp.io; + comp.cwd.access(io, path, .{ .execute = true }) catch return false; // Todo: ensure path is not a directory return true; } diff --git a/lib/compiler/aro/backend/Assembly.zig b/lib/compiler/aro/backend/Assembly.zig index 80143bf97f..4ec4860b51 100644 --- a/lib/compiler/aro/backend/Assembly.zig +++ b/lib/compiler/aro/backend/Assembly.zig @@ -12,8 +12,8 @@ pub fn deinit(self: *const Assembly, gpa: Allocator) void { gpa.free(self.text); } -pub fn writeToFile(self: Assembly, file: Io.File) !void { - var file_writer = file.writer(&.{}); +pub fn writeToFile(self: Assembly, io: Io, file: Io.File) !void { + var file_writer = file.writer(io, &.{}); var buffers = [_][]const u8{ self.data, self.text }; try file_writer.interface.writeSplatAll(&buffers, 1); diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index ae4ece2968..5588390197 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -250,13 +250,13 @@ pub const Options = struct { /// worlds' situation where we'll be compatible with most use-cases /// of the .rc extension being omitted from the CLI args, but still /// work fine if the file itself does not have an extension. - pub fn maybeAppendRC(options: *Options, cwd: Io.Dir) !void { + pub fn maybeAppendRC(options: *Options, io: Io, cwd: Io.Dir) !void { switch (options.input_source) { .stdio => return, .filename => {}, } if (options.input_format == .rc and std.fs.path.extension(options.input_source.filename).len == 0) { - cwd.access(options.input_source.filename, .{}) catch |err| switch (err) { + cwd.access(io, options.input_source.filename, .{}) catch |err| switch (err) { error.FileNotFound => { var filename_bytes = try options.allocator.alloc(u8, options.input_source.filename.len + 3); @memcpy(filename_bytes[0..options.input_source.filename.len], options.input_source.filename); @@ -2005,19 +2005,19 @@ test "maybeAppendRC" { // appended. var file = try tmp.dir.createFile(io, "foo", .{}); file.close(io); - try options.maybeAppendRC(tmp.dir); + try options.maybeAppendRC(io, tmp.dir); try std.testing.expectEqualStrings("foo", options.input_source.filename); // Now delete the file and try again. But this time change the input format // to non-rc. try tmp.dir.deleteFile("foo"); options.input_format = .res; - try options.maybeAppendRC(tmp.dir); + try options.maybeAppendRC(io, tmp.dir); try std.testing.expectEqualStrings("foo", options.input_source.filename); // Finally, reset the input format to rc. Since the verbatim name is no longer found // and the input filename does not have an extension, .rc should get appended. options.input_format = .rc; - try options.maybeAppendRC(tmp.dir); + try options.maybeAppendRC(io, tmp.dir); try std.testing.expectEqualStrings("foo.rc", options.input_source.filename); } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 416abc2ab7..1a6ef5eea3 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -318,7 +318,7 @@ pub fn main() !void { defer depfile.close(io); var depfile_buffer: [1024]u8 = undefined; - var depfile_writer = depfile.writer(&depfile_buffer); + var depfile_writer = depfile.writer(io, &depfile_buffer); switch (options.depfile_fmt) { .json => { var write_stream: std.json.Stringify = .{ @@ -521,9 +521,9 @@ const IoStream = struct { } }; - pub fn writer(source: *Source, allocator: Allocator, buffer: []u8) Writer { + pub fn writer(source: *Source, allocator: Allocator, io: Io, buffer: []u8) Writer { return switch (source.*) { - .file, .stdio => |file| .{ .file = file.writer(buffer) }, + .file, .stdio => |file| .{ .file = file.writer(io, buffer) }, .memory => |*list| .{ .allocating = .fromArrayList(allocator, list) }, .closed => unreachable, }; diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index d5beab5f17..f1382e6eae 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -334,8 +334,8 @@ fn buildWasmBinary( }); defer poller.deinit(); - try sendMessage(child.stdin.?, .update); - try sendMessage(child.stdin.?, .exit); + try sendMessage(io, child.stdin.?, .update); + try sendMessage(io, child.stdin.?, .exit); var result: ?Cache.Path = null; var result_error_bundle = std.zig.ErrorBundle.empty; @@ -421,12 +421,12 @@ fn buildWasmBinary( }; } -fn sendMessage(file: std.Io.File, tag: std.zig.Client.Message.Tag) !void { +fn sendMessage(io: Io, file: std.Io.File, tag: std.zig.Client.Message.Tag) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 0, }; - var w = file.writer(&.{}); + var w = file.writer(io, &.{}); w.interface.writeStruct(header, .little) catch |err| switch (err) { error.WriteFailed => return w.err.?, }; diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index d140145032..d02f21a2a8 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -232,7 +232,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration Io.File.stdout(); defer if (dep_file_name != null) file.close(io); - var file_writer = file.writer(&out_buf); + var file_writer = file.writer(io, &out_buf); dep_file.write(&file_writer.interface) catch return d.fatal("unable to write dependency file: {s}", .{aro.Driver.errorDescription(file_writer.err.?)}); } @@ -263,7 +263,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration out_file_path = path; } - var out_writer = out_file.writer(&out_buf); + var out_writer = out_file.writer(io, &out_buf); out_writer.interface.writeAll(rendered_zig) catch {}; out_writer.interface.flush() catch {}; if (out_writer.err) |write_err| diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 1eff8813e5..746b41860b 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1699,7 +1699,7 @@ pub fn addCheckFile( return Step.CheckFile.create(b, file_source, options); } -pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void { +pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatPathError)!void { const io = b.graph.io; if (b.verbose) log.info("truncate {s}", .{dest_path}); const cwd = Io.Dir.cwd(); diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 941948a9cd..759eb143b8 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -118,14 +118,14 @@ pub fn atomicFile( return p.root_dir.handle.atomicFile(joined_path, options); } -pub fn access(p: Path, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void { +pub fn access(p: Path, io: Io, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.access(joined_path, flags); + return p.root_dir.handle.access(io, joined_path, flags); } pub fn makePath(p: Path, io: Io, sub_path: []const u8) !void { diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 2ec1c0ef31..f66f8df4c8 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -519,19 +519,21 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u /// Wrapper around `Io.Dir.makePathStatus` that handles verbose and error output. pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus { const b = s.owner; + const io = b.graph.io; try handleVerbose(b, null, &.{ "install", "-d", dest_path }); - return Io.Dir.cwd().makePathStatus(dest_path) catch |err| + return Io.Dir.cwd().makePathStatus(io, dest_path, .default_dir) catch |err| return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err }); } fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.WebServer, gpa: Allocator) !?Path { const b = s.owner; const arena = b.allocator; + const io = b.graph.io; var timer = try std.time.Timer.start(); - try sendMessage(zp.child.stdin.?, .update); - if (!watch) try sendMessage(zp.child.stdin.?, .exit); + try sendMessage(io, zp.child.stdin.?, .update); + if (!watch) try sendMessage(io, zp.child.stdin.?, .exit); var result: ?Path = null; @@ -668,12 +670,12 @@ fn clearZigProcess(s: *Step, gpa: Allocator) void { } } -fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void { +fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 0, }; - var w = file.writer(&.{}); + var w = file.writer(io, &.{}); w.interface.writeStruct(header, .little) catch |err| switch (err) { error.WriteFailed => return w.err.?, }; diff --git a/lib/std/Build/Step/InstallDir.zig b/lib/std/Build/Step/InstallDir.zig index 788d5565a7..d03e72ca75 100644 --- a/lib/std/Build/Step/InstallDir.zig +++ b/lib/std/Build/Step/InstallDir.zig @@ -71,7 +71,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { defer src_dir.close(io); var it = try src_dir.walk(arena); var all_cached = true; - next_entry: while (try it.next()) |entry| { + next_entry: while (try it.next(io)) |entry| { for (install_dir.options.exclude_extensions) |ext| { if (mem.endsWith(u8, entry.path, ext)) continue :next_entry; } diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 54e77bd614..f6b29635c1 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1310,7 +1310,7 @@ fn runCommand( const need_cross_libc = exe.is_linking_libc and (root_target.isGnuLibC() or (root_target.isMuslLibC() and exe.linkage == .dynamic)); const other_target = exe.root_module.resolved_target.?.result; - switch (std.zig.system.getExternalExecutor(&b.graph.host.result, &other_target, .{ + switch (std.zig.system.getExternalExecutor(io, &b.graph.host.result, &other_target, .{ .qemu_fixes_dl = need_cross_libc and b.libc_runtimes_dir != null, .link_libc = exe.is_linking_libc, })) { @@ -1702,7 +1702,7 @@ fn evalZigTest( }); var child_killed = false; defer if (!child_killed) { - _ = child.kill() catch {}; + _ = child.kill(io) catch {}; poller.deinit(); run.step.result_peak_rss = @max( run.step.result_peak_rss, @@ -1732,7 +1732,7 @@ fn evalZigTest( child.stdin = null; poller.deinit(); child_killed = true; - const term = try child.wait(); + const term = try child.wait(io); run.step.result_peak_rss = @max( run.step.result_peak_rss, child.resource_usage_statistics.getMaxRss() orelse 0, @@ -1752,7 +1752,7 @@ fn evalZigTest( child.stdin = null; poller.deinit(); child_killed = true; - const term = try child.wait(); + const term = try child.wait(io); run.step.result_peak_rss = @max( run.step.result_peak_rss, child.resource_usage_statistics.getMaxRss() orelse 0, @@ -1840,6 +1840,7 @@ fn pollZigTest( switch (ctx.fuzz.mode) { .forever => { sendRunFuzzTestMessage( + io, child.stdin.?, ctx.unit_test_index, .forever, @@ -1848,6 +1849,7 @@ fn pollZigTest( }, .limit => |limit| { sendRunFuzzTestMessage( + io, child.stdin.?, ctx.unit_test_index, .iterations, @@ -1857,11 +1859,11 @@ fn pollZigTest( } } else if (opt_metadata.*) |*md| { // Previous unit test process died or was killed; we're continuing where it left off - requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; + requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; } else { // Running unit tests normally run.fuzz_tests.clearRetainingCapacity(); - sendMessage(child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err }; + sendMessage(io, child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err }; } var active_test_index: ?u32 = null; @@ -1977,7 +1979,7 @@ fn pollZigTest( active_test_index = null; if (timer) |*t| t.reset(); - requestNextTest(child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err }; + requestNextTest(io, child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err }; }, .test_started => { active_test_index = opt_metadata.*.?.next_index - 1; @@ -2026,7 +2028,7 @@ fn pollZigTest( active_test_index = null; if (timer) |*t| md.ns_per_test[tr_hdr.index] = t.lap(); - requestNextTest(child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; + requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; }, .coverage_id => { coverage_id = body_r.takeInt(u64, .little) catch unreachable; @@ -2097,7 +2099,7 @@ pub const CachedTestMetadata = struct { } }; -fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { +fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { while (metadata.next_index < metadata.names.len) { const i = metadata.next_index; metadata.next_index += 1; @@ -2108,31 +2110,31 @@ fn requestNextTest(in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr if (sub_prog_node.*) |n| n.end(); sub_prog_node.* = metadata.prog_node.start(name, 0); - try sendRunTestMessage(in, .run_test, i); + try sendRunTestMessage(io, in, .run_test, i); return; } else { metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done - try sendMessage(in, .exit); + try sendMessage(io, in, .exit); } } -fn sendMessage(file: Io.File, tag: std.zig.Client.Message.Tag) !void { +fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 0, }; - var w = file.writer(&.{}); + var w = file.writer(io, &.{}); w.interface.writeStruct(header, .little) catch |err| switch (err) { error.WriteFailed => return w.err.?, }; } -fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void { +fn sendRunTestMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void { const header: std.zig.Client.Message.Header = .{ .tag = tag, .bytes_len = 4, }; - var w = file.writer(&.{}); + var w = file.writer(io, &.{}); w.interface.writeStruct(header, .little) catch |err| switch (err) { error.WriteFailed => return w.err.?, }; @@ -2142,6 +2144,7 @@ fn sendRunTestMessage(file: Io.File, tag: std.zig.Client.Message.Tag, index: u32 } fn sendRunFuzzTestMessage( + io: Io, file: Io.File, index: u32, kind: std.Build.abi.fuzz.LimitKind, @@ -2151,7 +2154,7 @@ fn sendRunFuzzTestMessage( .tag = .start_fuzzing, .bytes_len = 4 + 1 + 8, }; - var w = file.writer(&.{}); + var w = file.writer(io, &.{}); w.interface.writeStruct(header, .little) catch |err| switch (err) { error.WriteFailed => return w.err.?, }; @@ -2172,14 +2175,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { const arena = b.allocator; try child.spawn(); - errdefer _ = child.kill() catch {}; + errdefer _ = child.kill(io) catch {}; try child.waitForSpawn(); switch (run.stdin) { .bytes => |bytes| { - child.stdin.?.writeAll(bytes) catch |err| { - return run.step.fail("unable to write stdin: {s}", .{@errorName(err)}); + child.stdin.?.writeStreamingAll(io, bytes) catch |err| { + return run.step.fail("unable to write stdin: {t}", .{err}); }; child.stdin.?.close(io); child.stdin = null; @@ -2187,14 +2190,14 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { .lazy_path => |lazy_path| { const path = lazy_path.getPath3(b, &run.step); const file = path.root_dir.handle.openFile(io, path.subPathOrDot(), .{}) catch |err| { - return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)}); + return run.step.fail("unable to open stdin file: {t}", .{err}); }; defer file.close(io); // TODO https://github.com/ziglang/zig/issues/23955 var read_buffer: [1024]u8 = undefined; var file_reader = file.reader(io, &read_buffer); var write_buffer: [1024]u8 = undefined; - var stdin_writer = child.stdin.?.writer(&write_buffer); + var stdin_writer = child.stdin.?.writer(io, &write_buffer); _ = stdin_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { error.ReadFailed => return run.step.fail("failed to read from {f}: {t}", .{ path, file_reader.err.?, @@ -2267,7 +2270,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { run.step.result_peak_rss = child.resource_usage_statistics.getMaxRss() orelse 0; return .{ - .term = try child.wait(), + .term = try child.wait(io), .stdout = stdout_bytes, .stderr = stderr_bytes, }; diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 21346959e7..94b04b4212 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -228,7 +228,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { var it = try src_dir.walk(gpa); defer it.deinit(); - while (try it.next()) |entry| { + while (try it.next(io)) |entry| { if (!dir.options.pathIncluded(entry.path)) continue; switch (entry.kind) { @@ -259,11 +259,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest }); - var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| { - return step.fail("unable to make path '{f}{s}': {s}", .{ - b.cache_root, cache_path, @errorName(err), - }); - }; + var cache_dir = b.cache_root.handle.makeOpenPath(io, cache_path, .{}) catch |err| + return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, cache_path, err }); defer cache_dir.close(io); for (write_file.files.items) |file| { diff --git a/lib/std/Io.zig b/lib/std/Io.zig index ad0764ebe1..7f5f049d34 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -664,13 +664,13 @@ pub const VTable = struct { dirMake: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakeError!void, dirMakePath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakePathError!Dir.MakePathStatus, - dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.MakeOpenPathError!Dir, + dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.MakeOpenPathError!Dir, + dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir, dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, dirStatPath: *const fn (?*anyopaque, Dir, []const u8, Dir.StatPathOptions) Dir.StatPathError!File.Stat, dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void, dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File, dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File, - dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir, dirClose: *const fn (?*anyopaque, []const Dir) void, dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize, dirRealPath: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathError!usize, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 58f81cbb90..755ce924ad 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -191,7 +191,7 @@ pub const SelectiveWalker = struct { while (self.stack.items.len > 0) { const top = &self.stack.items[self.stack.items.len - 1]; var dirname_len = top.dirname_len; - if (top.iter.next() catch |err| { + if (top.iter.next(io) catch |err| { // If we get an error, then we want the user to be able to continue // walking if they want, which means that we need to pop the directory // that errored from the stack. Otherwise, all future `next` calls would @@ -302,7 +302,7 @@ pub const Walker = struct { dir: Dir, basename: [:0]const u8, path: [:0]const u8, - kind: Dir.Entry.Kind, + kind: File.Kind, /// Returns the depth of the entry relative to the initial directory. /// Returns 1 for a direct child of the initial directory, 2 for an entry @@ -320,10 +320,10 @@ pub const Walker = struct { /// After each call to this function, and on deinit(), the memory returned /// from this function becomes invalid. A copy must be made in order to keep /// a reference to the path. - pub fn next(self: *Walker) !?Walker.Entry { - const entry = try self.inner.next(); + pub fn next(self: *Walker, io: Io) !?Walker.Entry { + const entry = try self.inner.next(io); if (entry != null and entry.?.kind == .directory) { - try self.inner.enter(entry.?); + try self.inner.enter(io, entry.?); } return entry; } @@ -495,7 +495,7 @@ pub const WriteFileOptions = struct { flags: File.CreateFlags = .{}, }; -pub const WriteFileError = File.WriteError || File.OpenError; +pub const WriteFileError = File.Writer.Error || File.OpenError; /// Writes content to the file system, using the file creation flags provided. pub fn writeFile(dir: Dir, io: Io, options: WriteFileOptions) WriteFileError!void { @@ -556,11 +556,11 @@ pub fn updateFile( } if (path.dirname(dest_path)) |dirname| { - try dest_dir.makePath(io, dirname, .default_dir); + try dest_dir.makePath(io, dirname); } var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available. - var atomic_file = try Dir.atomicFile(dest_dir, dest_path, .{ + var atomic_file = try dest_dir.atomicFile(io, dest_path, .{ .permissions = actual_permissions, .write_buffer = &buffer, }); diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 4ee1d5db53..16e8930267 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -12,7 +12,7 @@ const std = @import("../std.zig"); const Io = std.Io; const net = std.Io.net; const File = std.Io.File; -const Dir = std.Dir; +const Dir = std.Io.Dir; const HostName = std.Io.net.HostName; const IpAddress = std.Io.net.IpAddress; const Allocator = std.mem.Allocator; @@ -1614,13 +1614,14 @@ fn dirMakeOpenPathPosix( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, + permissions: Dir.Permissions, options: Dir.OpenOptions, ) Dir.MakeOpenPathError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const t_io = ioBasic(t); - return dirOpenDirPosix(t, dir, sub_path, options) catch |err| switch (err) { + return dirOpenDirPosix(t, dir, sub_path, permissions, options) catch |err| switch (err) { error.FileNotFound => { - try dir.makePath(t_io, sub_path); + _ = try dir.makePathStatus(t_io, sub_path, permissions); return dirOpenDirPosix(t, dir, sub_path, options); }, else => |e| return e, @@ -1631,12 +1632,15 @@ fn dirMakeOpenPathWindows( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, + permissions: Dir.Permissions, options: Dir.OpenOptions, ) Dir.MakeOpenPathError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); const w = windows; + _ = permissions; // TODO apply these permissions + var it = std.fs.path.componentIterator(sub_path); // If there are no components in the path, then create a dummy component with the full path. var component: std.fs.path.NativeComponentIterator.Component = it.last() orelse .{ @@ -1746,13 +1750,14 @@ fn dirMakeOpenPathWasi( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, + permissions: Dir.Permissions, options: Dir.OpenOptions, ) Dir.MakeOpenPathError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const t_io = ioBasic(t); return dirOpenDirWasi(t, dir, sub_path, options) catch |err| switch (err) { error.FileNotFound => { - try dir.makePath(t_io, sub_path); + _ = try dir.makePathStatus(t_io, sub_path, permissions); return dirOpenDirWasi(t, dir, sub_path, options); }, else => |e| return e, diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index e911031c7f..9763fb2397 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -30,7 +30,7 @@ test "write a file, read it, then delete it" { var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); - var file_writer = file.writer(&.{}); + var file_writer = file.writer(io, &.{}); const st = &file_writer.interface; try st.print("begin", .{}); try st.writeAll(&data); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 34f740bfee..39207f938d 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1279,7 +1279,7 @@ test printLineFromFile { const overlap = 10; var buf: [16]u8 = undefined; - var file_writer = file.writer(&buf); + var file_writer = file.writer(io, &buf); const writer = &file_writer.interface; try writer.splatByteAll('a', std.heap.page_size_min - overlap); try writer.writeByte('\n'); @@ -1296,7 +1296,7 @@ test printLineFromFile { const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" }); defer gpa.free(path); - var file_writer = file.writer(&.{}); + var file_writer = file.writer(io, &.{}); const writer = &file_writer.interface; try writer.splatByteAll('a', std.heap.page_size_max); @@ -1310,7 +1310,7 @@ test printLineFromFile { const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" }); defer gpa.free(path); - var file_writer = file.writer(&.{}); + var file_writer = file.writer(io, &.{}); const writer = &file_writer.interface; try writer.splatByteAll('a', 3 * std.heap.page_size_max); @@ -1336,7 +1336,7 @@ test printLineFromFile { const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" }); defer gpa.free(path); - var file_writer = file.writer(&.{}); + var file_writer = file.writer(io, &.{}); const writer = &file_writer.interface; const real_file_start = 3 * std.heap.page_size_min; try writer.splatByteAll('\n', real_file_start); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index bc84500419..59bacff2d0 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1206,8 +1206,8 @@ test "deleteTree does not follow symlinks" { try tmp.dir.deleteTree("a"); - try testing.expectError(error.FileNotFound, tmp.dir.access("a", .{})); - try tmp.dir.access("b", .{}); + try testing.expectError(error.FileNotFound, tmp.dir.access(io, "a", .{})); + try tmp.dir.access(io, "b", .{}); } test "deleteTree on a symlink" { @@ -1221,16 +1221,16 @@ test "deleteTree on a symlink" { try setupSymlink(tmp.dir, "file", "filelink", .{}); try tmp.dir.deleteTree("filelink"); - try testing.expectError(error.FileNotFound, tmp.dir.access("filelink", .{})); - try tmp.dir.access("file", .{}); + try testing.expectError(error.FileNotFound, tmp.dir.access(io, "filelink", .{})); + try tmp.dir.access(io, "file", .{}); // Symlink to a directory try tmp.dir.makePath(io, "dir"); try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true }); try tmp.dir.deleteTree("dirlink"); - try testing.expectError(error.FileNotFound, tmp.dir.access("dirlink", .{})); - try tmp.dir.access("dir", .{}); + try testing.expectError(error.FileNotFound, tmp.dir.access(io, "dirlink", .{})); + try tmp.dir.access(io, "dir", .{}); } test "makePath, put some files in it, deleteTree" { @@ -1358,8 +1358,8 @@ test "makepath relative walks" { // On Windows, .. is resolved before passing the path to NtCreateFile, // meaning everything except `first/C` drops out. try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "C"); - try testing.expectError(error.FileNotFound, tmp.dir.access("second", .{})); - try testing.expectError(error.FileNotFound, tmp.dir.access("third", .{})); + try testing.expectError(error.FileNotFound, tmp.dir.access(io, "second", .{})); + try testing.expectError(error.FileNotFound, tmp.dir.access(io, "third", .{})); }, else => { try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "A"); @@ -1561,10 +1561,10 @@ test "access file" { const file_path = try ctx.transformPath("os_test_tmp" ++ fs.path.sep_str ++ "file.txt"); try ctx.dir.makePath(io, dir_path); - try testing.expectError(error.FileNotFound, ctx.dir.access(file_path, .{})); + try testing.expectError(error.FileNotFound, ctx.dir.access(io, file_path, .{})); try ctx.dir.writeFile(.{ .sub_path = file_path, .data = "" }); - try ctx.dir.access(file_path, .{}); + try ctx.dir.access(io, file_path, .{}); try ctx.dir.deleteTree(dir_path); } }.impl); @@ -2036,13 +2036,13 @@ test "'.' and '..' in Io.Dir functions" { const update_path = try ctx.transformPath("./subdir/../update"); try ctx.dir.makeDir(subdir_path); - try ctx.dir.access(subdir_path, .{}); + try ctx.dir.access(io, subdir_path, .{}); var created_subdir = try ctx.dir.openDir(io, subdir_path, .{}); created_subdir.close(io); const created_file = try ctx.dir.createFile(io, file_path, .{}); created_file.close(io); - try ctx.dir.access(file_path, .{}); + try ctx.dir.access(io, file_path, .{}); try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{}); try ctx.dir.rename(copy_path, rename_path); diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 42429a4993..609cf62e82 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -2842,67 +2842,6 @@ pub fn msync(memory: []align(page_size_min) u8, flags: i32) MSyncError!void { } } -pub const AccessError = error{ - AccessDenied, - PermissionDenied, - FileNotFound, - NameTooLong, - InputOutput, - SystemResources, - FileBusy, - SymLinkLoop, - ReadOnlyFileSystem, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, - Canceled, -} || UnexpectedError; - -/// check user's permissions for a file -/// -/// * On Windows, asserts `path` is valid [WTF-8](https://wtf-8.codeberg.page/). -/// * On WASI, invalid UTF-8 passed to `path` causes `error.BadPathName`. -/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding. -/// -/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by -/// Windows. See `fs` for the cross-platform file system API. -pub fn access(path: []const u8, mode: u32) AccessError!void { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } else if (native_os == .wasi and !builtin.link_libc) { - @compileError("wasi doesn't support absolute paths"); - } - const path_c = try toPosixPath(path); - return accessZ(&path_c, mode); -} - -/// Same as `access` except `path` is null-terminated. -pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } else if (native_os == .wasi and !builtin.link_libc) { - return access(mem.sliceTo(path, 0), mode); - } - switch (errno(system.access(path, mode))) { - .SUCCESS => return, - .ACCES => return error.AccessDenied, - .PERM => return error.PermissionDenied, - .ROFS => return error.ReadOnlyFileSystem, - .LOOP => return error.SymLinkLoop, - .TXTBSY => return error.FileBusy, - .NOTDIR => return error.FileNotFound, - .NOENT => return error.FileNotFound, - .NAMETOOLONG => return error.NameTooLong, - .INVAL => unreachable, - .FAULT => unreachable, - .IO => return error.InputOutput, - .NOMEM => return error.SystemResources, - .ILSEQ => return error.BadPathName, - else => |err| return unexpectedErrno(err), - } -} - pub const PipeError = error{ SystemFdQuotaExceeded, ProcessFdQuotaExceeded, diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 169c5a70c2..af17f1f9ff 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -376,7 +376,7 @@ test "mmap" { const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); - var stream = file.writer(&.{}); + var stream = file.writer(io, &.{}); var i: usize = 0; while (i < alloc_size / @sizeOf(u32)) : (i += 1) { @@ -741,6 +741,8 @@ test "access smoke test" { if (native_os == .windows) return error.SkipZigTest; if (native_os == .openbsd) return error.SkipZigTest; + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); @@ -761,9 +763,9 @@ test "access smoke test" { const file_path = try fs.path.join(a, &.{ base_path, "some_file" }); defer a.free(file_path); if (native_os == .windows) { - try posix.access(file_path, posix.F_OK); + try posix.access(io, file_path, posix.F_OK); } else { - try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK); + try posix.access(io, file_path, posix.F_OK | posix.W_OK | posix.R_OK); } } @@ -771,7 +773,7 @@ test "access smoke test" { // Try to access() a non-existent file - should fail with error.FileNotFound const file_path = try fs.path.join(a, &.{ base_path, "some_other_file" }); defer a.free(file_path); - try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK)); + try expectError(error.FileNotFound, posix.access(io, file_path, posix.F_OK)); } { @@ -786,7 +788,7 @@ test "access smoke test" { const file_path = try fs.path.join(a, &.{ base_path, "some_dir" }); defer a.free(file_path); - try posix.access(file_path, posix.F_OK); + try posix.access(io, file_path, posix.F_OK); } } diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index a5c55d3522..f3dc73838f 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -357,7 +357,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F } if (self.sys_include_dir == null) { - if (search_dir.access(sys_include_dir_example_file, .{})) |_| { + if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| { self.sys_include_dir = try allocator.dupeZ(u8, search_path); } else |err| switch (err) { error.FileNotFound => {}, @@ -402,7 +402,7 @@ fn findNativeIncludeDirWindows( }; defer dir.close(io); - dir.access("stdlib.h", .{}) catch |err| switch (err) { + dir.access(io, "stdlib.h", .{}) catch |err| switch (err) { error.FileNotFound => continue, else => return error.FileSystem, }; @@ -450,7 +450,7 @@ fn findNativeCrtDirWindows( }; defer dir.close(io); - dir.access("ucrt.lib", .{}) catch |err| switch (err) { + dir.access(io, "ucrt.lib", .{}) catch |err| switch (err) { error.FileNotFound => continue, else => return error.FileSystem, }; @@ -518,7 +518,7 @@ fn findNativeKernel32LibDir( }; defer dir.close(io); - dir.access("kernel32.lib", .{}) catch |err| switch (err) { + dir.access(io, "kernel32.lib", .{}) catch |err| switch (err) { error.FileNotFound => continue, else => return error.FileSystem, }; @@ -554,7 +554,7 @@ fn findNativeMsvcIncludeDir( }; defer dir.close(io); - dir.access("vcruntime.h", .{}) catch |err| switch (err) { + dir.access(io, "vcruntime.h", .{}) catch |err| switch (err) { error.FileNotFound => return error.LibCStdLibHeaderNotFound, else => return error.FileSystem, }; diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 443bdcc391..251c87defc 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -9589,8 +9589,8 @@ pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void try b.printToFile(io, file, &buffer); } -pub fn printToFile(b: *Builder, file: Io.File, buffer: []u8) !void { - var fw = file.writer(buffer); +pub fn printToFile(b: *Builder, io: Io, file: Io.File, buffer: []u8) !void { + var fw = file.writer(io, buffer); try print(b, &fw.interface); try fw.interface.flush(); } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 9fa0546c3b..feed21efec 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -40,6 +40,7 @@ pub const GetExternalExecutorOptions = struct { /// Return whether or not the given host is capable of running executables of /// the other target. pub fn getExternalExecutor( + io: Io, host: *const std.Target, candidate: *const std.Target, options: GetExternalExecutorOptions, @@ -70,7 +71,7 @@ pub fn getExternalExecutor( if (os_match and cpu_ok) native: { if (options.link_libc) { if (candidate.dynamic_linker.get()) |candidate_dl| { - Io.Dir.cwd().access(candidate_dl, .{}) catch { + Io.Dir.cwd().access(io, candidate_dl, .{}) catch { bad_result = .{ .bad_dl = candidate_dl }; break :native; }; diff --git a/src/Compilation.zig b/src/Compilation.zig index 280d34cdbf..36429a42f8 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -788,7 +788,7 @@ pub const Directories = struct { const local_cache: Cache.Directory = switch (local_cache_strat) { .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"), .search => d: { - const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| { + const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, io, cwd) catch |err| { fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); }; const path = maybe_path orelse break :d global_cache; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index e54dcb9914..860fb8974e 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -418,7 +418,7 @@ pub fn run(f: *Fetch) RunError!void { const prefixed_pkg_sub_path = prefixed_pkg_sub_path_buffer[0 .. 2 + hash_slice.len]; const prefix_len: usize = if (f.job_queue.read_only) "p/".len else 0; const pkg_sub_path = prefixed_pkg_sub_path[prefix_len..]; - if (cache_root.handle.access(pkg_sub_path, .{})) |_| { + if (cache_root.handle.access(io, pkg_sub_path, .{})) |_| { assert(f.lazy_status != .unavailable); f.package_root = .{ .root_dir = cache_root, @@ -637,8 +637,9 @@ pub fn computedPackageHash(f: *const Fetch) Package.Hash { /// `computeHash` gets a free check for the existence of `build.zig`, but when /// not computing a hash, we need to do a syscall to check for it. fn checkBuildFileExistence(f: *Fetch) RunError!void { + const io = f.job_queue.io; const eb = &f.error_bundle; - if (f.package_root.access(Package.build_zig_basename, .{})) |_| { + if (f.package_root.access(io, Package.build_zig_basename, .{})) |_| { f.has_build_zig = true; } else |err| switch (err) { error.FileNotFound => {}, diff --git a/src/introspect.zig b/src/introspect.zig index a56a214cbe..3f8308961f 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -202,11 +202,11 @@ pub const default_local_zig_cache_basename = ".zig-cache"; /// Searches upwards from `cwd` for a directory containing a `build.zig` file. /// If such a directory is found, returns the path to it joined to the `.zig_cache` name. /// Otherwise, returns `null`, indicating no suitable local cache location. -pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator.Error!?[]u8 { +pub fn resolveSuitableLocalCacheDir(arena: Allocator, io: Io, cwd: []const u8) Allocator.Error!?[]u8 { var cur_dir = cwd; while (true) { const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); - if (Io.Dir.cwd().access(joined, .{})) |_| { + if (Io.Dir.cwd().access(io, joined, .{})) |_| { return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); } else |err| switch (err) { error.FileNotFound => { diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index b3ca51e833..93f88b9689 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -242,7 +242,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const def_file_path = findDef(arena, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { + const def_file_path = findDef(arena, io, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { error.FileNotFound => { log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); // In this case we will end up putting foo.lib onto the linker line and letting the linker @@ -402,11 +402,12 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { pub fn libExists( allocator: Allocator, + io: Io, target: *const std.Target, zig_lib_directory: Cache.Directory, lib_name: []const u8, ) !bool { - const s = findDef(allocator, target, zig_lib_directory, lib_name) catch |err| switch (err) { + const s = findDef(allocator, io, target, zig_lib_directory, lib_name) catch |err| switch (err) { error.FileNotFound => return false, else => |e| return e, }; @@ -418,6 +419,7 @@ pub fn libExists( /// see if a .def file exists. fn findDef( allocator: Allocator, + io: Io, target: *const std.Target, zig_lib_directory: Cache.Directory, lib_name: []const u8, @@ -443,7 +445,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{ lib_path, lib_name }); } - if (Io.Dir.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -460,7 +462,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (Io.Dir.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -477,7 +479,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (Io.Dir.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(io, override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, diff --git a/src/link/C.zig b/src/link/C.zig index a001f8fdd9..db5acebf07 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -371,6 +371,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P const comp = self.base.comp; const diags = &comp.link_diags; const gpa = comp.gpa; + const io = comp.io; const zcu = self.base.comp.zcu.?; const ip = &zcu.intern_pool; const pt: Zcu.PerThread = .activate(zcu, tid); @@ -509,7 +510,7 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P const file = self.base.file.?; file.setEndPos(f.file_size) catch |err| return diags.fail("failed to allocate file: {s}", .{@errorName(err)}); - var fw = file.writer(&.{}); + var fw = file.writer(io, &.{}); var w = &fw.interface; w.writeVecAll(f.all_buffers.items) catch |err| switch (err) { error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{ diff --git a/src/link/Lld.zig b/src/link/Lld.zig index b25b9da9d9..ca15a38bb0 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -359,6 +359,7 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { fn coffLink(lld: *Lld, arena: Allocator) !void { const comp = lld.base.comp; const gpa = comp.gpa; + const io = comp.io; const base = &lld.base; const coff = &lld.ofmt.coff; @@ -718,13 +719,13 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { argv.appendAssumeCapacity(try crt_file.full_object_path.toString(arena)); continue; } - if (try findLib(arena, lib_basename, coff.lib_directories)) |full_path| { + if (try findLib(arena, io, lib_basename, coff.lib_directories)) |full_path| { argv.appendAssumeCapacity(full_path); continue; } if (target.abi.isGnu()) { const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key}); - if (try findLib(arena, fallback_name, coff.lib_directories)) |full_path| { + if (try findLib(arena, io, fallback_name, coff.lib_directories)) |full_path| { argv.appendAssumeCapacity(full_path); continue; } @@ -741,9 +742,9 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { try spawnLld(comp, arena, argv.items); } } -fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Cache.Directory) !?[]const u8 { +fn findLib(arena: Allocator, io: Io, name: []const u8, lib_directories: []const Cache.Directory) !?[]const u8 { for (lib_directories) |lib_directory| { - lib_directory.handle.access(name, .{}) catch |err| switch (err) { + lib_directory.handle.access(io, name, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 78e035e2ad..6cd906340a 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -829,7 +829,8 @@ pub fn resolveLibSystem( comp: *Compilation, out_libs: anytype, ) !void { - const diags = &self.base.comp.link_diags; + const io = comp.io; + const diags = &comp.link_diags; var test_path = std.array_list.Managed(u8).init(arena); var checked_paths = std.array_list.Managed([]const u8).init(arena); @@ -838,16 +839,16 @@ pub fn resolveLibSystem( if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { .sdk => { const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" }); - if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; + if (try accessLibPath(arena, io, &test_path, &checked_paths, dir, "System")) break :success; }, .vendored => { const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" }); - if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; + if (try accessLibPath(arena, io, &test_path, &checked_paths, dir, "System")) break :success; }, }; for (self.lib_directories) |directory| { - if (try accessLibPath(arena, &test_path, &checked_paths, directory.path orelse ".", "System")) break :success; + if (try accessLibPath(arena, io, &test_path, &checked_paths, directory.path orelse ".", "System")) break :success; } diags.addMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{}); @@ -1074,6 +1075,7 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool { /// TODO delete this, libraries must be instead resolved when instantiating the compilation pipeline fn accessLibPath( arena: Allocator, + io: Io, test_path: *std.array_list.Managed(u8), checked_paths: *std.array_list.Managed([]const u8), search_dir: []const u8, @@ -1085,7 +1087,7 @@ fn accessLibPath( test_path.clearRetainingCapacity(); try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1097,6 +1099,7 @@ fn accessLibPath( fn accessFrameworkPath( arena: Allocator, + io: Io, test_path: *std.array_list.Managed(u8), checked_paths: *std.array_list.Managed([]const u8), search_dir: []const u8, @@ -1113,7 +1116,7 @@ fn accessFrameworkPath( ext, }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1172,14 +1175,14 @@ fn parseDependentDylibs(self: *MachO) !void { // Framework for (framework_dirs) |dir| { test_path.clearRetainingCapacity(); - if (try accessFrameworkPath(arena, &test_path, &checked_paths, dir, stem)) break :full_path test_path.items; + if (try accessFrameworkPath(arena, io, &test_path, &checked_paths, dir, stem)) break :full_path test_path.items; } // Library const lib_name = eatPrefix(stem, "lib") orelse stem; for (lib_directories) |lib_directory| { test_path.clearRetainingCapacity(); - if (try accessLibPath(arena, &test_path, &checked_paths, lib_directory.path orelse ".", lib_name)) break :full_path test_path.items; + if (try accessLibPath(arena, io, &test_path, &checked_paths, lib_directory.path orelse ".", lib_name)) break :full_path test_path.items; } } @@ -1194,7 +1197,7 @@ fn parseDependentDylibs(self: *MachO) !void { try test_path.print("{s}{s}", .{ path, ext }); } try checked_paths.append(try arena.dupe(u8, test_path.items)); - Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; diff --git a/src/main.zig b/src/main.zig index a063591b64..99850f5ffe 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3208,6 +3208,7 @@ fn buildOutputType( for (create_module.framework_dirs.items) |framework_dir_path| { if (try accessFrameworkPath( + io, &test_path, &checked_paths, framework_dir_path, @@ -6626,7 +6627,7 @@ fn warnAboutForeignBinaries( const host_query: std.Target.Query = .{}; const host_target = std.zig.resolveTargetQueryOrFatal(io, host_query); - switch (std.zig.system.getExternalExecutor(&host_target, target, .{ .link_libc = link_libc })) { + switch (std.zig.system.getExternalExecutor(io, &host_target, target, .{ .link_libc = link_libc })) { .native => return, .rosetta => { const host_name = try host_target.zigTriple(arena); @@ -6832,6 +6833,7 @@ const ClangSearchSanitizer = struct { }; fn accessFrameworkPath( + io: Io, test_path: *std.array_list.Managed(u8), checked_paths: *std.array_list.Managed(u8), framework_dir_path: []const u8, @@ -6845,7 +6847,7 @@ fn accessFrameworkPath( framework_dir_path, framework_name, framework_name, ext, }); try checked_paths.print("\n {s}", .{test_path.items}); - Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(io, test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{ ext, test_path.items, @errorName(e), @@ -7280,7 +7282,7 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build var dirname: []const u8 = cwd_path; while (true) { const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); - if (Io.Dir.cwd().access(joined_path, .{})) |_| { + if (Io.Dir.cwd().access(io, joined_path, .{})) |_| { const dir = Io.Dir.cwd().openDir(io, dirname, .{}) catch |err| { fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); }; -- cgit v1.2.3 From 4218344dd3178f2fd3d9d00e9ff6895ee344df6d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 17:21:52 -0800 Subject: std.Build.Cache: remove readSmallFile and writeSmallFile These were to support optimizations involving detecting when to avoid calling into LLD, which are no longer implemented. --- lib/compiler/build_runner.zig | 2 +- lib/compiler/reduce.zig | 12 +++++--- lib/compiler/resinator/main.zig | 2 +- lib/compiler/std-docs.zig | 2 +- lib/std/Build/Cache.zig | 36 ++++-------------------- lib/std/Build/Step/ConfigHeader.zig | 2 +- lib/std/Build/Step/Run.zig | 2 +- lib/std/Build/Step/UpdateSourceFiles.zig | 2 +- lib/std/Build/Step/WriteFile.zig | 2 +- lib/std/Build/WebServer.zig | 2 +- lib/std/debug.zig | 4 +-- lib/std/fs/test.zig | 48 +++++++++++++++++++------------- lib/std/posix/test.zig | 2 +- src/Compilation.zig | 4 +-- src/libs/freebsd.zig | 4 +-- src/libs/glibc.zig | 4 +-- src/libs/netbsd.zig | 2 +- src/main.zig | 6 ++-- 18 files changed, 63 insertions(+), 75 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 36c73e96eb..9150d84470 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -459,7 +459,7 @@ pub fn main() !void { } const s = std.fs.path.sep_str; const tmp_sub_path = "tmp" ++ s ++ (output_tmp_nonce orelse fatal("missing -Z arg", .{})); - local_cache_directory.handle.writeFile(.{ + local_cache_directory.handle.writeFile(io, .{ .sub_path = tmp_sub_path, .data = buffer.items, .flags = .{ .exclusive = true }, diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index d3f33ad81a..0bfa1902ab 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -55,6 +55,10 @@ pub fn main() !void { var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; const gpa = general_purpose_allocator.allocator(); + var threaded: std.Io.Threaded = .init(gpa); + defer threaded.deinit(); + const io = threaded.io(); + const args = try std.process.argsAlloc(arena); var opt_checker_path: ?[]const u8 = null; @@ -233,12 +237,12 @@ pub fn main() !void { } } - try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(io, .{ .sub_path = root_source_file_path, .data = rendered.written() }); // std.debug.print("trying this code:\n{s}\n", .{rendered.items}); const interestingness = try runCheck(arena, interestingness_argv.items); - std.debug.print("{d} random transformations: {s}. {d}/{d}\n", .{ - subset_size, @tagName(interestingness), start_index, transformations.items.len, + std.debug.print("{d} random transformations: {t}. {d}/{d}\n", .{ + subset_size, interestingness, start_index, transformations.items.len, }); switch (interestingness) { .interesting => { @@ -274,7 +278,7 @@ pub fn main() !void { fixups.clearRetainingCapacity(); rendered.clearRetainingCapacity(); try tree.render(gpa, &rendered.writer, fixups); - try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(io, .{ .sub_path = root_source_file_path, .data = rendered.written() }); return std.process.cleanExit(); } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 1a6ef5eea3..afe1dcbe91 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -212,7 +212,7 @@ pub fn main() !void { try output_file.writeAll(full_input); }, .filename => |output_filename| { - try Io.Dir.cwd().writeFile(.{ .sub_path = output_filename, .data = full_input }); + try Io.Dir.cwd().writeFile(io, .{ .sub_path = output_filename, .data = full_input }); }, } return; diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index f1382e6eae..8f02f05958 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -233,7 +233,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { .interface = std.Io.File.Reader.initInterface(&.{}), .size = stat.size, }; - try archiver.writeFile(entry.path, &file_reader, stat.mtime); + try archiver.writeFile(io, entry.path, &file_reader, stat.mtime); } { diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index dab1926f53..f7c4d729bc 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1276,30 +1276,6 @@ pub const Manifest = struct { } }; -/// On operating systems that support symlinks, does a readlink. On other operating systems, -/// uses the file contents. Windows supports symlinks but only with elevated privileges, so -/// it is treated as not supporting symlinks. -pub fn readSmallFile(dir: Io.Dir, sub_path: []const u8, buffer: []u8) ![]u8 { - if (builtin.os.tag == .windows) { - return dir.readFile(sub_path, buffer); - } else { - return dir.readLink(sub_path, buffer); - } -} - -/// On operating systems that support symlinks, does a symlink. On other operating systems, -/// uses the file contents. Windows supports symlinks but only with elevated privileges, so -/// it is treated as not supporting symlinks. -/// `data` must be a valid UTF-8 encoded file path and 255 bytes or fewer. -pub fn writeSmallFile(dir: Io.Dir, sub_path: []const u8, data: []const u8) !void { - assert(data.len <= 255); - if (builtin.os.tag == .windows) { - return dir.writeFile(.{ .sub_path = sub_path, .data = data }); - } else { - return dir.symLink(data, sub_path, .{}); - } -} - fn hashFile(io: Io, file: Io.File, bin_digest: *[Hasher.mac_length]u8) Io.File.ReadPositionalError!void { var buffer: [2048]u8 = undefined; var hasher = hasher_init; @@ -1338,7 +1314,7 @@ test "cache file and then recall it" { const temp_file = "test.txt"; const temp_manifest_dir = "temp_manifest_dir"; - try tmp.dir.writeFile(.{ .sub_path = temp_file, .data = "Hello, world!\n" }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file, .data = "Hello, world!\n" }); // Wait for file timestamps to tick const initial_time = try testGetCurrentFileTimestamp(io, tmp.dir); @@ -1404,7 +1380,7 @@ test "check that changing a file makes cache fail" { const original_temp_file_contents = "Hello, world!\n"; const updated_temp_file_contents = "Hello, world; but updated!\n"; - try tmp.dir.writeFile(.{ .sub_path = temp_file, .data = original_temp_file_contents }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file, .data = original_temp_file_contents }); // Wait for file timestamps to tick const initial_time = try testGetCurrentFileTimestamp(tmp.dir); @@ -1441,7 +1417,7 @@ test "check that changing a file makes cache fail" { try ch.writeManifest(); } - try tmp.dir.writeFile(.{ .sub_path = temp_file, .data = updated_temp_file_contents }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file, .data = updated_temp_file_contents }); { var ch = cache.obtain(); @@ -1521,8 +1497,8 @@ test "Manifest with files added after initial hash work" { const temp_file2 = "cache_hash_post_file_test2.txt"; const temp_manifest_dir = "cache_hash_post_file_manifest_dir"; - try tmp.dir.writeFile(.{ .sub_path = temp_file1, .data = "Hello, world!\n" }); - try tmp.dir.writeFile(.{ .sub_path = temp_file2, .data = "Hello world the second!\n" }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file1, .data = "Hello, world!\n" }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second!\n" }); // Wait for file timestamps to tick const initial_time = try testGetCurrentFileTimestamp(tmp.dir); @@ -1573,7 +1549,7 @@ test "Manifest with files added after initial hash work" { try testing.expect(mem.eql(u8, &digest1, &digest2)); // Modify the file added after initial hash - try tmp.dir.writeFile(.{ .sub_path = temp_file2, .data = "Hello world the second, updated\n" }); + try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second, updated\n" }); // Wait for file timestamps to tick const initial_time2 = try testGetCurrentFileTimestamp(tmp.dir); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index f377959610..589110d4c4 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -264,7 +264,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { }); }; - b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = output }) catch |err| { + b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = output }) catch |err| { return step.fail("unable to write file '{f}{s}': {s}", .{ b.cache_root, sub_path, @errorName(err), }); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index f6b29635c1..a1618beb02 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1482,7 +1482,7 @@ fn runCommand( .leading => mem.trimStart(u8, stream.bytes.?, &std.ascii.whitespace), .trailing => mem.trimEnd(u8, stream.bytes.?, &std.ascii.whitespace), }; - b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = data }) catch |err| { + b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = data }) catch |err| { return step.fail("unable to write file '{f}{s}': {s}", .{ b.cache_root, sub_path, @errorName(err), }); diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig index 44c6ae1ed4..eb8a6a85dd 100644 --- a/lib/std/Build/Step/UpdateSourceFiles.zig +++ b/lib/std/Build/Step/UpdateSourceFiles.zig @@ -84,7 +84,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { } switch (output_source_file.contents) { .bytes => |bytes| { - b.build_root.handle.writeFile(.{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| { + b.build_root.handle.writeFile(io, .{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| { return step.fail("unable to write file '{f}{s}': {t}", .{ b.build_root, output_source_file.sub_path, err, }); diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 94b04b4212..3d712fa1d4 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -273,7 +273,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { } switch (file.contents) { .bytes => |bytes| { - cache_dir.writeFile(.{ .sub_path = file.sub_path, .data = bytes }) catch |err| { + cache_dir.writeFile(io, .{ .sub_path = file.sub_path, .data = bytes }) catch |err| { return step.fail("unable to write file '{f}{s}{c}{s}': {t}", .{ b.cache_root, cache_path, fs.path.sep, file.sub_path, err, }); diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index 162d17f070..ed07d04d57 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -523,7 +523,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons if (cached_cwd_path == null) cached_cwd_path = try std.process.getCwdAlloc(gpa); break :cwd cached_cwd_path.?; }; - try archiver.writeFile(path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds())); + try archiver.writeFile(io, path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds())); } // intentionally not calling `archiver.finishPedantically` diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 39207f938d..cb79bb7855 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1243,7 +1243,7 @@ test printLineFromFile { { const path = try join(gpa, &.{ test_dir_path, "one_line.zig" }); defer gpa.free(path); - try test_dir.dir.writeFile(.{ .sub_path = "one_line.zig", .data = "no new lines in this file, but one is printed anyway" }); + try test_dir.dir.writeFile(io, .{ .sub_path = "one_line.zig", .data = "no new lines in this file, but one is printed anyway" }); try expectError(error.EndOfFile, printLineFromFile(io, output_stream, .{ .file_name = path, .line = 2, .column = 0 })); @@ -1254,7 +1254,7 @@ test printLineFromFile { { const path = try fs.path.join(gpa, &.{ test_dir_path, "three_lines.zig" }); defer gpa.free(path); - try test_dir.dir.writeFile(.{ + try test_dir.dir.writeFile(io, .{ .sub_path = "three_lines.zig", .data = \\1 diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 59bacff2d0..59e0990eb0 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -184,7 +184,7 @@ test "Dir.readLink" { fn impl(ctx: *TestContext) !void { // Create some targets const file_target_path = try ctx.transformPath("file.txt"); - try ctx.dir.writeFile(.{ .sub_path = file_target_path, .data = "nonsense" }); + try ctx.dir.writeFile(io, .{ .sub_path = file_target_path, .data = "nonsense" }); const dir_target_path = try ctx.transformPath("subdir"); try ctx.dir.makeDir(dir_target_path); @@ -487,11 +487,13 @@ test "readLinkAbsolute" { if (native_os == .wasi) return error.SkipZigTest; if (native_os == .openbsd) return error.SkipZigTest; + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); // Create some targets - try tmp.dir.writeFile(.{ .sub_path = "file.txt", .data = "nonsense" }); + try tmp.dir.writeFile(io, .{ .sub_path = "file.txt", .data = "nonsense" }); try tmp.dir.makeDir("subdir"); // Get base abs path @@ -708,6 +710,7 @@ test "Dir.realpath smoke test" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const allocator = ctx.arena.allocator(); const test_file_path = try ctx.transformPath("test_file"); const test_dir_path = try ctx.transformPath("test_dir"); @@ -720,7 +723,7 @@ test "Dir.realpath smoke test" { try testing.expectError(error.FileNotFound, ctx.dir.realpath(test_dir_path, &buf)); // Now create the file and dir - try ctx.dir.writeFile(.{ .sub_path = test_file_path, .data = "" }); + try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); try ctx.dir.makeDir(test_dir_path); const base_path = try ctx.transformPath("."); @@ -803,11 +806,12 @@ test "readFileAlloc" { test "Dir.statFile" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const test_file_name = try ctx.transformPath("test_file"); try testing.expectError(error.FileNotFound, ctx.dir.statFile(test_file_name)); - try ctx.dir.writeFile(.{ .sub_path = test_file_name, .data = "" }); + try ctx.dir.writeFile(io, .{ .sub_path = test_file_name, .data = "" }); const stat = try ctx.dir.statFile(test_file_name); try testing.expectEqual(File.Kind.file, stat.kind); @@ -925,6 +929,7 @@ test "makeOpenPath parent dirs do not exist" { test "deleteDir" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const test_dir_path = try ctx.transformPath("test_dir"); const test_file_path = try ctx.transformPath("test_dir" ++ fs.path.sep_str ++ "test_file"); @@ -933,7 +938,7 @@ test "deleteDir" { // deleting a non-empty directory try ctx.dir.makeDir(test_dir_path); - try ctx.dir.writeFile(.{ .sub_path = test_file_path, .data = "" }); + try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); // deleting an empty directory @@ -1217,7 +1222,7 @@ test "deleteTree on a symlink" { defer tmp.cleanup(); // Symlink to a file - try tmp.dir.writeFile(.{ .sub_path = "file", .data = "" }); + try tmp.dir.writeFile(io, .{ .sub_path = "file", .data = "" }); try setupSymlink(tmp.dir, "file", "filelink", .{}); try tmp.dir.deleteTree("filelink"); @@ -1241,11 +1246,11 @@ test "makePath, put some files in it, deleteTree" { const dir_path = try ctx.transformPath("os_test_tmp"); try ctx.dir.makePath(io, try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); - try ctx.dir.writeFile(.{ + try ctx.dir.writeFile(io, .{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", }); - try ctx.dir.writeFile(.{ + try ctx.dir.writeFile(io, .{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "file2.txt" }), .data = "blah", }); @@ -1264,11 +1269,11 @@ test "makePath, put some files in it, deleteTreeMinStackSize" { const dir_path = try ctx.transformPath("os_test_tmp"); try ctx.dir.makePath(io, try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); - try ctx.dir.writeFile(.{ + try ctx.dir.writeFile(io, .{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", }); - try ctx.dir.writeFile(.{ + try ctx.dir.writeFile(io, .{ .sub_path = try fs.path.join(allocator, &.{ "os_test_tmp", "b", "file2.txt" }), .data = "blah", }); @@ -1298,7 +1303,7 @@ test "makePath but sub_path contains pre-existing file" { defer tmp.cleanup(); try tmp.dir.makeDir("foo"); - try tmp.dir.writeFile(.{ .sub_path = "foo/bar", .data = "" }); + try tmp.dir.writeFile(io, .{ .sub_path = "foo/bar", .data = "" }); try testing.expectError(error.NotDir, tmp.dir.makePath(io, "foo/bar/baz")); } @@ -1400,7 +1405,7 @@ fn testFilenameLimits(io: Io, iterable_dir: Dir, maxed_filename: []const u8) !vo var maxed_dir = try iterable_dir.makeOpenPath(maxed_filename, .{}); defer maxed_dir.close(io); - try maxed_dir.writeFile(.{ .sub_path = maxed_filename, .data = "" }); + try maxed_dir.writeFile(io, .{ .sub_path = maxed_filename, .data = "" }); var walker = try iterable_dir.walk(testing.allocator); defer walker.deinit(); @@ -1513,7 +1518,7 @@ test "setEndPos" { defer tmp.cleanup(); const file_name = "afile.txt"; - try tmp.dir.writeFile(.{ .sub_path = file_name, .data = "ninebytes" }); + try tmp.dir.writeFile(io, .{ .sub_path = file_name, .data = "ninebytes" }); const f = try tmp.dir.openFile(io, file_name, .{ .mode = .read_write }); defer f.close(io); @@ -1563,7 +1568,7 @@ test "access file" { try ctx.dir.makePath(io, dir_path); try testing.expectError(error.FileNotFound, ctx.dir.access(io, file_path, .{})); - try ctx.dir.writeFile(.{ .sub_path = file_path, .data = "" }); + try ctx.dir.writeFile(io, .{ .sub_path = file_path, .data = "" }); try ctx.dir.access(io, file_path, .{}); try ctx.dir.deleteTree(dir_path); } @@ -1659,12 +1664,13 @@ test "sendfile with buffered data" { test "copyFile" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const data = "u6wj+JmdF3qHsFPE BUlH2g4gJCmEz0PP"; const src_file = try ctx.transformPath("tmp_test_copy_file.txt"); const dest_file = try ctx.transformPath("tmp_test_copy_file2.txt"); const dest_file2 = try ctx.transformPath("tmp_test_copy_file3.txt"); - try ctx.dir.writeFile(.{ .sub_path = src_file, .data = data }); + try ctx.dir.writeFile(io, .{ .sub_path = src_file, .data = data }); defer ctx.dir.deleteFile(src_file) catch {}; try ctx.dir.copyFile(src_file, ctx.dir, dest_file, .{}); @@ -2050,7 +2056,7 @@ test "'.' and '..' in Io.Dir functions" { renamed_file.close(io); try ctx.dir.deleteFile(rename_path); - try ctx.dir.writeFile(.{ .sub_path = update_path, .data = "something" }); + try ctx.dir.writeFile(io, .{ .sub_path = update_path, .data = "something" }); var dir = ctx.dir; const prev_status = try dir.updateFile(io, file_path, dir, update_path, .{}); try testing.expectEqual(Io.Dir.PrevStatus.stale, prev_status); @@ -2187,7 +2193,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.deleteTree(invalid_path)); try testing.expectError(expected_err, ctx.dir.deleteTreeMinStackSize(invalid_path)); - try testing.expectError(expected_err, ctx.dir.writeFile(.{ .sub_path = invalid_path, .data = "" })); + try testing.expectError(expected_err, ctx.dir.writeFile(io, .{ .sub_path = invalid_path, .data = "" })); try testing.expectError(expected_err, ctx.dir.access(invalid_path, .{})); @@ -2304,7 +2310,7 @@ test "seekBy" { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - try tmp_dir.dir.writeFile(.{ .sub_path = "blah.txt", .data = "let's test seekBy" }); + try tmp_dir.dir.writeFile(io, .{ .sub_path = "blah.txt", .data = "let's test seekBy" }); const f = try tmp_dir.dir.openFile(io, "blah.txt", .{ .mode = .read_only }); defer f.close(io); var reader = f.readerStreaming(io, &.{}); @@ -2350,7 +2356,7 @@ test "File.Writer sendfile with buffered contents" { defer tmp_dir.cleanup(); { - try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); + try tmp_dir.dir.writeFile(io, .{ .sub_path = "a", .data = "bcd" }); const in = try tmp_dir.dir.openFile(io, "a", .{}); defer in.close(io); const out = try tmp_dir.dir.createFile(io, "b", .{}); @@ -2391,11 +2397,13 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void { } test "readlinkat" { + const io = testing.io; + var tmp = tmpDir(.{}); defer tmp.cleanup(); // create file - try tmp.dir.writeFile(.{ .sub_path = "file.txt", .data = "nonsense" }); + try tmp.dir.writeFile(io, .{ .sub_path = "file.txt", .data = "nonsense" }); // create a symbolic link if (native_os == .windows) { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index af17f1f9ff..bacfdacf83 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -145,7 +145,7 @@ test "linkat with different directories" { const subdir = try tmp.dir.makeOpenPath("subdir", .{}); defer tmp.dir.deleteFile(target_name) catch {}; - try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "example" }); + try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); // Test 1: link from file in subdir back up to target in parent directory try posix.linkat(tmp.dir.handle, target_name, subdir.handle, link_name, 0); diff --git a/src/Compilation.zig b/src/Compilation.zig index 36429a42f8..7fe217b385 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5715,7 +5715,7 @@ pub fn translateC( const out_h_sub_path = tmp_sub_path ++ fs.path.sep_str ++ cimport_basename; const out_h_path = try comp.dirs.local_cache.join(arena, &.{out_h_sub_path}); if (comp.verbose_cimport) log.info("writing C import source to {s}", .{out_h_path}); - try cache_dir.writeFile(.{ .sub_path = out_h_sub_path, .data = c_src }); + try cache_dir.writeFile(io, .{ .sub_path = out_h_sub_path, .data = c_src }); break :path out_h_path; }, .path => |p| p, @@ -6572,7 +6572,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 resource_id, resource_type, fmtRcEscape(src_path), }); - try o_dir.writeFile(.{ .sub_path = rc_basename, .data = input }); + try o_dir.writeFile(io, .{ .sub_path = rc_basename, .data = input }); var argv = std.array_list.Managed([]const u8).init(comp.gpa); defer argv.deinit(); diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index cfd8d5554c..77bd4372d0 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -520,7 +520,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye for (metadata.all_versions[0 .. target_ver_index + 1]) |ver| { try map_contents.print("FBSD_{d}.{d} {{ }};\n", .{ ver.major, ver.minor }); } - try o_directory.handle.writeFile(.{ .sub_path = all_map_basename, .data = map_contents.items }); + try o_directory.handle.writeFile(io, .{ .sub_path = all_map_basename, .data = map_contents.items }); map_contents.deinit(); } @@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc. const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; - try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); + try o_directory.handle.writeFile(io, .{ .sub_path = asm_file_basename, .data = stubs_asm.items }); try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); } diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index e3d8ce1f7f..a60dc921be 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -759,7 +759,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye try map_contents.print("GLIBC_{d}.{d}.{d} {{ }};\n", .{ ver.major, ver.minor, ver.patch }); } } - try o_directory.handle.writeFile(.{ .sub_path = all_map_basename, .data = map_contents.items }); + try o_directory.handle.writeFile(io, .{ .sub_path = all_map_basename, .data = map_contents.items }); map_contents.deinit(); // The most recent allocation of an arena can be freed :) } @@ -1118,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; - try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); + try o_directory.handle.writeFile(io, .{ .sub_path = asm_file_basename, .data = stubs_asm.items }); try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); } diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index cb6a80d69d..fd80616e9d 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -628,7 +628,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; - try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); + try o_directory.handle.writeFile(io, .{ .sub_path = asm_file_basename, .data = stubs_asm.items }); try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); } diff --git a/src/main.zig b/src/main.zig index 99850f5ffe..bef3a3efb5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -7164,7 +7164,7 @@ fn cmdFetch( try ast.render(gpa, &aw.writer, fixups); const rendered = aw.written(); - build_root.directory.handle.writeFile(.{ .sub_path = Package.Manifest.basename, .data = rendered }) catch |err| { + build_root.directory.handle.writeFile(io, .{ .sub_path = Package.Manifest.basename, .data = rendered }) catch |err| { fatal("unable to write {s} file: {t}", .{ Package.Manifest.basename, err }); }; @@ -7207,7 +7207,7 @@ fn createDependenciesModule( { var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); defer tmp_dir.close(io); - try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); + try tmp_dir.writeFile(io, .{ .sub_path = basename, .data = source }); } var hh: Cache.HashHelper = .{}; @@ -7438,7 +7438,7 @@ const Templates = struct { i += 1; } - return out_dir.writeFile(.{ + return out_dir.writeFile(io, .{ .sub_path = template_path, .data = templates.buffer.items, .flags = .{ .exclusive = true }, -- cgit v1.2.3 From 4be8be1d2bd6959efae7df95e3f5713adf953a42 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 17:45:17 -0800 Subject: update all rename() to rename(io) --- lib/compiler/build_runner.zig | 8 ++++---- lib/compiler/objcopy.zig | 2 +- lib/std/Build/Cache.zig | 4 ++-- lib/std/Build/Fuzz.zig | 1 + lib/std/Build/Step/Compile.zig | 6 +++--- lib/std/Build/Step/Options.zig | 2 +- lib/std/Build/Step/Run.zig | 22 ++++++++-------------- lib/std/Build/WebServer.zig | 6 +++--- lib/std/Io.zig | 2 +- lib/std/Io/Dir.zig | 11 +++++++++-- lib/std/fs/test.zig | 38 +++++++++++++++++++------------------- lib/std/posix/test.zig | 4 ++-- lib/std/tar.zig | 2 +- lib/std/zip.zig | 2 +- src/Compilation.zig | 6 +++--- src/Package/Fetch.zig | 12 ++++++------ src/Package/Fetch/git.zig | 4 ++-- src/Zcu.zig | 14 ++++++++++---- src/Zcu/PerThread.zig | 12 ++++++------ src/libs/mingw.zig | 2 +- src/link.zig | 2 +- src/link/Lld.zig | 2 +- src/main.zig | 8 ++------ 23 files changed, 88 insertions(+), 84 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 9150d84470..677158645d 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -478,14 +478,14 @@ pub fn main() !void { validateSystemLibraryOptions(builder); if (help_menu) { - var w = initStdoutWriter(); + var w = initStdoutWriter(io); printUsage(builder, w) catch return stdout_writer_allocation.err.?; w.flush() catch return stdout_writer_allocation.err.?; return; } if (steps_menu) { - var w = initStdoutWriter(); + var w = initStdoutWriter(io); printSteps(builder, w) catch return stdout_writer_allocation.err.?; w.flush() catch return stdout_writer_allocation.err.?; return; @@ -1847,7 +1847,7 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { var stdio_buffer_allocation: [256]u8 = undefined; var stdout_writer_allocation: Io.File.Writer = undefined; -fn initStdoutWriter() *Writer { - stdout_writer_allocation = Io.File.stdout().writerStreaming(&stdio_buffer_allocation); +fn initStdoutWriter(io: Io) *Writer { + stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); return &stdout_writer_allocation.interface; } diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index 6473a10dd0..d9b9b33186 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -183,7 +183,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void var output_file = try Io.Dir.cwd().createFile(io, output, .{ .mode = mode }); defer output_file.close(io); - var out = output_file.writer(&output_buffer); + var out = output_file.writer(io, &output_buffer); switch (out_fmt) { .hex, .raw => { diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index f7c4d729bc..2d6dbc02fa 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1134,13 +1134,13 @@ pub const Manifest = struct { /// lock from exclusive to shared. pub fn writeManifest(self: *Manifest) !void { assert(self.have_exclusive_lock); - + const io = self.cache.io; const manifest_file = self.manifest_file.?; if (self.manifest_dirty) { self.manifest_dirty = false; var buffer: [4000]u8 = undefined; - var fw = manifest_file.writer(&buffer); + var fw = manifest_file.writer(io, &buffer); writeDirtyManifestToStream(self, &fw) catch |err| switch (err) { error.WriteFailed => return fw.err.?, else => |e| return e, diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index 8d5bc27f3a..8fedb7e067 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -389,6 +389,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO const target = run_step.producer.?.rootModuleTarget(); var debug_info = std.debug.Info.load( fuzz.gpa, + io, rebuilt_exe_path, &gop.value_ptr.coverage, target.ofmt, diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 4f1e83a573..dfa5460981 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -1709,7 +1709,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { defer b.cache_root.handle.deleteFile(io, tmp_path) catch { // It's fine if the temporary file can't be cleaned up. }; - b.cache_root.handle.rename(io, tmp_path, args_file) catch |rename_err| switch (rename_err) { + b.cache_root.handle.rename(tmp_path, b.cache_root.handle, args_file, io) catch |rename_err| switch (rename_err) { error.PathAlreadyExists => { // The args file was created by another concurrent build process. }, @@ -1827,14 +1827,14 @@ pub fn doAtomicSymLinks( // sym link for libfoo.so.1 to libfoo.so.1.2.3 const major_only_path = b.pathJoin(&.{ out_dir, filename_major_only }); const cwd: Io.Dir = .cwd(); - cwd.atomicSymLink(io, out_basename, major_only_path, .{}) catch |err| { + cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| { return step.fail("unable to symlink {s} -> {s}: {s}", .{ major_only_path, out_basename, @errorName(err), }); }; // sym link for libfoo.so to libfoo.so.1 const name_only_path = b.pathJoin(&.{ out_dir, filename_name_only }); - cwd.atomicSymLink(io, filename_major_only, name_only_path, .{}) catch |err| { + cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| { return step.fail("Unable to symlink {s} -> {s}: {s}", .{ name_only_path, filename_major_only, @errorName(err), }); diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 1416e0e916..676ea4d851 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -498,7 +498,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { }); }; - b.cache_root.handle.rename(io, tmp_sub_path, sub_path) catch |err| switch (err) { + b.cache_root.handle.rename(tmp_sub_path, b.cache_root.handle, sub_path, io) catch |err| switch (err) { error.PathAlreadyExists => { // Other process beat us to it. Clean up the temp file. b.cache_root.handle.deleteFile(io, tmp_sub_path) catch |e| { diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index a1618beb02..e52dd21a96 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1042,27 +1042,21 @@ fn make(step: *Step, options: Step.MakeOptions) !void { if (any_output) { const o_sub_path = "o" ++ fs.path.sep_str ++ &digest; - b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |err| { + b.cache_root.handle.rename(tmp_dir_path, b.cache_root.handle, o_sub_path, io) catch |err| { if (err == error.PathAlreadyExists) { b.cache_root.handle.deleteTree(o_sub_path) catch |del_err| { - return step.fail("unable to remove dir '{f}'{s}: {s}", .{ - b.cache_root, - tmp_dir_path, - @errorName(del_err), + return step.fail("unable to remove dir '{f}'{s}: {t}", .{ + b.cache_root, tmp_dir_path, del_err, }); }; - b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |retry_err| { - return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{ - b.cache_root, tmp_dir_path, - b.cache_root, o_sub_path, - @errorName(retry_err), + b.cache_root.handle.rename(tmp_dir_path, b.cache_root.handle, o_sub_path, io) catch |retry_err| { + return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ + b.cache_root, tmp_dir_path, b.cache_root, o_sub_path, retry_err, }); }; } else { - return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{ - b.cache_root, tmp_dir_path, - b.cache_root, o_sub_path, - @errorName(err), + return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {t}", .{ + b.cache_root, tmp_dir_path, b.cache_root, o_sub_path, err, }); } }; diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index ed07d04d57..38a7a73588 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -523,7 +523,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons if (cached_cwd_path == null) cached_cwd_path = try std.process.getCwdAlloc(gpa); break :cwd cached_cwd_path.?; }; - try archiver.writeFile(io, path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds())); + try archiver.writeFile(path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds())); } // intentionally not calling `archiver.finishPedantically` @@ -587,7 +587,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim }); defer poller.deinit(); - try child.stdin.?.writeAll(@ptrCast(@as([]const std.zig.Client.Message.Header, &.{ + try child.stdin.?.writeStreamingAll(io, @ptrCast(@as([]const std.zig.Client.Message.Header, &.{ .{ .tag = .update, .bytes_len = 0 }, .{ .tag = .exit, .bytes_len = 0 }, }))); @@ -638,7 +638,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim child.stdin.?.close(io); child.stdin = null; - switch (try child.wait()) { + switch (try child.wait(io)) { .Exited => |code| { if (code != 0) { log.err( diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 7f5f049d34..193998f037 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -677,7 +677,7 @@ pub const VTable = struct { dirDeleteFile: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void, dirDeleteDir: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteDirError!void, dirRename: *const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenameError!void, - dirSymLink: *const fn (?*anyopaque, Dir, target_path: []const u8, sym_link_path: []const u8, Dir.SymLinkFlags) Dir.RenameError!void, + dirSymLink: *const fn (?*anyopaque, Dir, target_path: []const u8, sym_link_path: []const u8, Dir.SymLinkFlags) Dir.SymLinkError!void, dirReadLink: *const fn (?*anyopaque, Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize, dirSetOwner: *const fn (?*anyopaque, Dir, ?File.Uid, ?File.Gid) Dir.SetOwnerError!void, dirSetPermissions: *const fn (?*anyopaque, Dir, Dir.Permissions) Dir.SetPermissionsError!void, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 755ce924ad..7d1f6212dc 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -501,7 +501,7 @@ pub const WriteFileError = File.Writer.Error || File.OpenError; pub fn writeFile(dir: Dir, io: Io, options: WriteFileOptions) WriteFileError!void { var file = try dir.createFile(io, options.sub_path, options.flags); defer file.close(io); - try file.writeAll(io, options.data); + try file.writeStreamingAll(io, options.data); } pub const PrevStatus = enum { @@ -955,6 +955,13 @@ pub fn rename( return io.vtable.dirRename(io.userdata, old_dir, old_sub_path, new_dir, new_sub_path); } +pub fn renameAbsolute(io: Io, old_path: []const u8, new_path: []const u8) RenameError!void { + assert(path.isAbsolute(old_path)); + assert(path.isAbsolute(new_path)); + const my_cwd = cwd(); + return io.vtable.dirRename(io.userdata, my_cwd, old_path, my_cwd, new_path); +} + /// Use with `Dir.symLink`, `Dir.symLinkAtomic`, and `symLinkAbsolute` to /// specify whether the symlink will point to a file or a directory. This value /// is ignored on all hosts except Windows where creating symlinks to different @@ -1053,7 +1060,7 @@ pub fn symLinkAtomic( temp_path[dirname.len + 1 ..][0..rand_len].* = std.fmt.hex(random_integer); if (dir.symLink(io, target_path, temp_path, flags)) { - return dir.rename(temp_path, dir, io, sym_link_path); + return dir.rename(temp_path, dir, sym_link_path, io); } else |err| switch (err) { error.PathAlreadyExists => continue, else => |e| return e, diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 59e0990eb0..92992f91b4 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -961,14 +961,14 @@ test "Dir.rename files" { const missing_file_path = try ctx.transformPath("missing_file_name"); const something_else_path = try ctx.transformPath("something_else"); - try testing.expectError(error.FileNotFound, ctx.dir.rename(missing_file_path, something_else_path)); + try testing.expectError(error.FileNotFound, ctx.dir.rename(missing_file_path, ctx.dir, something_else_path, io)); // Renaming files const test_file_name = try ctx.transformPath("test_file"); const renamed_test_file_name = try ctx.transformPath("test_file_renamed"); var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); - try ctx.dir.rename(test_file_name, renamed_test_file_name); + try ctx.dir.rename(test_file_name, ctx.dir, renamed_test_file_name, io); // Ensure the file was renamed try testing.expectError(error.FileNotFound, ctx.dir.openFile(io, test_file_name, .{})); @@ -976,13 +976,13 @@ test "Dir.rename files" { file.close(io); // Rename to self succeeds - try ctx.dir.rename(renamed_test_file_name, renamed_test_file_name); + try ctx.dir.rename(renamed_test_file_name, ctx.dir, renamed_test_file_name, io); // Rename to existing file succeeds const existing_file_path = try ctx.transformPath("existing_file"); var existing_file = try ctx.dir.createFile(io, existing_file_path, .{ .read = true }); existing_file.close(io); - try ctx.dir.rename(renamed_test_file_name, existing_file_path); + try ctx.dir.rename(renamed_test_file_name, ctx.dir, existing_file_path, io); try testing.expectError(error.FileNotFound, ctx.dir.openFile(io, renamed_test_file_name, .{})); file = try ctx.dir.openFile(io, existing_file_path, .{}); @@ -1007,7 +1007,7 @@ test "Dir.rename directories" { // Renaming directories try ctx.dir.makeDir(test_dir_path); - try ctx.dir.rename(test_dir_path, test_dir_renamed_path); + try ctx.dir.rename(test_dir_path, ctx.dir, test_dir_renamed_path, io); // Ensure the directory was renamed try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{})); @@ -1019,7 +1019,7 @@ test "Dir.rename directories" { dir.close(io); const test_dir_renamed_again_path = try ctx.transformPath("test_dir_renamed_again"); - try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path); + try ctx.dir.rename(test_dir_renamed_path, ctx.dir, test_dir_renamed_again_path, io); // Ensure the directory was renamed and the file still exists in it try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_renamed_path, .{})); @@ -1044,7 +1044,7 @@ test "Dir.rename directory onto empty dir" { try ctx.dir.makeDir(test_dir_path); try ctx.dir.makeDir(target_dir_path); - try ctx.dir.rename(test_dir_path, target_dir_path); + try ctx.dir.rename(test_dir_path, ctx.dir, target_dir_path, io); // Ensure the directory was renamed try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, test_dir_path, .{})); @@ -1072,7 +1072,7 @@ test "Dir.rename directory onto non-empty dir" { target_dir.close(io); // Rename should fail with PathAlreadyExists if target_dir is non-empty - try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path)); + try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, ctx.dir, target_dir_path, io)); // Ensure the directory was not renamed var dir = try ctx.dir.openDir(io, test_dir_path, .{}); @@ -1094,8 +1094,8 @@ test "Dir.rename file <-> dir" { var file = try ctx.dir.createFile(io, test_file_path, .{ .read = true }); file.close(io); try ctx.dir.makeDir(test_dir_path); - try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, test_dir_path)); - try testing.expectError(error.NotDir, ctx.dir.rename(test_dir_path, test_file_path)); + try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, ctx.dir, test_dir_path, io)); + try testing.expectError(error.NotDir, ctx.dir.rename(test_dir_path, ctx.dir, test_file_path, io)); } }.impl); } @@ -1114,7 +1114,7 @@ test "rename" { const renamed_test_file_name = "test_file_renamed"; var file = try tmp_dir1.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); - try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); + try Dir.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name, io); // ensure the file was renamed try testing.expectError(error.FileNotFound, tmp_dir1.dir.openFile(io, test_file_name, .{})); @@ -1492,7 +1492,7 @@ test "pwritev, preadv" { var src_file = try tmp.dir.createFile(io, "test.txt", .{ .read = true }); defer src_file.close(io); - var writer = src_file.writer(&.{}); + var writer = src_file.writer(io, &.{}); try writer.seekTo(16); try writer.interface.writeVecAll(&lines); @@ -1593,7 +1593,7 @@ test "sendfile" { var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); defer src_file.close(io); { - var fw = src_file.writer(&.{}); + var fw = src_file.writer(io, &.{}); try fw.interface.writeVecAll(&vecs); } @@ -1610,7 +1610,7 @@ test "sendfile" { var written_buf: [100]u8 = undefined; var file_reader = src_file.reader(io, &.{}); var fallback_buffer: [50]u8 = undefined; - var file_writer = dest_file.writer(&fallback_buffer); + var file_writer = dest_file.writer(io, &fallback_buffer); try file_writer.interface.writeVecAll(&headers); try file_reader.seekTo(1); try testing.expectEqual(10, try file_writer.interface.sendFileAll(&file_reader, .limited(10))); @@ -1648,7 +1648,7 @@ test "sendfile with buffered data" { try file_reader.interface.fill(8); var fallback_buffer: [32]u8 = undefined; - var file_writer = dest_file.writer(&fallback_buffer); + var file_writer = dest_file.writer(io, &fallback_buffer); try std.testing.expectEqual(4, try file_writer.interface.sendFileAll(&file_reader, .limited(4))); @@ -2051,7 +2051,7 @@ test "'.' and '..' in Io.Dir functions" { try ctx.dir.access(io, file_path, .{}); try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{}); - try ctx.dir.rename(copy_path, rename_path); + try ctx.dir.rename(copy_path, ctx.dir, rename_path, io); const renamed_file = try ctx.dir.openFile(io, rename_path, .{}); renamed_file.close(io); try ctx.dir.deleteFile(rename_path); @@ -2175,7 +2175,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.deleteDir(invalid_path)); - try testing.expectError(expected_err, ctx.dir.rename(invalid_path, invalid_path)); + try testing.expectError(expected_err, ctx.dir.rename(invalid_path, ctx.dir, invalid_path, io)); try testing.expectError(expected_err, ctx.dir.symLink(invalid_path, invalid_path, .{})); if (native_os == .wasi) { @@ -2208,7 +2208,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.realpathAlloc(testing.allocator, invalid_path)); } - try testing.expectError(expected_err, fs.rename(ctx.dir, invalid_path, ctx.dir, invalid_path)); + try testing.expectError(expected_err, Dir.rename(ctx.dir, invalid_path, ctx.dir, invalid_path, io)); if (native_os != .wasi and ctx.path_type != .relative) { try testing.expectError(expected_err, Dir.copyFileAbsolute(invalid_path, invalid_path, .{})); @@ -2334,7 +2334,7 @@ test "seekTo flushes buffered data" { defer file.close(io); { var buf: [16]u8 = undefined; - var file_writer = File.writer(file, &buf); + var file_writer = file.writer(io, file, &buf); try file_writer.interface.writeAll(contents); try file_writer.seekTo(8); diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index bacfdacf83..756ecfd63f 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -690,7 +690,7 @@ test "rename smoke test" { // Rename the file const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_file" }); defer a.free(new_file_path); - try posix.rename(file_path, new_file_path); + try Io.Dir.renameAbsolute(file_path, new_file_path); } { @@ -717,7 +717,7 @@ test "rename smoke test" { // Rename the directory const new_file_path = try fs.path.join(a, &.{ base_path, "some_other_dir" }); defer a.free(new_file_path); - try posix.rename(file_path, new_file_path); + try Io.Dir.renameAbsolute(file_path, new_file_path); } { diff --git a/lib/std/tar.zig b/lib/std/tar.zig index b2a5306458..5e7215f1d7 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -612,7 +612,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp .file => { if (createDirAndFile(io, dir, file_name, fileMode(file.mode, options))) |fs_file| { defer fs_file.close(io); - var file_writer = fs_file.writer(&file_contents_buffer); + var file_writer = fs_file.writer(io, &file_contents_buffer); try it.streamRemaining(file, &file_writer.interface); try file_writer.interface.flush(); } else |err| { diff --git a/lib/std/zip.zig b/lib/std/zip.zig index acb3fc65ab..5a91b73d6a 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -570,7 +570,7 @@ pub const Iterator = struct { }; defer out_file.close(io); var out_file_buffer: [1024]u8 = undefined; - var file_writer = out_file.writer(&out_file_buffer); + var file_writer = out_file.writer(io, &out_file_buffer); const local_data_file_offset: u64 = @as(u64, self.file_offset) + @as(u64, @sizeOf(LocalFileHeader)) + diff --git a/src/Compilation.zig b/src/Compilation.zig index 7fe217b385..3a6ae263a5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5303,7 +5303,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { defer tar_file.close(io); var buffer: [1024]u8 = undefined; - var tar_file_writer = tar_file.writer(&buffer); + var tar_file_writer = tar_file.writer(io, &buffer); var seen_table: std.AutoArrayHashMapUnmanaged(*Package.Module, []const u8) = .empty; defer seen_table.deinit(comp.gpa); @@ -6448,7 +6448,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_obj_path); - try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); + try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io); break :blk digest; }; @@ -6696,7 +6696,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_res_path); - try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); + try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename, io); break :blk digest; }; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 860fb8974e..aaba0c28cf 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -567,7 +567,7 @@ fn runResource( .root_dir = cache_root, .sub_path = try std.fmt.allocPrint(arena, "p" ++ s ++ "{s}", .{computed_package_hash.toSlice()}), }; - renameTmpIntoCache(cache_root.handle, package_sub_path, f.package_root.sub_path) catch |err| { + renameTmpIntoCache(io, cache_root.handle, package_sub_path, f.package_root.sub_path) catch |err| { const src = try cache_root.join(arena, &.{tmp_dir_sub_path}); const dest = try cache_root.join(arena, &.{f.package_root.sub_path}); try eb.addRootErrorMessage(.{ .msg = try eb.printString( @@ -1319,7 +1319,7 @@ fn unzip( defer zip_file.close(io); var zip_file_buffer: [4096]u8 = undefined; var zip_file_reader = b: { - var zip_file_writer = zip_file.writer(&zip_file_buffer); + var zip_file_writer = zip_file.writer(io, &zip_file_buffer); _ = reader.streamRemaining(&zip_file_writer.interface) catch |err| switch (err) { error.ReadFailed => return error.ReadFailed, @@ -1370,7 +1370,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = b: { - var pack_file_writer = pack_file.writer(&pack_file_buffer); + var pack_file_writer = pack_file.writer(io, &pack_file_buffer); const fetch_reader = &resource.fetch_stream.reader; _ = try fetch_reader.streamRemaining(&pack_file_writer.interface); try pack_file_writer.interface.flush(); @@ -1380,7 +1380,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U var index_file = try pack_dir.createFile(io, "pkg.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; - var index_file_writer = index_file.writer(&index_file_buffer); + var index_file_writer = index_file.writer(io, &index_file_buffer); { const index_prog_node = f.prog_node.start("Index pack", 0); defer index_prog_node.end(); @@ -1454,11 +1454,11 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void } } -pub fn renameTmpIntoCache(cache_dir: Io.Dir, tmp_dir_sub_path: []const u8, dest_dir_sub_path: []const u8) !void { +pub fn renameTmpIntoCache(io: Io, cache_dir: Io.Dir, tmp_dir_sub_path: []const u8, dest_dir_sub_path: []const u8) !void { assert(dest_dir_sub_path[1] == fs.path.sep); var handled_missing_dir = false; while (true) { - cache_dir.rename(tmp_dir_sub_path, dest_dir_sub_path) catch |err| switch (err) { + cache_dir.rename(tmp_dir_sub_path, cache_dir, dest_dir_sub_path, io) catch |err| switch (err) { error.FileNotFound => { if (handled_missing_dir) return err; cache_dir.makeDir(dest_dir_sub_path[0..1]) catch |mkd_err| switch (mkd_err) { diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 3f0ffb04cd..4d5bcfc84b 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -1594,7 +1594,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u var index_file = try git_dir.dir.createFile(io, "testrepo.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; - var index_file_writer = index_file.writer(&index_file_buffer); + var index_file_writer = index_file.writer(io, &index_file_buffer); try indexPack(testing.allocator, format, &pack_file_reader, &index_file_writer); // Arbitrary size limit on files read while checking the repository contents @@ -1730,7 +1730,7 @@ pub fn main() !void { var index_file = try git_dir.createFile(io, "idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [4096]u8 = undefined; - var index_file_writer = index_file.writer(&index_file_buffer); + var index_file_writer = index_file.writer(io, &index_file_buffer); try indexPack(allocator, format, &pack_file_reader, &index_file_writer); std.debug.print("Starting checkout...\n", .{}); diff --git a/src/Zcu.zig b/src/Zcu.zig index 1f2fe89236..2891da2407 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -2986,7 +2986,13 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_br: *Io.Reader return zir; } -pub fn saveZirCache(gpa: Allocator, cache_file: Io.File, stat: Io.File.Stat, zir: Zir) (Io.File.WriteError || Allocator.Error)!void { +pub fn saveZirCache( + gpa: Allocator, + io: Io, + cache_file: Io.File, + stat: Io.File.Stat, + zir: Zir, +) (Io.File.WriteError || Allocator.Error)!void { const safety_buffer = if (data_has_safety_tag) try gpa.alloc([8]u8, zir.instructions.len) else @@ -3020,13 +3026,13 @@ pub fn saveZirCache(gpa: Allocator, cache_file: Io.File, stat: Io.File.Stat, zir zir.string_bytes, @ptrCast(zir.extra), }; - var cache_fw = cache_file.writer(&.{}); + var cache_fw = cache_file.writer(io, &.{}); cache_fw.interface.writeVecAll(&vecs) catch |err| switch (err) { error.WriteFailed => return cache_fw.err.?, }; } -pub fn saveZoirCache(cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir) Io.File.WriteError!void { +pub fn saveZoirCache(io: Io, cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir) Io.File.WriteError!void { const header: Zoir.Header = .{ .nodes_len = @intCast(zoir.nodes.len), .extra_len = @intCast(zoir.extra.len), @@ -3050,7 +3056,7 @@ pub fn saveZoirCache(cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir) Io.Fil @ptrCast(zoir.compile_errors), @ptrCast(zoir.error_notes), }; - var cache_fw = cache_file.writer(&.{}); + var cache_fw = cache_file.writer(io, &.{}); cache_fw.interface.writeVecAll(&vecs) catch |err| switch (err) { error.WriteFailed => return cache_fw.err.?, }; diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 74196705c3..9d6a45ad26 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -278,18 +278,18 @@ pub fn updateFile( switch (file.getMode()) { .zig => { file.zir = try AstGen.generate(gpa, file.tree.?); - Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { + Zcu.saveZirCache(gpa, io, cache_file, stat, file.zir.?) catch |err| switch (err) { error.OutOfMemory => |e| return e, - else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {s}", .{ - file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), + else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {t}", .{ + file.path.fmt(comp), cache_directory, &hex_digest, err, }), }; }, .zon => { file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); - Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { - log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {s}", .{ - file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), + Zcu.saveZoirCache(io, cache_file, stat, file.zoir.?) catch |err| { + log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {t}", .{ + file.path.fmt(comp), cache_directory, &hex_digest, err, }); }; }, diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 93f88b9689..9631ec22f9 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -380,7 +380,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const lib_final_file = try o_dir.createFile(io, final_lib_basename, .{ .truncate = true }); defer lib_final_file.close(io); var buffer: [1024]u8 = undefined; - var file_writer = lib_final_file.writer(&buffer); + var file_writer = lib_final_file.writer(io, &buffer); try implib.writeCoffArchive(gpa, &file_writer.interface, members); try file_writer.interface.flush(); } diff --git a/src/link.zig b/src/link.zig index 06d18ec2d5..5f3031ca0e 100644 --- a/src/link.zig +++ b/src/link.zig @@ -621,7 +621,7 @@ pub const File = struct { }); defer gpa.free(tmp_sub_path); try emit.root_dir.handle.copyFile(emit.sub_path, emit.root_dir.handle, tmp_sub_path, .{}); - try emit.root_dir.handle.rename(tmp_sub_path, emit.sub_path); + try emit.root_dir.handle.rename(tmp_sub_path, emit.root_dir.handle, emit.sub_path, io); switch (builtin.os.tag) { .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { log.warn("ptrace failure: {s}", .{@errorName(err)}); diff --git a/src/link/Lld.zig b/src/link/Lld.zig index ca15a38bb0..6920c12762 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1631,7 +1631,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi { defer rsp_file.close(io); var rsp_file_buffer: [1024]u8 = undefined; - var rsp_file_writer = rsp_file.writer(&rsp_file_buffer); + var rsp_file_writer = rsp_file.writer(io, &rsp_file_buffer); const rsp_writer = &rsp_file_writer.interface; for (argv[2..]) |arg| { try rsp_writer.writeByte('"'); diff --git a/src/main.zig b/src/main.zig index bef3a3efb5..88e236adef 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3412,7 +3412,7 @@ fn buildOutputType( const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{ &bin_digest, ext.canonicalName(target), }); - try dirs.local_cache.handle.rename(dump_path, sub_path); + try dirs.local_cache.handle.rename(dump_path, dirs.local_cache.handle, sub_path, io); // Convert `sub_path` to be relative to current working directory. src.src_path = try dirs.local_cache.join(arena, &.{sub_path}); @@ -7216,11 +7216,7 @@ fn createDependenciesModule( const hex_digest = hh.final(); const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); - try Package.Fetch.renameTmpIntoCache( - dirs.local_cache.handle, - tmp_dir_sub_path, - o_dir_sub_path, - ); + try Package.Fetch.renameTmpIntoCache(io, dirs.local_cache.handle, tmp_dir_sub_path, o_dir_sub_path); const deps_mod = try Package.Module.create(arena, .{ .paths = .{ -- cgit v1.2.3 From 1dcfc8787e86ed94d216976e621a49fc488e8214 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 18:00:55 -0800 Subject: update all readFileAlloc() to accept Io instance --- lib/compiler/std-docs.zig | 6 ++++-- lib/std/Build/Cache.zig | 3 ++- lib/std/Build/Step/CheckFile.zig | 3 ++- lib/std/Build/Step/ConfigHeader.zig | 4 ++-- lib/std/Build/WebServer.zig | 5 +++-- lib/std/Io/Dir.zig | 6 +++--- lib/std/crypto/Certificate/Bundle/macos.zig | 3 +-- lib/std/fs/test.zig | 27 ++++++++++++++------------- lib/std/zig/LibCInstallation.zig | 8 ++------ lib/std/zig/WindowsSdk.zig | 2 +- src/Compilation.zig | 4 ++-- src/Package/Fetch/git.zig | 4 ++-- src/link.zig | 4 ++-- src/link/MachO.zig | 8 +++++--- src/link/MachO/CodeSignature.zig | 16 ++++++++-------- src/main.zig | 21 +++++++++------------ 16 files changed, 62 insertions(+), 62 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 8f02f05958..6452496305 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -179,10 +179,11 @@ fn serveDocsFile( content_type: []const u8, ) !void { const gpa = context.gpa; + const io = context.io; // The desired API is actually sendfile, which will require enhancing std.http.Server. // We load the file with every request so that the user can make changes to the file // and refresh the HTML page without restarting this server. - const file_contents = try context.lib_dir.readFileAlloc(name, gpa, .limited(10 * 1024 * 1024)); + const file_contents = try context.lib_dir.readFileAlloc(io, name, gpa, .limited(10 * 1024 * 1024)); defer gpa.free(file_contents); try request.respond(file_contents, .{ .extra_headers = &.{ @@ -255,6 +256,7 @@ fn serveWasm( optimize_mode: std.builtin.OptimizeMode, ) !void { const gpa = context.gpa; + const io = context.io; var arena_instance = std.heap.ArenaAllocator.init(gpa); defer arena_instance.deinit(); @@ -273,7 +275,7 @@ fn serveWasm( }); // std.http.Server does not have a sendfile API yet. const bin_path = try wasm_base_path.join(arena, bin_name); - const file_contents = try bin_path.root_dir.handle.readFileAlloc(bin_path.sub_path, gpa, .limited(10 * 1024 * 1024)); + const file_contents = try bin_path.root_dir.handle.readFileAlloc(io, bin_path.sub_path, gpa, .limited(10 * 1024 * 1024)); defer gpa.free(file_contents); try request.respond(file_contents, .{ .extra_headers = &.{ diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 2d6dbc02fa..d2ba33c74d 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1075,7 +1075,8 @@ pub const Manifest = struct { fn addDepFileMaybePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void { const gpa = self.cache.gpa; - const dep_file_contents = try dir.readFileAlloc(dep_file_sub_path, gpa, .limited(manifest_file_size_max)); + const io = self.cache.io; + const dep_file_contents = try dir.readFileAlloc(io, dep_file_sub_path, gpa, .limited(manifest_file_size_max)); defer gpa.free(dep_file_contents); var error_buf: std.ArrayList(u8) = .empty; diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig index 560b6ad050..1c3813ca82 100644 --- a/lib/std/Build/Step/CheckFile.zig +++ b/lib/std/Build/Step/CheckFile.zig @@ -51,11 +51,12 @@ pub fn setName(check_file: *CheckFile, name: []const u8) void { fn make(step: *Step, options: Step.MakeOptions) !void { _ = options; const b = step.owner; + const io = b.graph.io; const check_file: *CheckFile = @fieldParentPtr("step", step); try step.singleUnchangingWatchInput(check_file.source); const src_path = check_file.source.getPath2(b, step); - const contents = Io.Dir.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(io, src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 589110d4c4..250bae5009 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -208,7 +208,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .autoconf_undef, .autoconf_at => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read autoconf input file '{s}': {s}", .{ src_path, @errorName(err), }); @@ -222,7 +222,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .cmake => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read cmake input file '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index 38a7a73588..72306cbab9 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -469,11 +469,12 @@ pub fn serveFile( content_type: []const u8, ) !void { const gpa = ws.gpa; + const io = ws.graph.io; // The desired API is actually sendfile, which will require enhancing http.Server. // We load the file with every request so that the user can make changes to the file // and refresh the HTML page without restarting this server. - const file_contents = path.root_dir.handle.readFileAlloc(path.sub_path, gpa, .limited(10 * 1024 * 1024)) catch |err| { - log.err("failed to read '{f}': {s}", .{ path, @errorName(err) }); + const file_contents = path.root_dir.handle.readFileAlloc(io, path.sub_path, gpa, .limited(10 * 1024 * 1024)) catch |err| { + log.err("failed to read '{f}': {t}", .{ path, err }); return error.AlreadyReported; }; defer gpa.free(file_contents); diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 7d1f6212dc..cf5e2b4c72 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1117,10 +1117,10 @@ pub fn readLink(dir: Dir, io: Io, sub_path: []const u8, buffer: []u8) ReadLinkEr /// On other platforms, `path` is an opaque sequence of bytes with no particular encoding. pub fn readLinkAbsolute(io: Io, absolute_path: []const u8, buffer: []u8) ReadLinkError!usize { assert(path.isAbsolute(absolute_path)); - return io.vtable.dirReadLink(io.userdata, .cwd(), path, buffer); + return io.vtable.dirReadLink(io.userdata, .cwd(), absolute_path, buffer); } -pub const ReadFileAllocError = File.OpenError || File.ReadError || Allocator.Error || error{ +pub const ReadFileAllocError = File.OpenError || File.Reader.Error || Allocator.Error || error{ /// File size reached or exceeded the provided limit. StreamTooLong, }; @@ -1603,7 +1603,7 @@ pub const CopyFileOptions = struct { pub const CopyFileError = File.OpenError || File.StatError || File.Atomic.InitError || File.Atomic.FinishError || - File.ReadError || File.WriteError || error{InvalidFileName}; + File.Reader.Error || File.WriteError || error{InvalidFileName}; /// Atomically creates a new file at `dest_path` within `dest_dir` with the /// same contents as `source_path` within `source_dir`, overwriting any already diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index 444d8da675..086c8feb3f 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -17,9 +17,8 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanM "/Library/Keychains/System.keychain", }; - _ = io; // TODO migrate file system to use std.Io for (keychain_paths) |keychain_path| { - const bytes = Io.Dir.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { + const bytes = Io.Dir.cwd().readFileAlloc(io, keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { error.StreamTooLong => return error.FileTooBig, else => |e| return e, }; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 92992f91b4..bb3a9da0f5 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -767,7 +767,7 @@ test "readFileAlloc" { var file = try tmp_dir.dir.createFile(io, "test_file", .{ .read = true }); defer file.close(io); - const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); + const buf1 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(1024)); defer testing.allocator.free(buf1); try testing.expectEqualStrings("", buf1); @@ -776,7 +776,7 @@ test "readFileAlloc" { { // max_bytes > file_size - const buf2 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); + const buf2 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(1024)); defer testing.allocator.free(buf2); try testing.expectEqualStrings(write_buf, buf2); } @@ -785,13 +785,13 @@ test "readFileAlloc" { // max_bytes == file_size try testing.expectError( error.StreamTooLong, - tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len)), + tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len)), ); } { // max_bytes == file_size + 1 - const buf2 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len + 1)); + const buf2 = try tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len + 1)); defer testing.allocator.free(buf2); try testing.expectEqualStrings(write_buf, buf2); } @@ -799,7 +799,7 @@ test "readFileAlloc" { // max_bytes < file_size try testing.expectError( error.StreamTooLong, - tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(write_buf.len - 1)), + tmp_dir.dir.readFileAlloc(io, "test_file", testing.allocator, .limited(write_buf.len - 1)), ); } @@ -877,16 +877,16 @@ test "file operations on directories" { switch (native_os) { .dragonfly, .netbsd => { // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732 - const buf = try ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited); + const buf = try ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited); testing.allocator.free(buf); }, .wasi => { // WASI return EBADF, which gets mapped to NotOpenForReading. // See https://github.com/bytecodealliance/wasmtime/issues/1935 - try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited)); + try testing.expectError(error.NotOpenForReading, ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited)); }, else => { - try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(test_dir_name, testing.allocator, .unlimited)); + try testing.expectError(error.IsDir, ctx.dir.readFileAlloc(io, test_dir_name, testing.allocator, .unlimited)); }, } @@ -1679,14 +1679,14 @@ test "copyFile" { try ctx.dir.copyFile(src_file, ctx.dir, dest_file2, .{ .override_mode = File.default_mode }); defer ctx.dir.deleteFile(dest_file2) catch {}; - try expectFileContents(ctx.dir, dest_file, data); - try expectFileContents(ctx.dir, dest_file2, data); + try expectFileContents(io, ctx.dir, dest_file, data); + try expectFileContents(io, ctx.dir, dest_file2, data); } }.impl); } -fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void { - const contents = try dir.readFileAlloc(file_path, testing.allocator, .limited(1000)); +fn expectFileContents(io: Io, dir: Dir, file_path: []const u8, data: []const u8) !void { + const contents = try dir.readFileAlloc(io, file_path, testing.allocator, .limited(1000)); defer testing.allocator.free(contents); try testing.expectEqualSlices(u8, data, contents); @@ -1695,6 +1695,7 @@ fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void { test "AtomicFile" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { + const io = ctx.io; const allocator = ctx.arena.allocator(); const test_out_file = try ctx.transformPath("tmp_atomic_file_test_dest.txt"); const test_content = @@ -1709,7 +1710,7 @@ test "AtomicFile" { try af.file_writer.interface.writeAll(test_content); try af.finish(); } - const content = try ctx.dir.readFileAlloc(test_out_file, allocator, .limited(9999)); + const content = try ctx.dir.readFileAlloc(io, test_out_file, allocator, .limited(9999)); try testing.expectEqualStrings(test_content, content); try ctx.dir.deleteFile(test_out_file); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index f3dc73838f..1463ff4a40 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -37,11 +37,7 @@ pub const FindError = error{ ZigIsTheCCompiler, }; -pub fn parse( - allocator: Allocator, - libc_file: []const u8, - target: *const std.Target, -) !LibCInstallation { +pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation { var self: LibCInstallation = .{}; const fields = std.meta.fields(LibCInstallation); @@ -57,7 +53,7 @@ pub fn parse( } } - const contents = try Io.Dir.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize))); + const contents = try Io.Dir.cwd().readFileAlloc(io, libc_file, allocator, .limited(std.math.maxInt(usize))); defer allocator.free(contents); var it = std.mem.tokenizeScalar(u8, contents, '\n'); diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig index dca474020a..3f6d58b6ba 100644 --- a/lib/std/zig/WindowsSdk.zig +++ b/lib/std/zig/WindowsSdk.zig @@ -775,7 +775,7 @@ const MsvcLibDir = struct { writer.writeByte(std.fs.path.sep) catch unreachable; writer.writeAll("state.json") catch unreachable; - const json_contents = instances_dir.readFileAlloc(writer.buffered(), allocator, .limited(std.math.maxInt(usize))) catch continue; + const json_contents = instances_dir.readFileAlloc(io, writer.buffered(), allocator, .limited(std.math.maxInt(usize))) catch continue; defer allocator.free(json_contents); var parsed = std.json.parseFromSlice(std.json.Value, allocator, json_contents, .{}) catch continue; diff --git a/src/Compilation.zig b/src/Compilation.zig index 3a6ae263a5..79b2d51635 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -6400,7 +6400,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr if (comp.file_system_inputs != null) { // Use the same file size limit as the cache code does for dependency files. - const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(dep_basename, gpa, .limited(Cache.manifest_file_size_max)); + const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .limited(Cache.manifest_file_size_max)); defer gpa.free(dep_file_contents); var str_buf: std.ArrayList(u8) = .empty; @@ -6665,7 +6665,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 // Read depfile and update cache manifest { const dep_basename = fs.path.basename(out_dep_path); - const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(dep_basename, arena, .limited(50 * 1024 * 1024)); + const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, arena, .limited(50 * 1024 * 1024)); defer arena.free(dep_file_contents); const value = try std.json.parseFromSliceLeaky(std.json.Value, arena, dep_file_contents, .{}); diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 4d5bcfc84b..1d6aa1a849 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -1602,7 +1602,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u const max_file_size = 8192; if (!skip_checksums) { - const index_file_data = try git_dir.dir.readFileAlloc("testrepo.idx", testing.allocator, .limited(max_file_size)); + const index_file_data = try git_dir.dir.readFileAlloc(io, "testrepo.idx", testing.allocator, .limited(max_file_size)); defer testing.allocator.free(index_file_data); // testrepo.idx is generated by Git. The index created by this file should // match it exactly. Running `git verify-pack -v testrepo.pack` can verify @@ -1678,7 +1678,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u \\revision 19 \\ ; - const actual_file_contents = try worktree.dir.readFileAlloc("file", testing.allocator, .limited(max_file_size)); + const actual_file_contents = try worktree.dir.readFileAlloc(io, "file", testing.allocator, .limited(max_file_size)); defer testing.allocator.free(actual_file_contents); try testing.expectEqualStrings(expected_file_contents, actual_file_contents); } diff --git a/src/link.zig b/src/link.zig index 5f3031ca0e..ff6d938e6f 100644 --- a/src/link.zig +++ b/src/link.zig @@ -624,12 +624,12 @@ pub const File = struct { try emit.root_dir.handle.rename(tmp_sub_path, emit.root_dir.handle, emit.sub_path, io); switch (builtin.os.tag) { .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| { - log.warn("ptrace failure: {s}", .{@errorName(err)}); + log.warn("ptrace failure: {t}", .{err}); }, .maccatalyst, .macos => { const macho_file = base.cast(.macho).?; macho_file.ptraceAttach(pid) catch |err| { - log.warn("attaching failed with error: {s}", .{@errorName(err)}); + log.warn("attaching failed with error: {t}", .{err}); }; }, .windows => unreachable, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 6cd906340a..f996442f24 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -4347,11 +4347,13 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); + const io = comp.io; + const sdk_dir = switch (sdk_layout) { .sdk => comp.sysroot.?, .vendored => fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "libc", "darwin" }) catch return null, }; - if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { + if (readSdkVersionFromSettings(arena, io, sdk_dir)) |ver| { return parseSdkVersion(ver); } else |_| { // Read from settings should always succeed when vendored. @@ -4374,9 +4376,9 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi // Official Apple SDKs ship with a `SDKSettings.json` located at the top of SDK fs layout. // Use property `MinimalDisplayName` to determine version. // The file/property is also available with vendored libc. -fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 { +fn readSdkVersionFromSettings(arena: Allocator, io: Io, dir: []const u8) ![]const u8 { const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" }); - const contents = try Io.Dir.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16))); + const contents = try Io.Dir.cwd().readFileAlloc(io, sdk_path, arena, .limited(std.math.maxInt(u16))); const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{}); if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string; return error.SdkVersionFailure; diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index ec516d4af0..0955c823b8 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -17,6 +17,12 @@ const MachO = @import("../MachO.zig"); const hash_size = Sha256.digest_length; +page_size: u16, +code_directory: CodeDirectory, +requirements: ?Requirements = null, +entitlements: ?Entitlements = null, +signature: ?Signature = null, + const Blob = union(enum) { code_directory: *CodeDirectory, requirements: *Requirements, @@ -220,12 +226,6 @@ const Signature = struct { } }; -page_size: u16, -code_directory: CodeDirectory, -requirements: ?Requirements = null, -entitlements: ?Entitlements = null, -signature: ?Signature = null, - pub fn init(page_size: u16) CodeSignature { return .{ .page_size = page_size, @@ -246,8 +246,8 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void { } } -pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void { - const inner = try Io.Dir.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32))); +pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, io: Io, path: []const u8) !void { + const inner = try Io.Dir.cwd().readFileAlloc(io, path, allocator, .limited(std.math.maxInt(u32))); self.entitlements = .{ .inner = inner }; } diff --git a/src/main.zig b/src/main.zig index 88e236adef..9bb88d373b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1029,9 +1029,8 @@ fn buildOutputType( if (mem.cutPrefix(u8, arg, "@")) |resp_file_path| { // This is a "compiler response file". We must parse the file and treat its // contents as command line parameters. - args_iter.resp_file = initArgIteratorResponseFile(arena, resp_file_path) catch |err| { - fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) }); - }; + args_iter.resp_file = initArgIteratorResponseFile(arena, io, resp_file_path) catch |err| + fatal("unable to read response file '{s}': {t}", .{ resp_file_path, err }); } else if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { try Io.File.stdout().writeAll(usage_build_generic); @@ -5441,7 +5440,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) // that are missing. const s = fs.path.sep_str; const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce; - const stdout = dirs.local_cache.handle.readFileAlloc(tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| { + const stdout = dirs.local_cache.handle.readFileAlloc(io, tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| { fatal("unable to read results of configure phase from '{f}{s}': {s}", .{ dirs.local_cache, tmp_sub_path, @errorName(err), }); @@ -5822,9 +5821,9 @@ pub fn lldMain( const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true }); /// Initialize the arguments from a Response File. "*.rsp" -fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile { +fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []const u8) !ArgIteratorResponseFile { const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit - const cmd_line = try Io.Dir.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes)); + const cmd_line = try Io.Dir.cwd().readFileAlloc(io, resp_file_path, allocator, .limited(max_bytes)); errdefer allocator.free(cmd_line); return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line); @@ -5952,7 +5951,7 @@ pub const ClangArgIterator = struct { }; } - fn next(self: *ClangArgIterator) !void { + fn next(self: *ClangArgIterator, io: Io) !void { assert(self.has_next); assert(self.next_index < self.argv.len); // In this state we know that the parameter we are looking at is a root parameter @@ -5970,10 +5969,8 @@ pub const ClangArgIterator = struct { const arena = self.arena; const resp_file_path = arg[1..]; - self.arg_iterator_response_file = - initArgIteratorResponseFile(arena, resp_file_path) catch |err| { - fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) }); - }; + self.arg_iterator_response_file = initArgIteratorResponseFile(arena, io, resp_file_path) catch |err| + fatal("unable to read response file '{s}': {t}", .{ resp_file_path, err }); // NOTE: The ArgIteratorResponseFile returns tokens from next() that are slices of an // internal buffer. This internal buffer is arena allocated, so it is not cleaned up here. @@ -7405,7 +7402,7 @@ const Templates = struct { } const max_bytes = 10 * 1024 * 1024; - const contents = templates.dir.readFileAlloc(template_path, arena, .limited(max_bytes)) catch |err| { + const contents = templates.dir.readFileAlloc(io, template_path, arena, .limited(max_bytes)) catch |err| { fatal("unable to read template file '{s}': {t}", .{ template_path, err }); }; templates.buffer.clearRetainingCapacity(); -- cgit v1.2.3 From ebdbbd20ace6e93b581b90075f52946b3832da93 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 19:41:21 -0800 Subject: update makeDir() sites to specify permissions --- lib/compiler/reduce.zig | 16 +++---- lib/std/Build/Step/CheckObject.zig | 2 + lib/std/Build/Step/RemoveDir.zig | 11 ++--- lib/std/Build/Step/Run.zig | 2 +- lib/std/fs/test.zig | 70 +++++++++++++++---------------- lib/std/testing.zig | 2 +- src/Compilation.zig | 22 ++++------ src/Package/Fetch.zig | 8 ++-- src/Package/Fetch/git.zig | 4 +- src/main.zig | 1 + test/src/Cases.zig | 4 +- test/standalone/posix/relpaths.zig | 21 +++++----- test/standalone/windows_bat_args/fuzz.zig | 11 +++-- test/standalone/windows_bat_args/test.zig | 9 ++-- test/standalone/windows_spawn/main.zig | 8 ++-- test/tests.zig | 8 ++-- 16 files changed, 102 insertions(+), 97 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index f10bd12e9d..0c61111d10 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -92,9 +92,7 @@ pub fn main() !void { if (i >= args.len) fatal("expected 32-bit integer after {s}", .{arg}); const next_arg = args[i]; seed = std.fmt.parseUnsigned(u32, next_arg, 0) catch |err| { - fatal("unable to parse seed '{s}' as 32-bit integer: {s}", .{ - next_arg, @errorName(err), - }); + fatal("unable to parse seed '{s}' as 32-bit integer: {t}", .{ next_arg, err }); }; } else { fatal("unrecognized parameter: '{s}'", .{arg}); @@ -125,7 +123,7 @@ pub fn main() !void { var astgen_input: std.Io.Writer.Allocating = .init(gpa); defer astgen_input.deinit(); - var tree = try parse(gpa, root_source_file_path); + var tree = try parse(gpa, io, root_source_file_path); defer { gpa.free(tree.source); tree.deinit(gpa); @@ -190,7 +188,7 @@ pub fn main() !void { std.debug.print("{s} ", .{@tagName(t)}); } std.debug.print("\n", .{}); - try transformationsToFixups(gpa, arena, root_source_file_path, this_set, &fixups); + try transformationsToFixups(gpa, arena, io, root_source_file_path, this_set, &fixups); rendered.clearRetainingCapacity(); try tree.render(gpa, &rendered.writer, fixups); @@ -246,7 +244,7 @@ pub fn main() !void { }); switch (interestingness) { .interesting => { - const new_tree = try parse(gpa, root_source_file_path); + const new_tree = try parse(gpa, io, root_source_file_path); gpa.free(tree.source); tree.deinit(gpa); tree = new_tree; @@ -317,6 +315,7 @@ fn runCheck(arena: Allocator, io: Io, argv: []const []const u8) !Interestingness fn transformationsToFixups( gpa: Allocator, arena: Allocator, + io: Io, root_source_file_path: []const u8, transforms: []const Walk.Transformation, fixups: *Ast.Render.Fixups, @@ -354,7 +353,7 @@ fn transformationsToFixups( inline_imported_file.imported_string, }); defer gpa.free(full_imported_path); - var other_file_ast = try parse(gpa, full_imported_path); + var other_file_ast = try parse(gpa, io, full_imported_path); defer { gpa.free(other_file_ast.source); other_file_ast.deinit(gpa); @@ -398,8 +397,9 @@ fn transformationsToFixups( }; } -fn parse(gpa: Allocator, file_path: []const u8) !Ast { +fn parse(gpa: Allocator, io: Io, file_path: []const u8) !Ast { const source_code = Io.Dir.cwd().readFileAllocOptions( + io, file_path, gpa, .limited(std.math.maxInt(u32)), diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index c6c11ce2b9..ac8fafaa3f 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -547,12 +547,14 @@ pub fn checkComputeCompare( fn make(step: *Step, make_options: Step.MakeOptions) !void { _ = make_options; const b = step.owner; + const io = b.graph.io; const gpa = b.allocator; const check_object: *CheckObject = @fieldParentPtr("step", step); try step.singleUnchangingWatchInput(check_object.source); const src_path = check_object.source.getPath3(b, step); const contents = src_path.root_dir.handle.readFileAllocOptions( + io, src_path.sub_path, gpa, .limited(check_object.max_bytes), diff --git a/lib/std/Build/Step/RemoveDir.zig b/lib/std/Build/Step/RemoveDir.zig index e2d4c02abc..6f933da9ee 100644 --- a/lib/std/Build/Step/RemoveDir.zig +++ b/lib/std/Build/Step/RemoveDir.zig @@ -27,6 +27,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { _ = options; const b = step.owner; + const io = b.graph.io; const remove_dir: *RemoveDir = @fieldParentPtr("step", step); step.clearWatchInputs(); @@ -34,15 +35,11 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const full_doomed_path = remove_dir.doomed_path.getPath2(b, step); - b.build_root.handle.deleteTree(full_doomed_path) catch |err| { + b.build_root.handle.deleteTree(io, full_doomed_path) catch |err| { if (b.build_root.path) |base| { - return step.fail("unable to recursively delete path '{s}/{s}': {s}", .{ - base, full_doomed_path, @errorName(err), - }); + return step.fail("unable to recursively delete path '{s}/{s}': {t}", .{ base, full_doomed_path, err }); } else { - return step.fail("unable to recursively delete path '{s}': {s}", .{ - full_doomed_path, @errorName(err), - }); + return step.fail("unable to recursively delete path '{s}': {t}", .{ full_doomed_path, err }); } }; } diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index e52dd21a96..19d2e7e61c 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1044,7 +1044,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { b.cache_root.handle.rename(tmp_dir_path, b.cache_root.handle, o_sub_path, io) catch |err| { if (err == error.PathAlreadyExists) { - b.cache_root.handle.deleteTree(o_sub_path) catch |del_err| { + b.cache_root.handle.deleteTree(io, o_sub_path) catch |del_err| { return step.fail("unable to remove dir '{f}'{s}: {t}", .{ b.cache_root, tmp_dir_path, del_err, }); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index bb3a9da0f5..edc15526b2 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -186,7 +186,7 @@ test "Dir.readLink" { const file_target_path = try ctx.transformPath("file.txt"); try ctx.dir.writeFile(io, .{ .sub_path = file_target_path, .data = "nonsense" }); const dir_target_path = try ctx.transformPath("subdir"); - try ctx.dir.makeDir(dir_target_path); + try ctx.dir.makeDir(io, dir_target_path, .default_dir); // On Windows, symlink targets always use the canonical path separator const canonical_file_target_path = try ctx.toCanonicalPathSep(file_target_path); @@ -282,7 +282,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { const dir_target_path = try ctx.transformPath("subdir"); - try ctx.dir.makeDir(dir_target_path); + try ctx.dir.makeDir(io, dir_target_path, .default_dir); try setupSymlink(ctx.dir, dir_target_path, "symlink", .{ .is_directory = true }); @@ -363,7 +363,7 @@ test "openDir" { fn impl(ctx: *TestContext) !void { const allocator = ctx.arena.allocator(); const subdir_path = try ctx.transformPath("subdir"); - try ctx.dir.makeDir(subdir_path); + try ctx.dir.makeDir(io, subdir_path, .default_dir); for ([_][]const u8{ "", ".", ".." }) |sub_path| { const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path }); @@ -398,7 +398,7 @@ test "openDirAbsolute" { const tmp_ino = (try tmp.dir.stat(io)).inode; - try tmp.dir.makeDir("subdir"); + try tmp.dir.makeDir(io, "subdir", .default_dir); const sub_path = try tmp.dir.realpathAlloc(testing.allocator, "subdir"); defer testing.allocator.free(sub_path); @@ -494,7 +494,7 @@ test "readLinkAbsolute" { // Create some targets try tmp.dir.writeFile(io, .{ .sub_path = "file.txt", .data = "nonsense" }); - try tmp.dir.makeDir("subdir"); + try tmp.dir.makeDir(io, "subdir", .default_dir); // Get base abs path var arena = ArenaAllocator.init(testing.allocator); @@ -531,7 +531,7 @@ test "Dir.Iterator" { const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); - try tmp_dir.dir.makeDir("some_dir"); + try tmp_dir.dir.makeDir(io, "some_dir", .default_dir); var arena = ArenaAllocator.init(testing.allocator); defer arena.deinit(); @@ -600,7 +600,7 @@ test "Dir.Iterator twice" { const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); - try tmp_dir.dir.makeDir("some_dir"); + try tmp_dir.dir.makeDir(io, "some_dir", .default_dir); var arena = ArenaAllocator.init(testing.allocator); defer arena.deinit(); @@ -635,7 +635,7 @@ test "Dir.Iterator reset" { const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); - try tmp_dir.dir.makeDir("some_dir"); + try tmp_dir.dir.makeDir(io, "some_dir", .default_dir); var arena = ArenaAllocator.init(testing.allocator); defer arena.deinit(); @@ -682,7 +682,7 @@ test "Dir.Iterator but dir is deleted during iteration" { // This is a contrived reproduction, but this could happen outside of the program, in another thread, etc. // If we get an error while trying to delete, we can skip this test (this will happen on platforms // like Windows which will give FileBusy if the directory is currently open for iteration). - tmp.dir.deleteTree("subdir") catch return error.SkipZigTest; + tmp.dir.deleteTree(io, "subdir") catch return error.SkipZigTest; // Now, when we try to iterate, the next call should return null immediately. const entry = try iterator.next(); @@ -724,7 +724,7 @@ test "Dir.realpath smoke test" { // Now create the file and dir try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); - try ctx.dir.makeDir(test_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); const base_path = try ctx.transformPath("."); const base_realpath = try ctx.dir.realpathAlloc(allocator, base_path); @@ -842,7 +842,7 @@ test "directory operations on files" { var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); - try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); + try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(io, test_file_name, .default_dir)); try testing.expectError(error.NotDir, ctx.dir.openDir(io, test_file_name, .{})); try testing.expectError(error.NotDir, ctx.dir.deleteDir(test_file_name)); @@ -870,7 +870,7 @@ test "file operations on directories" { fn impl(ctx: *TestContext) !void { const test_dir_name = try ctx.transformPath("test_dir"); - try ctx.dir.makeDir(test_dir_name); + try ctx.dir.makeDir(io, test_dir_name, .default_dir); try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); @@ -937,7 +937,7 @@ test "deleteDir" { try testing.expectError(error.FileNotFound, ctx.dir.deleteDir(test_dir_path)); // deleting a non-empty directory - try ctx.dir.makeDir(test_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); @@ -1006,7 +1006,7 @@ test "Dir.rename directories" { const test_dir_renamed_path = try ctx.transformPath("test_dir_renamed"); // Renaming directories - try ctx.dir.makeDir(test_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); try ctx.dir.rename(test_dir_path, ctx.dir, test_dir_renamed_path, io); // Ensure the directory was renamed @@ -1042,8 +1042,8 @@ test "Dir.rename directory onto empty dir" { const test_dir_path = try ctx.transformPath("test_dir"); const target_dir_path = try ctx.transformPath("target_dir_path"); - try ctx.dir.makeDir(test_dir_path); - try ctx.dir.makeDir(target_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); + try ctx.dir.makeDir(io, target_dir_path, .default_dir); try ctx.dir.rename(test_dir_path, ctx.dir, target_dir_path, io); // Ensure the directory was renamed @@ -1064,7 +1064,7 @@ test "Dir.rename directory onto non-empty dir" { const test_dir_path = try ctx.transformPath("test_dir"); const target_dir_path = try ctx.transformPath("target_dir_path"); - try ctx.dir.makeDir(test_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); var file = try target_dir.createFile(io, "test_file", .{ .read = true }); @@ -1093,7 +1093,7 @@ test "Dir.rename file <-> dir" { var file = try ctx.dir.createFile(io, test_file_path, .{ .read = true }); file.close(io); - try ctx.dir.makeDir(test_dir_path); + try ctx.dir.makeDir(io, test_dir_path, .default_dir); try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, ctx.dir, test_dir_path, io)); try testing.expectError(error.NotDir, ctx.dir.rename(test_dir_path, ctx.dir, test_file_path, io)); } @@ -1163,7 +1163,7 @@ test "renameAbsolute" { // Renaming directories const test_dir_name = "test_dir"; const renamed_test_dir_name = "test_dir_renamed"; - try tmp_dir.dir.makeDir(test_dir_name); + try tmp_dir.dir.makeDir(io, test_dir_name, .default_dir); try fs.renameAbsolute( try fs.path.join(allocator, &.{ base_path, test_dir_name }), try fs.path.join(allocator, &.{ base_path, renamed_test_dir_name }), @@ -1209,7 +1209,7 @@ test "deleteTree does not follow symlinks" { try setupSymlink(a, "../b", "b", .{ .is_directory = true }); } - try tmp.dir.deleteTree("a"); + try tmp.dir.deleteTree(io, "a"); try testing.expectError(error.FileNotFound, tmp.dir.access(io, "a", .{})); try tmp.dir.access(io, "b", .{}); @@ -1225,7 +1225,7 @@ test "deleteTree on a symlink" { try tmp.dir.writeFile(io, .{ .sub_path = "file", .data = "" }); try setupSymlink(tmp.dir, "file", "filelink", .{}); - try tmp.dir.deleteTree("filelink"); + try tmp.dir.deleteTree(io, "filelink"); try testing.expectError(error.FileNotFound, tmp.dir.access(io, "filelink", .{})); try tmp.dir.access(io, "file", .{}); @@ -1233,7 +1233,7 @@ test "deleteTree on a symlink" { try tmp.dir.makePath(io, "dir"); try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true }); - try tmp.dir.deleteTree("dirlink"); + try tmp.dir.deleteTree(io, "dirlink"); try testing.expectError(error.FileNotFound, tmp.dir.access(io, "dirlink", .{})); try tmp.dir.access(io, "dir", .{}); } @@ -1255,7 +1255,7 @@ test "makePath, put some files in it, deleteTree" { .data = "blah", }); - try ctx.dir.deleteTree(dir_path); + try ctx.dir.deleteTree(io, dir_path); try testing.expectError(error.FileNotFound, ctx.dir.openDir(io, dir_path, .{})); } }.impl); @@ -1291,7 +1291,7 @@ test "makePath in a directory that no longer exists" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.parent_dir.deleteTree(&tmp.sub_path); + try tmp.parent_dir.deleteTree(io, &tmp.sub_path); try testing.expectError(error.FileNotFound, tmp.dir.makePath(io, "sub-path")); } @@ -1302,7 +1302,7 @@ test "makePath but sub_path contains pre-existing file" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makeDir("foo"); + try tmp.dir.makeDir(io, "foo", .default_dir); try tmp.dir.writeFile(io, .{ .sub_path = "foo/bar", .data = "" }); try testing.expectError(error.NotDir, tmp.dir.makePath(io, "foo/bar/baz")); @@ -1319,10 +1319,10 @@ test "makepath existing directories" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makeDir("A"); + try tmp.dir.makeDir(io, "A", .default_dir); var tmpA = try tmp.dir.openDir(io, "A", .{}); defer tmpA.close(io); - try tmpA.makeDir("B"); + try tmpA.makeDir(io, "B", .default_dir); const testPath = "A" ++ fs.path.sep_str ++ "B" ++ fs.path.sep_str ++ "C"; try tmp.dir.makePath(io, testPath); @@ -1336,7 +1336,7 @@ test "makepath through existing valid symlink" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makeDir("realfolder"); + try tmp.dir.makeDir(io, "realfolder", .default_dir); try setupSymlink(tmp.dir, "." ++ fs.path.sep_str ++ "realfolder", "working-symlink", .{}); try tmp.dir.makePath(io, "working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); @@ -1419,7 +1419,7 @@ fn testFilenameLimits(io: Io, iterable_dir: Dir, maxed_filename: []const u8) !vo } // ensure that we can delete the tree - try iterable_dir.deleteTree(maxed_filename); + try iterable_dir.deleteTree(io, maxed_filename); } test "max file name component lengths" { @@ -1570,7 +1570,7 @@ test "access file" { try ctx.dir.writeFile(io, .{ .sub_path = file_path, .data = "" }); try ctx.dir.access(io, file_path, .{}); - try ctx.dir.deleteTree(dir_path); + try ctx.dir.deleteTree(io, dir_path); } }.impl); } @@ -2042,7 +2042,7 @@ test "'.' and '..' in Io.Dir functions" { const rename_path = try ctx.transformPath("./subdir/../rename"); const update_path = try ctx.transformPath("./subdir/../update"); - try ctx.dir.makeDir(subdir_path); + try ctx.dir.makeDir(io, subdir_path, .default_dir); try ctx.dir.access(io, subdir_path, .{}); var created_subdir = try ctx.dir.openDir(io, subdir_path, .{}); created_subdir.close(io); @@ -2120,7 +2120,7 @@ test "chmod" { try file.chmod(0o644); try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat(io)).mode & 0o7777); - try tmp.dir.makeDir("test_dir"); + try tmp.dir.makeDir(io, "test_dir", .default_dir); var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); @@ -2141,7 +2141,7 @@ test "chown" { defer file.close(io); try file.chown(null, null); - try tmp.dir.makeDir("test_dir"); + try tmp.dir.makeDir(io, "test_dir", .default_dir); var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); @@ -2165,7 +2165,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.createFile(invalid_path, .{})); - try testing.expectError(expected_err, ctx.dir.makeDir(invalid_path)); + try testing.expectError(expected_err, ctx.dir.makeDir(invalid_path, .default_dir)); try testing.expectError(expected_err, ctx.dir.makePath(invalid_path)); try testing.expectError(expected_err, ctx.dir.makeOpenPath(invalid_path, .{})); @@ -2191,7 +2191,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.readFile(invalid_path, &[_]u8{})); try testing.expectError(expected_err, ctx.dir.readFileAlloc(invalid_path, testing.allocator, .limited(0))); - try testing.expectError(expected_err, ctx.dir.deleteTree(invalid_path)); + try testing.expectError(expected_err, ctx.dir.deleteTree(io, invalid_path)); try testing.expectError(expected_err, ctx.dir.deleteTreeMinStackSize(invalid_path)); try testing.expectError(expected_err, ctx.dir.writeFile(io, .{ .sub_path = invalid_path, .data = "" })); diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 99d67ec132..9eb2ad5e96 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -616,7 +616,7 @@ pub const TmpDir = struct { pub fn cleanup(self: *TmpDir) void { self.dir.close(io); - self.parent_dir.deleteTree(&self.sub_path) catch {}; + self.parent_dir.deleteTree(io, &self.sub_path) catch {}; self.parent_dir.close(io); self.* = undefined; } diff --git a/src/Compilation.zig b/src/Compilation.zig index 79b2d51635..617421e279 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2823,12 +2823,9 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { return; } const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); - comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| { - log.warn("failed to delete temporary directory '{s}{c}{s}': {s}", .{ - comp.dirs.local_cache.path orelse ".", - fs.path.sep, - tmp_dir_sub_path, - @errorName(err), + comp.dirs.local_cache.handle.deleteTree(io, tmp_dir_sub_path) catch |err| { + log.warn("failed to delete temporary directory '{s}{c}{s}': {t}", .{ + comp.dirs.local_cache.path orelse ".", fs.path.sep, tmp_dir_sub_path, err, }); }; } @@ -2847,12 +2844,9 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { tmp_dir.handle.close(io); whole.tmp_artifact_directory = null; const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); - comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| { - log.warn("failed to delete temporary directory '{s}{c}{s}': {s}", .{ - comp.dirs.local_cache.path orelse ".", - fs.path.sep, - tmp_dir_sub_path, - @errorName(err), + comp.dirs.local_cache.handle.deleteTree(io, tmp_dir_sub_path) catch |err| { + log.warn("failed to delete temporary directory '{s}{c}{s}': {t}", .{ + comp.dirs.local_cache.path orelse ".", fs.path.sep, tmp_dir_sub_path, err, }); }; } @@ -3419,13 +3413,13 @@ fn renameTmpIntoCache( .windows => { if (seen_eaccess) return error.AccessDenied; seen_eaccess = true; - try cache_directory.handle.deleteTree(o_sub_path); + try cache_directory.handle.deleteTree(io, o_sub_path); continue; }, else => return error.AccessDenied, }, error.PathAlreadyExists => { - try cache_directory.handle.deleteTree(o_sub_path); + try cache_directory.handle.deleteTree(io, o_sub_path); continue; }, error.FileNotFound => { diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index aaba0c28cf..3552a7fc06 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -656,9 +656,11 @@ fn checkBuildFileExistence(f: *Fetch) RunError!void { /// This function populates `f.manifest` or leaves it `null`. fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { + const io = f.job_queue.io; const eb = &f.error_bundle; const arena = f.arena.allocator(); const manifest_bytes = pkg_root.root_dir.handle.readFileAllocOptions( + io, try fs.path.join(arena, &.{ pkg_root.sub_path, Manifest.basename }), arena, .limited(Manifest.max_bytes), @@ -1409,7 +1411,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U } } - try out_dir.deleteTree(".git"); + try out_dir.deleteTree(io, ".git"); return res; } @@ -1461,7 +1463,7 @@ pub fn renameTmpIntoCache(io: Io, cache_dir: Io.Dir, tmp_dir_sub_path: []const u cache_dir.rename(tmp_dir_sub_path, cache_dir, dest_dir_sub_path, io) catch |err| switch (err) { error.FileNotFound => { if (handled_missing_dir) return err; - cache_dir.makeDir(dest_dir_sub_path[0..1]) catch |mkd_err| switch (mkd_err) { + cache_dir.makeDir(io, dest_dir_sub_path[0..1], .default_dir) catch |mkd_err| switch (mkd_err) { error.PathAlreadyExists => handled_missing_dir = true, else => |e| return e, }; @@ -1469,7 +1471,7 @@ pub fn renameTmpIntoCache(io: Io, cache_dir: Io.Dir, tmp_dir_sub_path: []const u }, error.PathAlreadyExists, error.AccessDenied => { // Package has been already downloaded and may already be in use on the system. - cache_dir.deleteTree(tmp_dir_sub_path) catch { + cache_dir.deleteTree(io, tmp_dir_sub_path) catch { // Garbage files leftover in zig-cache/tmp/ is, as they say // on Star Trek, "operating within normal parameters". }; diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 1d6aa1a849..33ff982b66 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -253,7 +253,7 @@ pub const Repository = struct { while (try tree_iter.next()) |entry| { switch (entry.type) { .directory => { - try dir.makeDir(entry.name); + try dir.makeDir(io, entry.name, .default_dir); var subdir = try dir.openDir(io, entry.name, .{}); defer subdir.close(io); const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name }); @@ -296,7 +296,7 @@ pub const Repository = struct { .gitlink => { // Consistent with git archive behavior, create the directory but // do nothing else - try dir.makeDir(entry.name); + try dir.makeDir(io, entry.name, .default_dir); }, } } diff --git a/src/main.zig b/src/main.zig index 58f0e68301..a832a79dbe 100644 --- a/src/main.zig +++ b/src/main.zig @@ -7316,6 +7316,7 @@ fn loadManifest( ) !struct { Package.Manifest, Ast } { const manifest_bytes = while (true) { break options.dir.readFileAllocOptions( + io, Package.Manifest.basename, arena, .limited(Package.Manifest.max_bytes), diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 5889449bbe..bf3eade8f4 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -10,6 +10,7 @@ const ArrayList = std.ArrayList; gpa: Allocator, arena: Allocator, +io: Io, cases: std.array_list.Managed(Case), pub const IncrementalCase = struct { @@ -334,6 +335,7 @@ fn addFromDirInner( current_file: *[]const u8, b: *std.Build, ) !void { + const io = ctx.io; var it = try iterable_dir.walk(ctx.arena); var filenames: ArrayList([]const u8) = .empty; @@ -349,7 +351,7 @@ fn addFromDirInner( current_file.* = filename; const max_file_size = 10 * 1024 * 1024; - const src = try iterable_dir.readFileAllocOptions(filename, ctx.arena, .limited(max_file_size), .@"1", 0); + const src = try iterable_dir.readFileAllocOptions(io, filename, ctx.arena, .limited(max_file_size), .@"1", 0); // Parse the manifest var manifest = try TestManifest.parse(ctx.arena, src); diff --git a/test/standalone/posix/relpaths.zig b/test/standalone/posix/relpaths.zig index 70e9fad687..ed143ccdc2 100644 --- a/test/standalone/posix/relpaths.zig +++ b/test/standalone/posix/relpaths.zig @@ -5,13 +5,14 @@ const builtin = @import("builtin"); const std = @import("std"); const Io = std.Io; +const Allocator = std.mem.Allocator; pub fn main() !void { if (builtin.target.os.tag == .wasi) return; // Can link, but can't change into tmpDir - var Allocator = std.heap.DebugAllocator(.{}){}; - const a = Allocator.allocator(); - defer std.debug.assert(Allocator.deinit() == .ok); + var debug_allocator: std.heap.DebugAllocator(.{}) = .init; + const gpa = debug_allocator.allocator(); + defer std.debug.assert(debug_allocator.deinit() == .ok); var threaded: std.Io.Threaded = .init_single_threaded; const io = threaded.io(); @@ -24,22 +25,22 @@ pub fn main() !void { // Want to test relative paths, so cd into the tmpdir for these tests try tmp.dir.setAsCwd(); - try test_symlink(a, tmp); + try test_symlink(gpa, io, tmp); try test_link(io, tmp); } -fn test_symlink(a: std.mem.Allocator, tmp: std.testing.TmpDir) !void { +fn test_symlink(gpa: Allocator, io: Io, tmp: std.testing.TmpDir) !void { const target_name = "symlink-target"; const symlink_name = "symlinker"; // Create the target file - try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "nonsense" }); + try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "nonsense" }); if (builtin.target.os.tag == .windows) { - const wtarget_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, target_name); - const wsymlink_name = try std.unicode.wtf8ToWtf16LeAllocZ(a, symlink_name); - defer a.free(wtarget_name); - defer a.free(wsymlink_name); + const wtarget_name = try std.unicode.wtf8ToWtf16LeAllocZ(gpa, target_name); + const wsymlink_name = try std.unicode.wtf8ToWtf16LeAllocZ(gpa, symlink_name); + defer gpa.free(wtarget_name); + defer gpa.free(wsymlink_name); std.os.windows.CreateSymbolicLink(tmp.dir.fd, wsymlink_name, wtarget_name, false) catch |err| switch (err) { // Symlink requires admin privileges on windows, so this test can legitimately fail. diff --git a/test/standalone/windows_bat_args/fuzz.zig b/test/standalone/windows_bat_args/fuzz.zig index bbc0d94077..6c89c50e0b 100644 --- a/test/standalone/windows_bat_args/fuzz.zig +++ b/test/standalone/windows_bat_args/fuzz.zig @@ -9,6 +9,9 @@ pub fn main() anyerror!void { defer std.debug.assert(debug_alloc_inst.deinit() == .ok); const gpa = debug_alloc_inst.allocator(); + var threaded: Io.Threaded = .init(gpa); + const io = threaded.io(); + var it = try std.process.argsWithAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name @@ -58,15 +61,15 @@ pub fn main() anyerror!void { const preamble_len = buf.items.len; try buf.appendSlice(gpa, " %*"); - try tmp.dir.writeFile(.{ .sub_path = "args1.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args1.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); try buf.appendSlice(gpa, " %1 %2 %3 %4 %5 %6 %7 %8 %9"); - try tmp.dir.writeFile(.{ .sub_path = "args2.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args2.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); try buf.appendSlice(gpa, " \"%~1\" \"%~2\" \"%~3\" \"%~4\" \"%~5\" \"%~6\" \"%~7\" \"%~8\" \"%~9\""); - try tmp.dir.writeFile(.{ .sub_path = "args3.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args3.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); var i: u64 = 0; @@ -74,7 +77,7 @@ pub fn main() anyerror!void { const rand_arg = try randomArg(gpa, rand); defer gpa.free(rand_arg); - try testExec(gpa, &.{rand_arg}, null); + try testExec(gpa, io, &.{rand_arg}, null); i += 1; } diff --git a/test/standalone/windows_bat_args/test.zig b/test/standalone/windows_bat_args/test.zig index 558adc248f..04d2fa37f0 100644 --- a/test/standalone/windows_bat_args/test.zig +++ b/test/standalone/windows_bat_args/test.zig @@ -7,6 +7,9 @@ pub fn main() anyerror!void { defer std.debug.assert(debug_alloc_inst.deinit() == .ok); const gpa = debug_alloc_inst.allocator(); + var threaded: Io.Threaded = .init(gpa); + const io = threaded.io(); + var it = try std.process.argsWithAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name @@ -32,15 +35,15 @@ pub fn main() anyerror!void { const preamble_len = buf.items.len; try buf.appendSlice(gpa, " %*"); - try tmp.dir.writeFile(.{ .sub_path = "args1.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args1.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); try buf.appendSlice(gpa, " %1 %2 %3 %4 %5 %6 %7 %8 %9"); - try tmp.dir.writeFile(.{ .sub_path = "args2.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args2.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); try buf.appendSlice(gpa, " \"%~1\" \"%~2\" \"%~3\" \"%~4\" \"%~5\" \"%~6\" \"%~7\" \"%~8\" \"%~9\""); - try tmp.dir.writeFile(.{ .sub_path = "args3.bat", .data = buf.items }); + try tmp.dir.writeFile(io, .{ .sub_path = "args3.bat", .data = buf.items }); buf.shrinkRetainingCapacity(preamble_len); // Test cases are from https://github.com/rust-lang/rust/blob/master/tests/ui/std/windows-bat-args.rs diff --git a/test/standalone/windows_spawn/main.zig b/test/standalone/windows_spawn/main.zig index 1acae0aca2..0d82ecff97 100644 --- a/test/standalone/windows_spawn/main.zig +++ b/test/standalone/windows_spawn/main.zig @@ -65,9 +65,9 @@ pub fn main() anyerror!void { try std.testing.expectError(error.FileNotFound, testExecWithCwd(gpa, io, "hello.exe", "missing_dir", "")); // now add a .bat - try tmp.dir.writeFile(.{ .sub_path = "hello.bat", .data = "@echo hello from bat" }); + try tmp.dir.writeFile(io, .{ .sub_path = "hello.bat", .data = "@echo hello from bat" }); // and a .cmd - try tmp.dir.writeFile(.{ .sub_path = "hello.cmd", .data = "@echo hello from cmd" }); + try tmp.dir.writeFile(io, .{ .sub_path = "hello.cmd", .data = "@echo hello from cmd" }); // with extension should find the .bat (case insensitive) try testExec(gpa, "heLLo.bat", "hello from bat\r\n"); @@ -84,7 +84,7 @@ pub fn main() anyerror!void { // without extension should succeed (case insensitive) try testExec(gpa, "heLLo", "hello from exe\n"); - try tmp.dir.makeDir("something"); + try tmp.dir.makeDir(io, "something", .default_dir); try renameExe(tmp.dir, "hello", "something/hello.exe"); const relative_path_no_ext = try std.fs.path.join(gpa, &.{ tmp_relative_path, "something/hello" }); @@ -99,7 +99,7 @@ pub fn main() anyerror!void { try testExec(gpa, "heLLo", "hello from bat\r\n"); // Add a hello.exe that is not a valid executable - try tmp.dir.writeFile(.{ .sub_path = "hello.exe", .data = "invalid" }); + try tmp.dir.writeFile(io, .{ .sub_path = "hello.exe", .data = "invalid" }); // Trying to execute it with extension will give InvalidExe. This is a special // case for .EXE extensions, where if they ever try to get executed but they are diff --git a/test/tests.zig b/test/tests.zig index 5ca170c83c..015c3535bb 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -2135,12 +2135,12 @@ pub fn addCliTests(b: *std.Build) *Step { var dir = std.Io.Dir.cwd().openDir(io, tmp_path, .{}) catch @panic("unhandled"); defer dir.close(io); - dir.writeFile(.{ .sub_path = "fmt1.zig", .data = unformatted_code }) catch @panic("unhandled"); - dir.writeFile(.{ .sub_path = "fmt2.zig", .data = unformatted_code }) catch @panic("unhandled"); - dir.makeDir("subdir") catch @panic("unhandled"); + dir.writeFile(io, .{ .sub_path = "fmt1.zig", .data = unformatted_code }) catch @panic("unhandled"); + dir.writeFile(io, .{ .sub_path = "fmt2.zig", .data = unformatted_code }) catch @panic("unhandled"); + dir.makeDir(io, "subdir", .default_dir) catch @panic("unhandled"); var subdir = dir.openDir(io, "subdir", .{}) catch @panic("unhandled"); defer subdir.close(io); - subdir.writeFile(.{ .sub_path = "fmt3.zig", .data = unformatted_code }) catch @panic("unhandled"); + subdir.writeFile(io, .{ .sub_path = "fmt3.zig", .data = unformatted_code }) catch @panic("unhandled"); // Test zig fmt affecting only the appropriate files. const run1 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "fmt1.zig" }); -- cgit v1.2.3 From 4a53e5b0b4131c6b8e18bb551e8215e425f8ac71 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 20:03:50 -0800 Subject: fix a handful of compilation errors related to std.fs migration --- lib/compiler/resinator/cli.zig | 2 +- lib/compiler/resinator/main.zig | 2 +- lib/compiler/std-docs.zig | 18 +++---- lib/std/Build.zig | 2 +- lib/std/Build/Cache.zig | 2 +- lib/std/Build/Step.zig | 2 +- lib/std/Build/Step/Run.zig | 4 +- lib/std/Build/WebServer.zig | 2 +- lib/std/Io/Dir.zig | 7 +-- lib/std/Io/File.zig | 4 ++ lib/std/Io/File/Atomic.zig | 7 ++- lib/std/Io/net/test.zig | 2 +- lib/std/Io/test.zig | 2 +- lib/std/fs/test.zig | 26 +++++----- lib/std/posix/test.zig | 2 +- lib/std/process/Child.zig | 94 +++++++++++++++++----------------- lib/std/tar.zig | 36 ++++++------- src/Compilation.zig | 15 +++--- src/Package/Fetch.zig | 12 ++--- src/link.zig | 14 +++-- src/link/Lld.zig | 8 +-- src/main.zig | 13 ++--- test/src/Cases.zig | 3 +- test/standalone/child_process/main.zig | 2 +- 24 files changed, 148 insertions(+), 133 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index 5588390197..d2dd71b1f6 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -2010,7 +2010,7 @@ test "maybeAppendRC" { // Now delete the file and try again. But this time change the input format // to non-rc. - try tmp.dir.deleteFile("foo"); + try tmp.dir.deleteFile(io, "foo"); options.input_format = .res; try options.maybeAppendRC(io, tmp.dir); try std.testing.expectEqualStrings("foo", options.input_source.filename); diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index afe1dcbe91..6c12903f06 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -440,7 +440,7 @@ const IoStream = struct { // Delete the output file on error file.close(io); // Failing to delete is not really a big deal, so swallow any errors - Io.Dir.cwd().deleteFile(self.name) catch {}; + Io.Dir.cwd().deleteFile(io, self.name) catch {}; }, .stdio, .memory, .closed => return, } diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 6452496305..538558fe48 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -72,8 +72,8 @@ pub fn main() !void { const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port}); std.Io.File.stdout().writeAll(url_with_newline) catch {}; if (should_open_browser) { - openBrowserTab(gpa, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { - std.log.err("unable to open browser: {s}", .{@errorName(err)}); + openBrowserTab(gpa, io, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { + std.log.err("unable to open browser: {t}", .{err}); }; } @@ -89,7 +89,7 @@ pub fn main() !void { while (true) { const connection = try http_server.accept(); _ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| { - std.log.err("unable to accept connection: {s}", .{@errorName(err)}); + std.log.err("unable to accept connection: {t}", .{err}); connection.stream.close(io); continue; }; @@ -328,7 +328,7 @@ fn buildWasmBinary( child.stdin_behavior = .Pipe; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; - try child.spawn(); + try child.spawn(io); var poller = std.Io.poll(gpa, enum { stdout, stderr }, .{ .stdout = child.stdout.?, @@ -434,13 +434,13 @@ fn sendMessage(io: Io, file: std.Io.File, tag: std.zig.Client.Message.Tag) !void }; } -fn openBrowserTab(gpa: Allocator, url: []const u8) !void { +fn openBrowserTab(gpa: Allocator, io: Io, url: []const u8) !void { // Until https://github.com/ziglang/zig/issues/19205 is implemented, we // spawn a thread for this child process. - _ = try std.Thread.spawn(.{}, openBrowserTabThread, .{ gpa, url }); + _ = try std.Thread.spawn(.{}, openBrowserTabThread, .{ gpa, io, url }); } -fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void { +fn openBrowserTabThread(gpa: Allocator, io: Io, url: []const u8) !void { const main_exe = switch (builtin.os.tag) { .windows => "explorer", .macos => "open", @@ -450,6 +450,6 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void { child.stdin_behavior = .Ignore; child.stdout_behavior = .Ignore; child.stderr_behavior = .Ignore; - try child.spawn(); - _ = try child.wait(); + try child.spawn(io); + _ = try child.wait(io); } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 746b41860b..ae2ab1c4d0 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1838,7 +1838,7 @@ pub fn runAllowFail( child.env_map = &b.graph.env_map; try Step.handleVerbose2(b, null, child.env_map, argv); - try child.spawn(); + try child.spawn(io); var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); const stdout = stdout_reader.interface.allocRemaining(b.allocator, .limited(max_output_size)) catch { diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index d2ba33c74d..b97efc7677 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1300,7 +1300,7 @@ fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { }); defer { file.close(io); - dir.deleteFile(test_out_file) catch {}; + dir.deleteFile(io, test_out_file) catch {}; } return (try file.stat(io)).mtime; diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 8115aaa1a1..9c7fcc757f 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -455,7 +455,7 @@ pub fn evalZigProcess( child.request_resource_usage_statistics = true; child.progress_node = prog_node; - child.spawn() catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); + child.spawn(io) catch |err| return s.fail("failed to spawn zig compiler {s}: {t}", .{ argv[0], err }); const zp = try gpa.create(ZigProcess); zp.* = .{ diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 19d2e7e61c..95024061d8 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1689,7 +1689,7 @@ fn evalZigTest( }; while (true) { - try child.spawn(); + try child.spawn(io); var poller = std.Io.poll(gpa, StdioPollEnum, .{ .stdout = child.stdout.?, .stderr = child.stderr.?, @@ -2168,7 +2168,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { const io = b.graph.io; const arena = b.allocator; - try child.spawn(); + try child.spawn(io); errdefer _ = child.kill(io) catch {}; try child.waitForSpawn(); diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index 72306cbab9..5f633c5948 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -580,7 +580,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim child.stdin_behavior = .Pipe; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; - try child.spawn(); + try child.spawn(io); var poller = Io.poll(gpa, enum { stdout, stderr }, .{ .stdout = child.stdout.?, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index cf5e2b4c72..d6d6aa1be2 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1366,7 +1366,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { => |e| return e, }; } else { - if (parent_dir.deleteFile(name)) { + if (parent_dir.deleteFile(io, name)) { continue :process_stack; } else |err| switch (err) { error.FileNotFound => continue :process_stack, @@ -1477,7 +1477,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, dir_name = result; continue :scan_dir; } else { - if (dir.deleteFile(entry.name)) { + if (dir.deleteFile(io, entry.name)) { continue :dir_it; } else |err| switch (err) { error.FileNotFound => continue :dir_it, @@ -1567,7 +1567,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin => |e| return e, }; } else { - if (dir.deleteFile(sub_path)) { + if (dir.deleteFile(io, sub_path)) { return null; } else |err| switch (err) { error.FileNotFound => return null, @@ -1588,6 +1588,7 @@ fn deleteTreeOpenInitialSubpath(dir: Dir, io: Io, sub_path: []const u8, kind_hin error.FileBusy, error.BadPathName, error.NetworkNotFound, + error.Canceled, error.Unexpected, => |e| return e, } diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig index 302d2a8ca5..6d4dd4f323 100644 --- a/lib/std/Io/File.zig +++ b/lib/std/Io/File.zig @@ -407,6 +407,10 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( return @intFromEnum(self); } + pub fn fromMode(mode: std.posix.mode_t) @This() { + return @enumFromInt(mode); + } + /// Returns `true` if and only if no class has write permissions. pub fn readOnly(self: @This()) bool { const mode = toMode(self); diff --git a/lib/std/Io/File/Atomic.zig b/lib/std/Io/File/Atomic.zig index ccb81815ed..7d412703ed 100644 --- a/lib/std/Io/File/Atomic.zig +++ b/lib/std/Io/File/Atomic.zig @@ -20,7 +20,7 @@ pub const InitError = File.OpenError; pub fn init( io: Io, dest_basename: []const u8, - mode: File.Mode, + permissions: File.Permissions, dir: Dir, close_dir_on_deinit: bool, write_buffer: []u8, @@ -28,7 +28,10 @@ pub fn init( while (true) { const random_integer = std.crypto.random.int(u64); const tmp_sub_path = std.fmt.hex(random_integer); - const file = dir.createFile(io, &tmp_sub_path, .{ .mode = mode, .exclusive = true }) catch |err| switch (err) { + const file = dir.createFile(io, &tmp_sub_path, .{ + .permissions = permissions, + .exclusive = true, + }) catch |err| switch (err) { error.PathAlreadyExists => continue, else => |e| return e, }; diff --git a/lib/std/Io/net/test.zig b/lib/std/Io/net/test.zig index c9ed0d3284..23edab5a5d 100644 --- a/lib/std/Io/net/test.zig +++ b/lib/std/Io/net/test.zig @@ -278,7 +278,7 @@ test "listen on a unix socket, send bytes, receive bytes" { defer testing.allocator.free(socket_path); const socket_addr = try net.UnixAddress.init(socket_path); - defer Io.Dir.cwd().deleteFile(socket_path) catch {}; + defer Io.Dir.cwd().deleteFile(io, socket_path) catch {}; var server = try socket_addr.listen(io, .{}); defer server.socket.close(io); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index 9763fb2397..02bdb591d0 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -60,7 +60,7 @@ test "write a file, read it, then delete it" { try expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data)); try expect(mem.eql(u8, contents[contents.len - "end".len ..], "end")); } - try tmp.dir.deleteFile(tmp_file_name); + try tmp.dir.deleteFile(io, tmp_file_name); } test "File seek ops" { diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index edc15526b2..da0a0cff79 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -873,7 +873,7 @@ test "file operations on directories" { try ctx.dir.makeDir(io, test_dir_name, .default_dir); try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); - try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); + try testing.expectError(error.IsDir, ctx.dir.deleteFile(io, test_dir_name)); switch (native_os) { .dragonfly, .netbsd => { // no error when reading a directory. See https://github.com/ziglang/zig/issues/5732 @@ -942,7 +942,7 @@ test "deleteDir" { try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); // deleting an empty directory - try ctx.dir.deleteFile(test_file_path); + try ctx.dir.deleteFile(io, test_file_path); try ctx.dir.deleteDir(test_dir_path); } }.impl); @@ -1671,13 +1671,13 @@ test "copyFile" { const dest_file2 = try ctx.transformPath("tmp_test_copy_file3.txt"); try ctx.dir.writeFile(io, .{ .sub_path = src_file, .data = data }); - defer ctx.dir.deleteFile(src_file) catch {}; + defer ctx.dir.deleteFile(io, src_file) catch {}; try ctx.dir.copyFile(src_file, ctx.dir, dest_file, .{}); - defer ctx.dir.deleteFile(dest_file) catch {}; + defer ctx.dir.deleteFile(io, dest_file) catch {}; try ctx.dir.copyFile(src_file, ctx.dir, dest_file2, .{ .override_mode = File.default_mode }); - defer ctx.dir.deleteFile(dest_file2) catch {}; + defer ctx.dir.deleteFile(io, dest_file2) catch {}; try expectFileContents(io, ctx.dir, dest_file, data); try expectFileContents(io, ctx.dir, dest_file2, data); @@ -1713,7 +1713,7 @@ test "AtomicFile" { const content = try ctx.dir.readFileAlloc(io, test_out_file, allocator, .limited(9999)); try testing.expectEqualStrings(test_content, content); - try ctx.dir.deleteFile(test_out_file); + try ctx.dir.deleteFile(io, test_out_file); } }.impl); } @@ -2055,7 +2055,7 @@ test "'.' and '..' in Io.Dir functions" { try ctx.dir.rename(copy_path, ctx.dir, rename_path, io); const renamed_file = try ctx.dir.openFile(io, rename_path, .{}); renamed_file.close(io); - try ctx.dir.deleteFile(rename_path); + try ctx.dir.deleteFile(io, rename_path); try ctx.dir.writeFile(io, .{ .sub_path = update_path, .data = "something" }); var dir = ctx.dir; @@ -2113,19 +2113,19 @@ test "chmod" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 }); + const file = try tmp.dir.createFile(io, "test_file", .{ .permissions = .fromMode(0o600) }); defer file.close(io); - try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat(io)).mode & 0o7777); + try testing.expectEqual(@as(posix.mode_t, 0o600), (try file.stat(io)).permissions.toMode() & 0o7777); - try file.chmod(0o644); - try testing.expectEqual(@as(File.Mode, 0o644), (try file.stat(io)).mode & 0o7777); + try file.setPermissions(io, .fromMode(0o644)); + try testing.expectEqual(@as(posix.mode_t, 0o644), (try file.stat(io)).permissions.toMode() & 0o7777); try tmp.dir.makeDir(io, "test_dir", .default_dir); var dir = try tmp.dir.openDir(io, "test_dir", .{ .iterate = true }); defer dir.close(io); - try dir.chmod(0o700); - try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat(io)).mode & 0o7777); + try dir.setPermissions(io, .fromMode(0o700)); + try testing.expectEqual(@as(posix.mode_t, 0o700), (try dir.stat(io)).permissions.toMode() & 0o7777); } test "chown" { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 756ecfd63f..b5255ad2a1 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -144,7 +144,7 @@ test "linkat with different directories" { const subdir = try tmp.dir.makeOpenPath("subdir", .{}); - defer tmp.dir.deleteFile(target_name) catch {}; + defer tmp.dir.deleteFile(io, target_name) catch {}; try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); // Test 1: link from file in subdir back up to target in parent directory diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index dbbacc496c..17139e66b8 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -1,4 +1,4 @@ -const ChildProcess = @This(); +const Child = @This(); const builtin = @import("builtin"); const native_os = builtin.os.tag; @@ -31,7 +31,7 @@ pub const Id = switch (native_os) { id: Id, thread_handle: if (native_os == .windows) windows.HANDLE else void, -allocator: mem.Allocator, +allocator: Allocator, /// The writing end of the child process's standard input pipe. /// Usage requires `stdin_behavior == StdIo.Pipe`. @@ -229,7 +229,7 @@ pub const StdIo = enum { }; /// First argument in argv is the executable. -pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { +pub fn init(argv: []const []const u8, allocator: Allocator) Child { return .{ .allocator = allocator, .argv = argv, @@ -252,7 +252,7 @@ pub fn init(argv: []const []const u8, allocator: mem.Allocator) ChildProcess { }; } -pub fn setUserName(self: *ChildProcess, name: []const u8) !void { +pub fn setUserName(self: *Child, name: []const u8) !void { const user_info = try process.getUserInfo(name); self.uid = user_info.uid; self.gid = user_info.gid; @@ -260,7 +260,7 @@ pub fn setUserName(self: *ChildProcess, name: []const u8) !void { /// On success must call `kill` or `wait`. /// After spawning the `id` is available. -pub fn spawn(self: *ChildProcess) SpawnError!void { +pub fn spawn(self: *Child, io: Io) SpawnError!void { if (!process.can_spawn) { @compileError("the target operating system cannot spawn processes"); } @@ -268,17 +268,17 @@ pub fn spawn(self: *ChildProcess) SpawnError!void { if (native_os == .windows) { return self.spawnWindows(); } else { - return self.spawnPosix(); + return self.spawnPosix(io); } } -pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term { - try self.spawn(); - return self.wait(); +pub fn spawnAndWait(child: *Child, io: Io) SpawnError!Term { + try child.spawn(io); + return child.wait(io); } /// Forcibly terminates child process and then cleans up all resources. -pub fn kill(self: *ChildProcess, io: Io) !Term { +pub fn kill(self: *Child, io: Io) !Term { if (native_os == .windows) { return self.killWindows(io, 1); } else { @@ -286,7 +286,7 @@ pub fn kill(self: *ChildProcess, io: Io) !Term { } } -pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { +pub fn killWindows(self: *Child, io: Io, exit_code: windows.UINT) !Term { if (self.term) |term| { self.cleanupStreams(io); return term; @@ -308,7 +308,7 @@ pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { return self.term.?; } -pub fn killPosix(self: *ChildProcess, io: Io) !Term { +pub fn killPosix(self: *Child, io: Io) !Term { if (self.term) |term| { self.cleanupStreams(io); return term; @@ -325,7 +325,7 @@ pub const WaitError = SpawnError || std.os.windows.GetProcessMemoryInfoError; /// On some targets, `spawn` may not report all spawn errors, such as `error.InvalidExe`. /// This function will block until any spawn errors can be reported, and return them. -pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { +pub fn waitForSpawn(self: *Child) SpawnError!void { if (native_os == .windows) return; // `spawn` reports everything if (self.term) |term| { _ = term catch |spawn_err| return spawn_err; @@ -355,7 +355,7 @@ pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { } /// Blocks until child process terminates and then cleans up all resources. -pub fn wait(self: *ChildProcess, io: Io) WaitError!Term { +pub fn wait(self: *Child, io: Io) WaitError!Term { try self.waitForSpawn(); // report spawn errors if (self.term) |term| { self.cleanupStreams(io); @@ -381,7 +381,7 @@ pub const RunResult = struct { /// /// The process must be started with stdout_behavior and stderr_behavior == .Pipe pub fn collectOutput( - child: ChildProcess, + child: Child, /// Used for `stdout` and `stderr`. allocator: Allocator, stdout: *ArrayList(u8), @@ -446,7 +446,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { expand_arg0: Arg0Expand = .no_expand, progress_node: std.Progress.Node = std.Progress.Node.none, }) RunError!RunResult { - var child = ChildProcess.init(args.argv, allocator); + var child = Child.init(args.argv, allocator); child.stdin_behavior = .Ignore; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; @@ -461,7 +461,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { var stderr: ArrayList(u8) = .empty; defer stderr.deinit(allocator); - try child.spawn(); + try child.spawn(io); errdefer { _ = child.kill(io) catch {}; } @@ -474,7 +474,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { }; } -fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { +fn waitUnwrappedWindows(self: *Child, io: Io) WaitError!void { const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false); self.term = @as(SpawnError!Term, x: { @@ -496,7 +496,7 @@ fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { return result; } -fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { +fn waitUnwrappedPosix(self: *Child, io: Io) void { const res: posix.WaitPidResult = res: { if (self.request_resource_usage_statistics) { switch (native_os) { @@ -531,11 +531,11 @@ fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { self.handleWaitResult(status); } -fn handleWaitResult(self: *ChildProcess, status: u32) void { +fn handleWaitResult(self: *Child, status: u32) void { self.term = statusToTerm(status); } -fn cleanupStreams(self: *ChildProcess, io: Io) void { +fn cleanupStreams(self: *Child, io: Io) void { if (self.stdin) |*stdin| { stdin.close(io); self.stdin = null; @@ -561,7 +561,7 @@ fn statusToTerm(status: u32) Term { Term{ .Unknown = status }; } -fn spawnPosix(self: *ChildProcess) SpawnError!void { +fn spawnPosix(self: *Child, io: Io) SpawnError!void { // The child process does need to access (one end of) these pipes. However, // we must initially set CLOEXEC to avoid a race condition. If another thread // is racing to spawn a different child process, we don't want it to inherit @@ -659,7 +659,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { })).ptr; } else { // TODO come up with a solution for this. - @panic("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process"); + @panic("missing std lib enhancement: std.process.Child implementation has no way to collect the environment variables to forward to the child process"); } }; @@ -671,41 +671,41 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { const pid_result = try posix.fork(); if (pid_result == 0) { // we are the child - setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); - setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); - setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); + setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); + setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); + setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(io, err_pipe[1], err); if (self.cwd_dir) |cwd| { - posix.fchdir(cwd.handle) catch |err| forkChildErrReport(err_pipe[1], err); + posix.fchdir(cwd.handle) catch |err| forkChildErrReport(io, err_pipe[1], err); } else if (self.cwd) |cwd| { - posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err); + posix.chdir(cwd) catch |err| forkChildErrReport(io, err_pipe[1], err); } // Must happen after fchdir above, the cwd file descriptor might be // equal to prog_fileno and be clobbered by this dup2 call. - if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err); + if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(io, err_pipe[1], err); if (self.gid) |gid| { - posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err); + posix.setregid(gid, gid) catch |err| forkChildErrReport(io, err_pipe[1], err); } if (self.uid) |uid| { - posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); + posix.setreuid(uid, uid) catch |err| forkChildErrReport(io, err_pipe[1], err); } if (self.pgid) |pid| { - posix.setpgid(0, pid) catch |err| forkChildErrReport(err_pipe[1], err); + posix.setpgid(0, pid) catch |err| forkChildErrReport(io, err_pipe[1], err); } if (self.start_suspended) { - posix.kill(posix.getpid(), .STOP) catch |err| forkChildErrReport(err_pipe[1], err); + posix.kill(posix.getpid(), .STOP) catch |err| forkChildErrReport(io, err_pipe[1], err); } const err = switch (self.expand_arg0) { .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp), }; - forkChildErrReport(err_pipe[1], err); + forkChildErrReport(io, err_pipe[1], err); } // we are the parent @@ -750,7 +750,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { self.progress_node.setIpcFd(prog_pipe[0]); } -fn spawnWindows(self: *ChildProcess) SpawnError!void { +fn spawnWindows(self: *Child) SpawnError!void { var saAttr = windows.SECURITY_ATTRIBUTES{ .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES), .bInheritHandle = windows.TRUE, @@ -880,7 +880,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { const app_name_wtf8 = self.argv[0]; const app_name_is_absolute = fs.path.isAbsolute(app_name_wtf8); - // the cwd set in ChildProcess is in effect when choosing the executable path + // the cwd set in Child is in effect when choosing the executable path // to match posix semantics var cwd_path_w_needs_free = false; const cwd_path_w = x: { @@ -965,7 +965,7 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void { // If the app name had path separators, that disallows PATH searching, // and there's no need to search the PATH if the app name is absolute. // We still search the path if the cwd is absolute because of the - // "cwd set in ChildProcess is in effect when choosing the executable path + // "cwd set in Child is in effect when choosing the executable path // to match posix semantics" behavior--we don't want to skip searching // the PATH just because we were trying to set the cwd of the child process. if (app_dirname_w != null or app_name_is_absolute) { @@ -1039,8 +1039,8 @@ fn destroyPipe(pipe: [2]posix.fd_t) void { // Child of fork calls this to report an error to the fork parent. // Then the child exits. -fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { - writeIntFd(fd, @as(ErrInt, @intFromError(err))) catch {}; +fn forkChildErrReport(io: Io, fd: i32, err: Child.SpawnError) noreturn { + writeIntFd(io, fd, @as(ErrInt, @intFromError(err))) catch {}; // If we're linking libc, some naughty applications may have registered atexit handlers // which we really do not want to run in the fork child. I caught LLVM doing this and // it caused a deadlock instead of doing an exit syscall. In the words of Avril Lavigne, @@ -1052,9 +1052,9 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { posix.system.exit(1); } -fn writeIntFd(fd: i32, value: ErrInt) !void { +fn writeIntFd(io: Io, fd: i32, value: ErrInt) !void { var buffer: [8]u8 = undefined; - var fw: File.Writer = .initStreaming(.{ .handle = fd }, &buffer); + var fw: File.Writer = .initStreaming(.{ .handle = fd }, io, &buffer); fw.interface.writeInt(u64, value, .little) catch unreachable; fw.interface.flush() catch return error.SystemResources; } @@ -1078,7 +1078,7 @@ const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); /// Note: `app_buf` should not contain any leading path separators. /// Note: If the dir is the cwd, dir_buf should be empty (len = 0). fn windowsCreateProcessPathExt( - allocator: mem.Allocator, + allocator: Allocator, dir_buf: *ArrayList(u16), app_buf: *ArrayList(u16), pathext: [:0]const u16, @@ -1525,9 +1525,9 @@ const WindowsCommandLineCache = struct { script_cmd_line: ?[:0]u16 = null, cmd_exe_path: ?[:0]u16 = null, argv: []const []const u8, - allocator: mem.Allocator, + allocator: Allocator, - fn init(allocator: mem.Allocator, argv: []const []const u8) WindowsCommandLineCache { + fn init(allocator: Allocator, argv: []const []const u8) WindowsCommandLineCache { return .{ .allocator = allocator, .argv = argv, @@ -1571,7 +1571,7 @@ const WindowsCommandLineCache = struct { /// Returns the absolute path of `cmd.exe` within the Windows system directory. /// The caller owns the returned slice. -fn windowsCmdExePath(allocator: mem.Allocator) error{ OutOfMemory, Unexpected }![:0]u16 { +fn windowsCmdExePath(allocator: Allocator) error{ OutOfMemory, Unexpected }![:0]u16 { var buf = try ArrayList(u16).initCapacity(allocator, 128); errdefer buf.deinit(allocator); while (true) { @@ -1608,7 +1608,7 @@ const ArgvToCommandLineError = error{ OutOfMemory, InvalidWtf8, InvalidArg0 }; /// /// When executing `.bat`/`.cmd` scripts, use `argvToScriptCommandLineWindows` instead. fn argvToCommandLineWindows( - allocator: mem.Allocator, + allocator: Allocator, argv: []const []const u8, ) ArgvToCommandLineError![:0]u16 { var buf = std.array_list.Managed(u8).init(allocator); @@ -1784,7 +1784,7 @@ const ArgvToScriptCommandLineError = error{ /// Should only be used when spawning `.bat`/`.cmd` scripts, see `argvToCommandLineWindows` otherwise. /// The `.bat`/`.cmd` file must be known to both have the `.bat`/`.cmd` extension and exist on the filesystem. fn argvToScriptCommandLineWindows( - allocator: mem.Allocator, + allocator: Allocator, /// Path to the `.bat`/`.cmd` script. If this path is relative, it is assumed to be relative to the CWD. /// The script must have been verified to exist at this path before calling this function. script_path: []const u16, diff --git a/lib/std/tar.zig b/lib/std/tar.zig index 5e7215f1d7..7bb20a9959 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -610,7 +610,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } }, .file => { - if (createDirAndFile(io, dir, file_name, fileMode(file.mode, options))) |fs_file| { + if (createDirAndFile(io, dir, file_name, filePermissions(file.mode, options))) |fs_file| { defer fs_file.close(io); var file_writer = fs_file.writer(io, &file_contents_buffer); try it.streamRemaining(file, &file_writer.interface); @@ -638,12 +638,12 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } } -fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { - const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }) catch |err| { +fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, permissions: Io.File.Permissions) !Io.File { + const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { try dir.makePath(io, dir_name); - return try dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }); + return try dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }); } } return err; @@ -880,9 +880,9 @@ test "create file and symlink" { var root = testing.tmpDir(.{}); defer root.cleanup(); - var file = try createDirAndFile(io, root.dir, "file1", default_mode); + var file = try createDirAndFile(io, root.dir, "file1", .default_file); file.close(io); - file = try createDirAndFile(io, root.dir, "a/b/c/file2", default_mode); + file = try createDirAndFile(io, root.dir, "a/b/c/file2", .default_file); file.close(io); createDirAndSymlink(io, root.dir, "a/b/c/file2", "symlink1") catch |err| { @@ -894,7 +894,7 @@ test "create file and symlink" { // Danglink symlnik, file created later try createDirAndSymlink(io, root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); - file = try createDirAndFile(io, root.dir, "g/h/i/file4", default_mode); + file = try createDirAndFile(io, root.dir, "g/h/i/file4", .default_file); file.close(io); } @@ -1118,30 +1118,30 @@ fn normalizePath(bytes: []u8) []u8 { return bytes; } -const default_mode = Io.File.default_mode; - // File system mode based on tar header mode and mode_mode options. -fn fileMode(mode: u32, options: PipeOptions) Io.File.Mode { +fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions { + const default_mode = 0o666; + if (!std.fs.has_executable_bit or options.mode_mode == .ignore) - return default_mode; + return .fromMode(default_mode); const S = std.posix.S; // The mode from the tar file is inspected for the owner executable bit. if (mode & S.IXUSR == 0) - return default_mode; + return .fromMode(default_mode); // This bit is copied to the group and other executable bits. // Other bits of the mode are left as the default when creating files. - return default_mode | S.IXUSR | S.IXGRP | S.IXOTH; + return .fromMode(default_mode | S.IXUSR | S.IXGRP | S.IXOTH); } -test fileMode { +test filePermissions { if (!std.fs.has_executable_bit) return error.SkipZigTest; - try testing.expectEqual(default_mode, fileMode(0o744, PipeOptions{ .mode_mode = .ignore })); - try testing.expectEqual(0o777, fileMode(0o744, PipeOptions{})); - try testing.expectEqual(0o666, fileMode(0o644, PipeOptions{})); - try testing.expectEqual(0o666, fileMode(0o655, PipeOptions{})); + try testing.expectEqual(0o666, filePermissions(0o744, PipeOptions{ .mode_mode = .ignore })); + try testing.expectEqual(0o777, filePermissions(0o744, PipeOptions{})); + try testing.expectEqual(0o666, filePermissions(0o644, PipeOptions{})); + try testing.expectEqual(0o666, filePermissions(0o655, PipeOptions{})); } test "executable bit" { diff --git a/src/Compilation.zig b/src/Compilation.zig index 617421e279..c63fa9a3c1 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5782,7 +5782,7 @@ pub fn translateC( } // Just to save disk space, we delete the file because it is never needed again. - cache_tmp_dir.deleteFile(dep_basename) catch |err| { + cache_tmp_dir.deleteFile(io, dep_basename) catch |err| { log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err }); }; } @@ -6314,11 +6314,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } // Just to save disk space, we delete the files that are never needed again. - defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(fs.path.basename(diag_file_path)) catch |err| switch (err) { + defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(diag_file_path)) catch |err| switch (err) { error.FileNotFound => {}, // the file wasn't created due to an error we reported else => log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }), }; - defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(fs.path.basename(dep_file_path)) catch |err| switch (err) { + defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(dep_file_path)) catch |err| switch (err) { error.FileNotFound => {}, // the file wasn't created due to an error we reported else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }), }; @@ -6329,7 +6329,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr child.stdout_behavior = .Inherit; child.stderr_behavior = .Inherit; - const term = child.spawnAndWait() catch |err| { + const term = child.spawnAndWait(io) catch |err| { return comp.failCObj(c_object, "failed to spawn zig clang (passthrough mode) {s}: {s}", .{ argv.items[0], @errorName(err) }); }; switch (term) { @@ -6347,7 +6347,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr child.stdout_behavior = .Ignore; child.stderr_behavior = .Pipe; - try child.spawn(); + try child.spawn(io); var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32))); @@ -6723,6 +6723,7 @@ fn spawnZigRc( argv: []const []const u8, child_progress_node: std.Progress.Node, ) !void { + const io = comp.io; var node_name: std.ArrayList(u8) = .empty; defer node_name.deinit(arena); @@ -6732,8 +6733,8 @@ fn spawnZigRc( child.stderr_behavior = .Pipe; child.progress_node = child_progress_node; - child.spawn() catch |err| { - return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv[0], @errorName(err) }); + child.spawn(io) catch |err| { + return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{ argv[0], err }); }; var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{ diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 3552a7fc06..e9753734e9 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -1347,7 +1347,7 @@ fn unzip( .diagnostics = &diagnostics, }) catch |err| return f.fail(f.location_tok, try eb.printString("zip extract failed: {t}", .{err})); - cache_root.handle.deleteFile(&zip_path) catch |err| + cache_root.handle.deleteFile(io, &zip_path) catch |err| return f.fail(f.location_tok, try eb.printString("delete temporary zip failed: {t}", .{err})); return .{ .root_dir = diagnostics.root_dir }; @@ -1547,7 +1547,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute .fs_path = fs_path, .failure = undefined, // to be populated by the worker }; - group.async(io, workerDeleteFile, .{ root_dir, deleted_file }); + group.async(io, workerDeleteFile, .{ io, root_dir, deleted_file }); try deleted_files.append(deleted_file); continue; } @@ -1669,8 +1669,8 @@ fn workerHashFile(dir: Io.Dir, hashed_file: *HashedFile) void { hashed_file.failure = hashFileFallible(dir, hashed_file); } -fn workerDeleteFile(dir: Io.Dir, deleted_file: *DeletedFile) void { - deleted_file.failure = deleteFileFallible(dir, deleted_file); +fn workerDeleteFile(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) void { + deleted_file.failure = deleteFileFallible(io, dir, deleted_file); } fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Error!void { @@ -1712,8 +1712,8 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er hashed_file.size = file_size; } -fn deleteFileFallible(dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { - try dir.deleteFile(deleted_file.fs_path); +fn deleteFileFallible(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { + try dir.deleteFile(io, deleted_file.fs_path); } fn setExecutable(file: Io.File) !void { diff --git a/src/link.zig b/src/link.zig index ff6d938e6f..7ebe1c6ba2 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1235,22 +1235,26 @@ pub const File = struct { ty: InternPool.Index, }; - pub fn determineMode( + pub fn determinePermissions( output_mode: std.builtin.OutputMode, link_mode: std.builtin.LinkMode, - ) Io.File.Mode { + ) Io.File.Permissions { // On common systems with a 0o022 umask, 0o777 will still result in a file created // with 0o755 permissions, but it works appropriately if the system is configured // more leniently. As another data point, C's fopen seems to open files with the // 666 mode. - const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777; + const executable_mode: Io.FilePermissions = if (builtin.target.os.tag == .windows) + .default_file + else + .fromMode(0o777); + switch (output_mode) { .Lib => return switch (link_mode) { .dynamic => executable_mode, - .static => Io.File.default_mode, + .static => .default_file, }, .Exe => return executable_mode, - .Obj => return Io.File.default_mode, + .Obj => return .default_file, } } diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 6920c12762..e3127b24bf 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1608,13 +1608,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi child.stdout_behavior = .Inherit; child.stderr_behavior = .Inherit; - break :term child.spawnAndWait(); + break :term child.spawnAndWait(io); } else term: { child.stdin_behavior = .Ignore; child.stdout_behavior = .Ignore; child.stderr_behavior = .Pipe; - child.spawn() catch |err| break :term err; + child.spawn(io) catch |err| break :term err; var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); break :term child.wait(); @@ -1658,13 +1658,13 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi rsp_child.stdout_behavior = .Inherit; rsp_child.stderr_behavior = .Inherit; - break :term rsp_child.spawnAndWait() catch |err| break :err err; + break :term rsp_child.spawnAndWait(io) catch |err| break :err err; } else { rsp_child.stdin_behavior = .Ignore; rsp_child.stdout_behavior = .Ignore; rsp_child.stderr_behavior = .Pipe; - rsp_child.spawn() catch |err| break :err err; + rsp_child.spawn(io) catch |err| break :err err; var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{}); stderr = try stderr_reader.interface.allocRemaining(comp.gpa, .unlimited); break :term rsp_child.wait() catch |err| break :err err; diff --git a/src/main.zig b/src/main.zig index a832a79dbe..3835e75949 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4457,7 +4457,7 @@ fn runOrTest( const term_result = t: { std.debug.lockStdErr(); defer std.debug.unlockStdErr(); - break :t child.spawnAndWait(); + break :t child.spawnAndWait(io); }; const term = term_result catch |err| { try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); @@ -4512,6 +4512,7 @@ fn runOrTestHotSwap( all_args: []const []const u8, runtime_args_start: ?usize, ) !std.process.Child.Id { + const io = comp.io; const lf = comp.bin_file.?; const exe_path = switch (builtin.target.os.tag) { @@ -4593,7 +4594,7 @@ fn runOrTestHotSwap( child.stdout_behavior = .Inherit; child.stderr_behavior = .Inherit; - try child.spawn(); + try child.spawn(io); return child.id; }, @@ -5419,8 +5420,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) const term = t: { std.debug.lockStdErr(); defer std.debug.unlockStdErr(); - break :t child.spawnAndWait() catch |err| { - fatal("failed to spawn build runner {s}: {s}", .{ child_argv.items[0], @errorName(err) }); + break :t child.spawnAndWait(io) catch |err| { + fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); }; }; @@ -5444,7 +5445,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) dirs.local_cache, tmp_sub_path, @errorName(err), }); }; - dirs.local_cache.handle.deleteFile(tmp_sub_path) catch {}; + dirs.local_cache.handle.deleteFile(io, tmp_sub_path) catch {}; var it = mem.splitScalar(u8, stdout, '\n'); var any_errors = false; @@ -5685,7 +5686,7 @@ fn jitCmd( child.stdout_behavior = if (options.capture == null) .Inherit else .Pipe; child.stderr_behavior = .Inherit; - try child.spawn(); + try child.spawn(io); if (options.capture) |ptr| { var stdout_reader = child.stdout.?.readerStreaming(io, &.{}); diff --git a/test/src/Cases.zig b/test/src/Cases.zig index bf3eade8f4..82b59f722d 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -461,6 +461,7 @@ pub fn lowerToBuildSteps( parent_step: *std.Build.Step, options: CaseTestOptions, ) void { + const io = self.io; const host = b.resolveTargetQuery(.{}); const cases_dir_path = b.build_root.join(b.allocator, &.{ "test", "cases" }) catch @panic("OOM"); @@ -595,7 +596,7 @@ pub fn lowerToBuildSteps( }, .Execution => |expected_stdout| no_exec: { const run = if (case.target.result.ofmt == .c) run_step: { - if (getExternalExecutor(&host.result, &case.target.result, .{ .link_libc = true }) != .native) { + if (getExternalExecutor(io, &host.result, &case.target.result, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. break :no_exec; } diff --git a/test/standalone/child_process/main.zig b/test/standalone/child_process/main.zig index 2a28845a56..3aaec0f2b2 100644 --- a/test/standalone/child_process/main.zig +++ b/test/standalone/child_process/main.zig @@ -29,7 +29,7 @@ pub fn main() !void { child.stdin_behavior = .Pipe; child.stdout_behavior = .Pipe; child.stderr_behavior = .Inherit; - try child.spawn(); + try child.spawn(io); const child_stdin = child.stdin.?; try child_stdin.writeAll("hello from stdin"); // verified in child child_stdin.close(io); -- cgit v1.2.3 From 16f8af1b9a7a287ac6fdefec5949725c55cbe179 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Dec 2025 23:18:42 -0800 Subject: compiler: update various code to new fs API --- lib/compiler/aro/main.zig | 2 +- lib/std/Build/Cache.zig | 8 +- lib/std/Build/Cache/Path.zig | 4 +- lib/std/Io/Dir.zig | 2 +- lib/std/crypto/Certificate/Bundle.zig | 3 +- lib/std/crypto/Certificate/Bundle/macos.zig | 2 +- lib/std/fs/test.zig | 14 +-- lib/std/posix/test.zig | 2 +- lib/std/zip.zig | 4 +- src/Compilation.zig | 30 +++--- src/Package/Fetch.zig | 14 +-- src/Package/Fetch/git.zig | 4 +- src/Zcu.zig | 2 +- src/crash_report.zig | 10 +- src/fmt.zig | 12 +-- src/introspect.zig | 54 +++++----- src/libs/freebsd.zig | 4 +- src/libs/glibc.zig | 4 +- src/libs/mingw.zig | 4 +- src/libs/netbsd.zig | 4 +- src/link.zig | 15 ++- src/link/Coff.zig | 4 +- src/link/Dwarf.zig | 1 - src/link/Elf.zig | 2 +- src/link/Elf2.zig | 4 +- src/link/MachO.zig | 35 +++++-- src/link/MappedFile.zig | 7 +- src/link/Wasm.zig | 6 +- src/main.zig | 155 +++++++++++++--------------- src/print_env.zig | 17 +-- src/print_targets.zig | 16 +-- test/standalone/self_exe_symlink/main.zig | 2 +- 32 files changed, 228 insertions(+), 219 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/main.zig b/lib/compiler/aro/main.zig index d1be1dbb21..9e0440febf 100644 --- a/lib/compiler/aro/main.zig +++ b/lib/compiler/aro/main.zig @@ -43,7 +43,7 @@ pub fn main() u8 { return 1; }; - const aro_name = std.fs.selfExePathAlloc(gpa) catch { + const aro_name = process.executablePathAlloc(io, gpa) catch { std.debug.print("unable to find Aro executable path\n", .{}); if (fast_exit) process.exit(1); return 1; diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index b97efc7677..e2c848b6fd 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1330,7 +1330,7 @@ test "cache file and then recall it" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1396,7 +1396,7 @@ test "check that changing a file makes cache fail" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1456,7 +1456,7 @@ test "no file inputs" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1515,7 +1515,7 @@ test "Manifest with files added after initial hash work" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 54104afa41..51f9e7aecd 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -84,14 +84,14 @@ pub fn openDir( return p.root_dir.handle.openDir(io, joined_path, args); } -pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir { +pub fn makeOpenPath(p: Path, io: Io, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.makeOpenPath(joined_path, opts); + return p.root_dir.handle.makeOpenPath(io, joined_path, opts); } pub fn statFile(p: Path, io: Io, sub_path: []const u8) !Io.Dir.Stat { diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index be82b8b8b2..cd30181900 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1588,7 +1588,7 @@ pub const CopyFileOptions = struct { pub const CopyFileError = File.OpenError || File.StatError || File.Atomic.InitError || File.Atomic.FinishError || - File.Reader.Error || File.WriteError || error{InvalidFileName}; + File.Reader.Error || File.Writer.Error || error{InvalidFileName}; /// Atomically creates a new file at `dest_path` within `dest_dir` with the /// same contents as `source_path` within `source_dir`, overwriting any already diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 1b87c97949..386e1b6b5a 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -242,8 +242,7 @@ pub fn addCertsFromFilePath( } pub const AddCertsFromFileError = Allocator.Error || - Io.File.GetSeekPosError || - Io.File.ReadError || + Io.File.Reader.Error || ParseCertError || std.base64.Error || error{ CertificateAuthorityBundleTooBig, MissingEndCertificateMarker, Streaming }; diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index 086c8feb3f..ea8a91702d 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -6,7 +6,7 @@ const mem = std.mem; const Allocator = std.mem.Allocator; const Bundle = @import("../Bundle.zig"); -pub const RescanMacError = Allocator.Error || Io.File.OpenError || Io.File.ReadError || Io.File.SeekError || Bundle.ParseCertError || error{EndOfStream}; +pub const RescanMacError = Allocator.Error || Io.File.OpenError || Io.File.Reader.Error || Io.File.SeekError || Bundle.ParseCertError || error{EndOfStream}; pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanMacError!void { cb.bytes.clearRetainingCapacity(); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 5205e8eacf..1a8e5adfbd 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -213,7 +213,7 @@ test "Dir.readLink" { // test 3: relative path symlink const parent_file = ".." ++ fs.path.sep_str ++ "target.txt"; const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); - var subdir = try ctx.dir.makeOpenPath("subdir", .{}); + var subdir = try ctx.dir.makeOpenPath(io, "subdir", .{}); defer subdir.close(io); try setupSymlink(io, subdir, canonical_parent_file, "relative-link.txt", .{}); try testReadLink(io, subdir, canonical_parent_file, "relative-link.txt"); @@ -411,7 +411,7 @@ test "openDir non-cwd parent '..'" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var subdir = try tmp.dir.makeOpenPath("subdir", .{}); + var subdir = try tmp.dir.makeOpenPath(io, "subdir", .{}); defer subdir.close(io); var dir = try subdir.openDir(io, "..", .{}); @@ -613,7 +613,7 @@ test "Dir.Iterator but dir is deleted during iteration" { defer tmp.cleanup(); // Create directory and setup an iterator for it - var subdir = try tmp.dir.makeOpenPath("subdir", .{ .iterate = true }); + var subdir = try tmp.dir.makeOpenPath(io, "subdir", .{ .iterate = true }); defer subdir.close(io); var iterator = subdir.iterate(); @@ -862,7 +862,7 @@ test "makeOpenPath parent dirs do not exist" { var tmp_dir = tmpDir(.{}); defer tmp_dir.cleanup(); - var dir = try tmp_dir.dir.makeOpenPath("root_dir/parent_dir/some_dir", .{}); + var dir = try tmp_dir.dir.makeOpenPath(io, "root_dir/parent_dir/some_dir", .{}); dir.close(io); // double check that the full directory structure was created @@ -1010,7 +1010,7 @@ test "Dir.rename directory onto non-empty dir" { try ctx.dir.makeDir(io, test_dir_path, .default_dir); - var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); + var target_dir = try ctx.dir.makeOpenPath(io, target_dir_path, .{}); var file = try target_dir.createFile(io, "test_file", .{ .read = true }); file.close(io); target_dir.close(io); @@ -1147,7 +1147,7 @@ test "deleteTree does not follow symlinks" { try tmp.dir.makePath(io, "b"); { - var a = try tmp.dir.makeOpenPath("a", .{}); + var a = try tmp.dir.makeOpenPath(io, "a", .{}); defer a.close(io); try setupSymlink(io, a, "../b", "b", .{ .is_directory = true }); @@ -1346,7 +1346,7 @@ test "makepath ignores '.'" { fn testFilenameLimits(io: Io, iterable_dir: Dir, maxed_filename: []const u8) !void { // setup, create a dir and a nested file both with maxed filenames, and walk the dir { - var maxed_dir = try iterable_dir.makeOpenPath(maxed_filename, .{}); + var maxed_dir = try iterable_dir.makeOpenPath(io, maxed_filename, .{}); defer maxed_dir.close(io); try maxed_dir.writeFile(io, .{ .sub_path = maxed_filename, .data = "" }); diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 87361a5038..64511ff4a2 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -142,7 +142,7 @@ test "linkat with different directories" { const target_name = "link-target"; const link_name = "newlink"; - const subdir = try tmp.dir.makeOpenPath("subdir", .{}); + const subdir = try tmp.dir.makeOpenPath(io, "subdir", .{}); defer tmp.dir.deleteFile(io, target_name) catch {}; try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 5a91b73d6a..770bfd8ae7 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -117,7 +117,7 @@ pub const EndRecord = extern struct { return record; } - pub const FindFileError = File.Reader.SizeError || File.SeekError || File.ReadError || error{ + pub const FindFileError = File.Reader.SizeError || File.SeekError || File.Reader.Error || error{ ZipNoEndRecord, EndOfStream, ReadFailed, @@ -560,7 +560,7 @@ pub const Iterator = struct { const out_file = blk: { if (std.fs.path.dirname(filename)) |dirname| { - var parent_dir = try dest.makeOpenPath(dirname, .{}); + var parent_dir = try dest.makeOpenPath(io, dirname, .{}); defer parent_dir.close(io); const basename = std.fs.path.basename(filename); diff --git a/src/Compilation.zig b/src/Compilation.zig index c63fa9a3c1..9e76b8feca 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -832,7 +832,7 @@ pub const Directories = struct { const nonempty_path = if (path.len == 0) "." else path; const handle_or_err = switch (thing) { .@"zig lib" => Io.Dir.cwd().openDir(io, nonempty_path, .{}), - .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}), + .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(io, nonempty_path, .{}), }; return .{ .path = if (path.len == 0) null else path, @@ -2111,7 +2111,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, cache.* = .{ .gpa = gpa, .io = io, - .manifest_dir = options.dirs.local_cache.handle.makeOpenPath("h", .{}) catch |err| { + .manifest_dir = options.dirs.local_cache.handle.makeOpenPath(io, "h", .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = "h", .err = err } }); }, }; @@ -2161,7 +2161,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, // to redundantly happen for each AstGen operation. const zir_sub_dir = "z"; - var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { + var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(io, zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } }); }; errdefer local_zir_dir.close(io); @@ -2169,7 +2169,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, .handle = local_zir_dir, .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), }; - var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { + var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(io, zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } }); }; errdefer global_zir_dir.close(io); @@ -2440,7 +2440,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, const digest = hash.final(); const artifact_sub_dir = "o" ++ fs.path.sep_str ++ digest; - var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}) catch |err| { + var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(io, artifact_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } }); }; errdefer artifact_dir.close(io); @@ -2895,7 +2895,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE tmp_dir_rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path}); - const handle = comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}) catch |err| { + const handle = comp.dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}) catch |err| { return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err }); }; break :d .{ .path = path, .handle = handle }; @@ -2976,7 +2976,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE tmp_dir_rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path}); - const handle = comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}) catch |err| { + const handle = comp.dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}) catch |err| { return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err }); }; break :d .{ .path = path, .handle = handle }; @@ -5267,7 +5267,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { const io = comp.io; const docs_path = comp.resolveEmitPath(comp.emit_docs.?); - var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| { + var out_dir = docs_path.root_dir.handle.makeOpenPath(io, docs_path.sub_path, .{}) catch |err| { return comp.lockAndSetMiscFailure( .docs_copy, "unable to create output directory '{f}': {s}", @@ -5509,7 +5509,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU assert(docs_bin_file.sub_path.len > 0); // emitted binary is not a directory const docs_path = comp.resolveEmitPath(comp.emit_docs.?); - var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| { + var out_dir = docs_path.root_dir.handle.makeOpenPath(io, docs_path.sub_path, .{}) catch |err| { comp.lockAndSetMiscFailure( .docs_copy, "unable to create output directory '{f}': {t}", @@ -5699,7 +5699,7 @@ pub fn translateC( const tmp_basename = std.fmt.hex(std.crypto.random.int(u64)); const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename; const cache_dir = comp.dirs.local_cache.handle; - var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{}); + var cache_tmp_dir = try cache_dir.makeOpenPath(io, tmp_sub_path, .{}); defer cache_tmp_dir.close(io); const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename }); @@ -6274,7 +6274,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr // We can't know the digest until we do the C compiler invocation, // so we need a temporary filename. const out_obj_path = try comp.tmpFilePath(arena, o_basename); - var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); + var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, "tmp", .{}); defer zig_cache_tmp_dir.close(io); const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) @@ -6439,7 +6439,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr // Rename into place. const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_obj_path); try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io); @@ -6528,7 +6528,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const digest = man.final(); const o_sub_path = try fs.path.join(arena, &.{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); defer o_dir.close(io); const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ @@ -6616,7 +6616,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const rc_basename_noext = src_basename[0 .. src_basename.len - fs.path.extension(src_basename).len]; const digest = if (try man.hit()) man.final() else blk: { - var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); + var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, "tmp", .{}); defer zig_cache_tmp_dir.close(io); const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); @@ -6687,7 +6687,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 // Rename into place. const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_res_path); try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename, io); diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index d25ee55c32..33214a47db 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -500,12 +500,12 @@ fn runResource( var tmp_directory: Cache.Directory = .{ .path = tmp_directory_path, .handle = handle: { - const dir = cache_root.handle.makeOpenPath(tmp_dir_sub_path, .{ + const dir = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ .iterate = true, }) catch |err| { try eb.addRootErrorMessage(.{ - .msg = try eb.printString("unable to create temporary directory '{s}': {s}", .{ - tmp_directory_path, @errorName(err), + .msg = try eb.printString("unable to create temporary directory '{s}': {t}", .{ + tmp_directory_path, err, }), }); return error.FetchFailed; @@ -524,7 +524,7 @@ fn runResource( if (native_os == .linux and f.job_queue.work_around_btrfs_bug) { // https://github.com/ziglang/zig/issues/17095 pkg_path.root_dir.handle.close(io); - pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(tmp_dir_sub_path, .{ + pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ .iterate = true, }) catch @panic("btrfs workaround failed"); } @@ -1366,7 +1366,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U // we do not attempt to replicate the exact structure of a real .git // directory, since that isn't relevant for fetching a package. { - var pack_dir = try out_dir.makeOpenPath(".git", .{}); + var pack_dir = try out_dir.makeOpenPath(io, ".git", .{}); defer pack_dir.close(io); var pack_file = try pack_dir.createFile(io, "pkg.pack", .{ .read = true }); defer pack_file.close(io); @@ -1743,7 +1743,7 @@ const HashedFile = struct { const Error = Io.File.OpenError || - Io.File.ReadError || + Io.File.Reader.Error || Io.File.StatError || Io.File.ChmodError || Io.Dir.ReadLinkError; @@ -2258,7 +2258,7 @@ const TestFetchBuilder = struct { cache_parent_dir: std.Io.Dir, path_or_url: []const u8, ) !*Fetch { - const cache_dir = try cache_parent_dir.makeOpenPath("zig-global-cache", .{}); + const cache_dir = try cache_parent_dir.makeOpenPath(io, "zig-global-cache", .{}); self.http_client = .{ .allocator = allocator, .io = io }; self.global_cache_directory = .{ .handle = cache_dir, .path = null }; diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 255f0e6f69..f53c96cc3d 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -1720,10 +1720,10 @@ pub fn main() !void { var pack_file_reader = pack_file.reader(io, &pack_file_buffer); const commit = try Oid.parse(format, args[3]); - var worktree = try Io.Dir.cwd().makeOpenPath(args[4], .{}); + var worktree = try Io.Dir.cwd().makeOpenPath(io, args[4], .{}); defer worktree.close(io); - var git_dir = try worktree.makeOpenPath(".git", .{}); + var git_dir = try worktree.makeOpenPath(io, ".git", .{}); defer git_dir.close(io); std.debug.print("Starting index...\n", .{}); diff --git a/src/Zcu.zig b/src/Zcu.zig index 2891da2407..e0e254d807 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -1200,7 +1200,7 @@ pub const EmbedFile = struct { /// `.none` means the file was not loaded, so `stat` is undefined. val: InternPool.Index, /// If this is `null` and `val` is `.none`, the file has never been loaded. - err: ?(Io.File.OpenError || Io.File.StatError || Io.File.ReadError || error{UnexpectedEof}), + err: ?(Io.File.OpenError || Io.File.StatError || Io.File.Reader.Error || error{UnexpectedEof}), stat: Cache.File.Stat, pub const Index = enum(u32) { diff --git a/src/crash_report.zig b/src/crash_report.zig index d525d4b3b5..76503fdc53 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -95,19 +95,19 @@ fn dumpCrashContext() Io.Writer.Error!void { // TODO: this does mean that a different thread could grab the stderr mutex between the context // and the actual panic printing, which would be quite confusing. - const stderr, _ = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); - try stderr.writeAll("Compiler crash context:\n"); + try stderr.interface.writeAll("Compiler crash context:\n"); if (CodegenFunc.current) |*cg| { const func_nav = cg.zcu.funcInfo(cg.func_index).owner_nav; const func_fqn = cg.zcu.intern_pool.getNav(func_nav).fqn; - try stderr.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); + try stderr.interface.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); } else if (AnalyzeBody.current) |anal| { - try dumpCrashContextSema(anal, stderr, &S.crash_heap); + try dumpCrashContextSema(anal, &stderr.interface, &S.crash_heap); } else { - try stderr.writeAll("(no context)\n\n"); + try stderr.interface.writeAll("(no context)\n\n"); } } fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8) Io.Writer.Error!void { diff --git a/src/fmt.zig b/src/fmt.zig index 59b4470f81..bec3496e68 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -59,7 +59,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(usage_fmt); + try Io.File.stdout().writeStreamingAll(io, usage_fmt); return process.cleanExit(); } else if (mem.eql(u8, arg, "--color")) { if (i + 1 >= args.len) { @@ -154,7 +154,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! process.exit(code); } - return Io.File.stdout().writeAll(formatted); + return Io.File.stdout().writeStreamingAll(io, formatted); } if (input_files.items.len == 0) { @@ -162,7 +162,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! } var stdout_buffer: [4096]u8 = undefined; - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); var fmt: Fmt = .{ .gpa = gpa, @@ -231,7 +231,7 @@ fn fmtPathDir( if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; var dir_it = dir.iterate(); - while (try dir_it.next()) |entry| { + while (try dir_it.next(io)) |entry| { const is_dir = entry.kind == .directory; if (mem.startsWith(u8, entry.name, ".")) continue; @@ -244,7 +244,7 @@ fn fmtPathDir( try fmtPathDir(fmt, full_path, check_mode, dir, entry.name); } else { fmtPathFile(fmt, full_path, check_mode, dir, entry.name) catch |err| { - std.log.err("unable to format '{s}': {s}", .{ full_path, @errorName(err) }); + std.log.err("unable to format '{s}': {t}", .{ full_path, err }); fmt.any_error = true; return; }; @@ -355,7 +355,7 @@ fn fmtPathFile( try fmt.stdout_writer.interface.print("{s}\n", .{file_path}); fmt.any_error = true; } else { - var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode, .write_buffer = &.{} }); + var af = try dir.atomicFile(io, sub_path, .{ .permissions = stat.permissions, .write_buffer = &.{} }); defer af.deinit(); try af.file_writer.interface.writeAll(fmt.out_buffer.written()); diff --git a/src/introspect.zig b/src/introspect.zig index 3f8308961f..0a57505aeb 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -3,10 +3,9 @@ const build_options = @import("build_options"); const std = @import("std"); const Io = std.Io; +const Dir = std.Io.Dir; const mem = std.mem; const Allocator = std.mem.Allocator; -const os = std.os; -const fs = std.fs; const Cache = std.Build.Cache; const Compilation = @import("Compilation.zig"); @@ -16,11 +15,11 @@ const Package = @import("Package.zig"); /// The path of the returned Directory is relative to `base`. /// The handle of the returned Directory is open. fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { - const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; + const test_index_file = "std" ++ Dir.path.sep_str ++ "std.zig"; zig_dir: { // Try lib/zig/std/std.zig - const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; + const lib_zig = "lib" ++ Dir.path.sep_str ++ "zig"; var test_zig_dir = base_dir.openDir(io, lib_zig, .{}) catch break :zig_dir; const file = test_zig_dir.openFile(io, test_index_file, .{}) catch { test_zig_dir.close(io); @@ -44,13 +43,13 @@ fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { pub fn findZigLibDir(gpa: Allocator, io: Io) !Cache.Directory { const cwd_path = try getResolvedCwd(gpa); defer gpa.free(cwd_path); - const self_exe_path = try fs.selfExePathAlloc(gpa); + const self_exe_path = try std.process.executablePathAlloc(io, gpa); defer gpa.free(self_exe_path); return findZigLibDirFromSelfExe(gpa, io, cwd_path, self_exe_path); } -/// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This +/// Like `std.process.getCwdAlloc`, but also resolves the path with `Dir.path.resolve`. This /// means the path has no repeated separators, no "." or ".." components, and no trailing separator. /// On WASI, "" is returned instead of ".". pub fn getResolvedCwd(gpa: Allocator) error{ @@ -68,8 +67,8 @@ pub fn getResolvedCwd(gpa: Allocator) error{ } const cwd = try std.process.getCwdAlloc(gpa); defer gpa.free(cwd); - const resolved = try fs.path.resolve(gpa, &.{cwd}); - std.debug.assert(fs.path.isAbsolute(resolved)); + const resolved = try Dir.path.resolve(gpa, &.{cwd}); + std.debug.assert(Dir.path.isAbsolute(resolved)); return resolved; } @@ -84,12 +83,12 @@ pub fn findZigLibDirFromSelfExe( ) error{ OutOfMemory, FileNotFound }!Cache.Directory { const cwd = Io.Dir.cwd(); var cur_path: []const u8 = self_exe_path; - while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { + while (Dir.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { var base_dir = cwd.openDir(io, dirname, .{}) catch continue; defer base_dir.close(io); const sub_directory = testZigInstallPrefix(io, base_dir) orelse continue; - const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? }); + const p = try Dir.path.join(allocator, &.{ dirname, sub_directory.path.? }); defer allocator.free(p); const resolved = try resolvePath(allocator, cwd_path, &.{p}); @@ -113,18 +112,18 @@ pub fn resolveGlobalCacheDir(allocator: Allocator) ![]u8 { if (builtin.os.tag != .windows) { if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| { if (cache_root.len > 0) { - return fs.path.join(allocator, &.{ cache_root, appname }); + return Dir.path.join(allocator, &.{ cache_root, appname }); } } if (std.zig.EnvVar.HOME.getPosix()) |home| { - return fs.path.join(allocator, &.{ home, ".cache", appname }); + return Dir.path.join(allocator, &.{ home, ".cache", appname }); } } - return fs.getAppDataDir(allocator, appname); + return std.fs.getAppDataDir(allocator, appname); } -/// Similar to `fs.path.resolve`, but converts to a cwd-relative path, or, if that would +/// Similar to `Dir.path.resolve`, but converts to a cwd-relative path, or, if that would /// start with a relative up-dir (".."), an absolute path based on the cwd. Also, the cwd /// returns the empty string ("") instead of ".". pub fn resolvePath( @@ -136,7 +135,7 @@ pub fn resolvePath( ) Allocator.Error![]u8 { if (builtin.target.os.tag == .wasi) { std.debug.assert(mem.eql(u8, cwd_resolved, "")); - const res = try fs.path.resolve(gpa, paths); + const res = try Dir.path.resolve(gpa, paths); if (mem.eql(u8, res, ".")) { gpa.free(res); return ""; @@ -146,16 +145,16 @@ pub fn resolvePath( // Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`. for (paths) |p| { - if (fs.path.isAbsolute(p)) break; // absolute path + if (Dir.path.isAbsolute(p)) break; // absolute path if (mem.indexOf(u8, p, "..") != null) break; // may contain up-dir } else { // no absolute path, no "..". - const res = try fs.path.resolve(gpa, paths); + const res = try Dir.path.resolve(gpa, paths); if (mem.eql(u8, res, ".")) { gpa.free(res); return ""; } - std.debug.assert(!fs.path.isAbsolute(res)); + std.debug.assert(!Dir.path.isAbsolute(res)); std.debug.assert(!isUpDir(res)); return res; } @@ -164,19 +163,19 @@ pub fn resolvePath( // Optimization: `paths` often has just one element. const path_resolved = switch (paths.len) { 0 => unreachable, - 1 => try fs.path.resolve(gpa, &.{ cwd_resolved, paths[0] }), + 1 => try Dir.path.resolve(gpa, &.{ cwd_resolved, paths[0] }), else => r: { const all_paths = try gpa.alloc([]const u8, paths.len + 1); defer gpa.free(all_paths); all_paths[0] = cwd_resolved; @memcpy(all_paths[1..], paths); - break :r try fs.path.resolve(gpa, all_paths); + break :r try Dir.path.resolve(gpa, all_paths); }, }; errdefer gpa.free(path_resolved); - std.debug.assert(fs.path.isAbsolute(path_resolved)); - std.debug.assert(fs.path.isAbsolute(cwd_resolved)); + std.debug.assert(Dir.path.isAbsolute(path_resolved)); + std.debug.assert(Dir.path.isAbsolute(cwd_resolved)); if (!std.mem.startsWith(u8, path_resolved, cwd_resolved)) return path_resolved; // not in cwd if (path_resolved.len == cwd_resolved.len) { @@ -184,7 +183,7 @@ pub fn resolvePath( gpa.free(path_resolved); return ""; } - if (path_resolved[cwd_resolved.len] != std.fs.path.sep) return path_resolved; // not in cwd (last component differs) + if (path_resolved[cwd_resolved.len] != Dir.path.sep) return path_resolved; // not in cwd (last component differs) // in cwd; extract sub path const sub_path = try gpa.dupe(u8, path_resolved[cwd_resolved.len + 1 ..]); @@ -192,9 +191,8 @@ pub fn resolvePath( return sub_path; } -/// TODO move this to std.fs.path pub fn isUpDir(p: []const u8) bool { - return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep); + return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == Dir.path.sep); } pub const default_local_zig_cache_basename = ".zig-cache"; @@ -205,12 +203,12 @@ pub const default_local_zig_cache_basename = ".zig-cache"; pub fn resolveSuitableLocalCacheDir(arena: Allocator, io: Io, cwd: []const u8) Allocator.Error!?[]u8 { var cur_dir = cwd; while (true) { - const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); + const joined = try Dir.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); if (Io.Dir.cwd().access(io, joined, .{})) |_| { - return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); + return try Dir.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); } else |err| switch (err) { error.FileNotFound => { - cur_dir = fs.path.dirname(cur_dir) orelse return null; + cur_dir = Dir.path.dirname(cur_dir) orelse return null; continue; }, else => return null, diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index 77bd4372d0..ee638718b7 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -444,7 +444,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -477,7 +477,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index a60dc921be..de86413cfd 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -679,7 +679,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -712,7 +712,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 9631ec22f9..05a9de71e7 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -258,7 +258,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -297,7 +297,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const digest = man.final(); const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}); + var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}); defer o_dir.close(io); const aro = @import("aro"); diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index fd80616e9d..33dd62d851 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -385,7 +385,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -418,7 +418,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/link.zig b/src/link.zig index 7ebe1c6ba2..9914b1af3a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -2170,28 +2170,27 @@ fn resolvePathInputLib( }) { var file = test_path.root_dir.handle.openFile(io, test_path.sub_path, .{}) catch |err| switch (err) { error.FileNotFound => return .no_match, - else => |e| fatal("unable to search for {s} library '{f}': {s}", .{ - @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e), + else => |e| fatal("unable to search for {t} library '{f}': {t}", .{ + link_mode, std.fmt.alt(test_path, .formatEscapeChar), e, }), }; errdefer file.close(io); try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); - const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f}': {s}", .{ - std.fmt.alt(test_path, .formatEscapeChar), @errorName(err), - }); + const n = file.readPositionalAll(io, ld_script_bytes.items, 0) catch |err| + fatal("failed to read '{f}': {t}", .{ std.fmt.alt(test_path, .formatEscapeChar), err }); const buf = ld_script_bytes.items[0..n]; if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) { // Appears to be an ELF or archive file. return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); } const stat = file.stat(io) catch |err| - fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) }); + fatal("failed to stat {f}: {t}", .{ test_path, err }); const size = std.math.cast(u32, stat.size) orelse fatal("{f}: linker script too big", .{test_path}); try ld_script_bytes.resize(gpa, size); const buf2 = ld_script_bytes.items[n..]; - const n2 = file.preadAll(buf2, n) catch |err| - fatal("failed to read {f}: {s}", .{ test_path, @errorName(err) }); + const n2 = file.readPositionalAll(io, buf2, n) catch |err| + fatal("failed to read {f}: {t}", .{ test_path, err }); if (n2 != buf2.len) fatal("failed to read {f}: unexpected end of file", .{test_path}); // This `Io` is only used for a mutex, and we know we aren't doing anything async/concurrent. diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 009e59ed0d..2585d43eba 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -636,7 +636,7 @@ fn create( const coff = try arena.create(Coff); const file = try path.root_dir.handle.createFile(io, path.sub_path, .{ .read = true, - .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), + .permissions = link.File.determinePermissions(comp.config.output_mode, comp.config.link_mode), }); errdefer file.close(io); coff.* = .{ @@ -653,7 +653,7 @@ fn create( .allow_shlib_undefined = false, .stack_size = 0, }, - .mf = try .init(file, comp.gpa), + .mf = try .init(file, comp.gpa, io), .nodes = .empty, .import_table = .{ .ni = .none, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index c675af3e22..8b05272033 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -52,7 +52,6 @@ pub const UpdateError = error{ codegen.GenerateSymbolError || Io.File.OpenError || Io.File.LengthError || - Io.File.CopyRangeError || Io.File.ReadPositionalError || Io.File.WritePositionalError; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 13a624a295..2916f5ee25 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -320,7 +320,7 @@ pub fn createEmpty( self.base.file = try emit.root_dir.handle.createFile(io, sub_path, .{ .truncate = true, .read = true, - .mode = link.File.determineMode(output_mode, link_mode), + .permissions = link.File.determinePermissions(output_mode, link_mode), }); const gpa = comp.gpa; diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 72fdb244a4..fc4794a7b0 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -976,7 +976,7 @@ fn create( const elf = try arena.create(Elf); const file = try path.root_dir.handle.createFile(io, path.sub_path, .{ .read = true, - .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), + .permissions = link.File.determinePermissions(comp.config.output_mode, comp.config.link_mode), }); errdefer file.close(io); elf.* = .{ @@ -994,7 +994,7 @@ fn create( .stack_size = 0, }, .options = options, - .mf = try .init(file, comp.gpa), + .mf = try .init(file, comp.gpa, io), .ni = .{ .tls = .none, }, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index f996442f24..6c380637ee 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -224,7 +224,7 @@ pub fn createEmpty( self.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, - .mode = link.File.determineMode(output_mode, link_mode), + .permissions = link.File.determinePermissions(output_mode, link_mode), }); // Append null file @@ -3157,7 +3157,9 @@ fn detectAllocCollision(self: *MachO, start: u64, size: u64) !?u64 { } } - if (at_end) try self.base.file.?.setEndPos(end); + const comp = self.base.comp; + const io = comp.io; + if (at_end) try self.base.file.?.setLength(io, end); return null; } @@ -3292,7 +3294,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { ); defer gpa.free(d_sym_path); - var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{}); + var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(io, d_sym_path, .{}); defer d_sym_bundle.close(io); self.d_sym.?.file = try d_sym_bundle.createFile(io, fs.path.basename(self.base.emit.sub_path), .{ @@ -3303,6 +3305,10 @@ pub fn reopenDebugInfo(self: *MachO) !void { // TODO: move to ZigObject fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { + const comp = self.base.comp; + const gpa = comp.gpa; + const io = comp.io; + if (!self.base.isRelocatable()) { const base_vmaddr = blk: { const pagezero_size = self.pagezero_size orelse default_pagezero_size; @@ -3357,7 +3363,11 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { if (options.zo.dwarf) |*dwarf| { // Create dSYM bundle. log.debug("creating {s}.dSYM bundle", .{options.emit.sub_path}); - self.d_sym = .{ .allocator = self.base.comp.gpa, .file = null }; + self.d_sym = .{ + .io = io, + .allocator = gpa, + .file = null, + }; try self.reopenDebugInfo(); try self.d_sym.?.initMetadata(self); try dwarf.initMetadata(); @@ -3477,6 +3487,9 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !vo const seg_id = self.sections.items(.segment_id)[sect_index]; const seg = &self.segments.items[seg_id]; + const comp = self.base.comp; + const io = comp.io; + if (!sect.isZerofill()) { const allocated_size = self.allocatedSize(sect.offset); if (needed_size > allocated_size) { @@ -3498,7 +3511,7 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !vo sect.offset = @intCast(new_offset); } else if (sect.offset + allocated_size == std.math.maxInt(u64)) { - try self.base.file.?.setEndPos(sect.offset + needed_size); + try self.base.file.?.setLength(io, sect.offset + needed_size); } seg.filesize = needed_size; } @@ -3520,6 +3533,8 @@ fn growSectionNonRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !vo } fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void { + const comp = self.base.comp; + const io = comp.io; const sect = &self.sections.items(.header)[sect_index]; if (!sect.isZerofill()) { @@ -3547,7 +3562,7 @@ fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void sect.offset = @intCast(new_offset); sect.addr = new_addr; } else if (sect.offset + allocated_size == std.math.maxInt(u64)) { - try self.base.file.?.setEndPos(sect.offset + needed_size); + try self.base.file.?.setLength(io, sect.offset + needed_size); } } sect.size = needed_size; @@ -5346,12 +5361,12 @@ pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkF }; } -pub fn setEndPos(macho_file: *MachO, length: u64) error{LinkFailure}!void { +pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void { const comp = macho_file.base.comp; + const io = comp.io; const diags = &comp.link_diags; - macho_file.base.file.?.setEndPos(length) catch |err| { - return diags.fail("failed to set file end pos: {s}", .{@errorName(err)}); - }; + macho_file.base.file.?.setLength(io, length) catch |err| + return diags.fail("failed to set file end pos: {t}", .{err}); } pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure}!T { diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 4e58aae01a..974b03ef7f 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -10,6 +10,7 @@ const assert = std.debug.assert; const linux = std.os.linux; const windows = std.os.windows; +io: Io, file: std.Io.File, flags: packed struct { block_size: std.mem.Alignment, @@ -36,8 +37,9 @@ pub const Error = std.posix.MMapError || std.posix.MRemapError || Io.File.Length NoSpaceLeft, }; -pub fn init(file: std.Io.File, gpa: std.mem.Allocator) !MappedFile { +pub fn init(file: std.Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { var mf: MappedFile = .{ + .io = io, .file = file, .flags = undefined, .section = if (is_windows) windows.INVALID_HANDLE_VALUE else {}, @@ -624,13 +626,14 @@ pub fn addNodeAfter( } fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void { + const io = mf.io; const node = ni.get(mf); const old_offset, const old_size = node.location().resolve(mf); const new_size = node.flags.alignment.forward(@intCast(requested_size)); // Resize the entire file if (ni == Node.Index.root) { try mf.ensureCapacityForSetLocation(gpa); - try mf.file.setEndPos(new_size); + try mf.file.setLength(io, new_size); try mf.ensureTotalCapacity(@intCast(new_size)); ni.setLocationAssumeCapacity(mf, old_offset, new_size); return; diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 80a248eb6f..489fb8e6fe 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3002,11 +3002,11 @@ pub fn createEmpty( wasm.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, - .mode = if (Io.File.Permissions.has_executable_bit) + .permissions = if (Io.File.Permissions.has_executable_bit) if (target.os.tag == .wasi and output_mode == .Exe) - Io.File.default_mode | 0b001_000_000 + .executable_file else - Io.File.default_mode + .default_file else 0, }); diff --git a/src/main.zig b/src/main.zig index 2eebb6d060..47e5af23da 100644 --- a/src/main.zig +++ b/src/main.zig @@ -335,19 +335,20 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { } else if (mem.eql(u8, cmd, "targets")) { dev.check(.targets_command); const host = std.zig.resolveTargetQueryOrFatal(io, .{}); - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); try @import("print_targets.zig").cmdTargets(arena, io, cmd_args, &stdout_writer.interface, &host); return stdout_writer.interface.flush(); } else if (mem.eql(u8, cmd, "version")) { dev.check(.version_command); - try Io.File.stdout().writeAll(build_options.version ++ "\n"); + try Io.File.stdout().writeStreamingAll(io, build_options.version ++ "\n"); return; } else if (mem.eql(u8, cmd, "env")) { dev.check(.env_command); const host = std.zig.resolveTargetQueryOrFatal(io, .{}); - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); try @import("print_env.zig").cmdEnv( arena, + io, &stdout_writer.interface, args, if (native_os == .wasi) wasi_preopens, @@ -361,10 +362,10 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { }); } else if (mem.eql(u8, cmd, "zen")) { dev.check(.zen_command); - return Io.File.stdout().writeAll(info_zen); + return Io.File.stdout().writeStreamingAll(io, info_zen); } else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) { dev.check(.help_command); - return Io.File.stdout().writeAll(usage); + return Io.File.stdout().writeStreamingAll(io, usage); } else if (mem.eql(u8, cmd, "ast-check")) { return cmdAstCheck(arena, io, cmd_args); } else if (mem.eql(u8, cmd, "detect-cpu")) { @@ -374,7 +375,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { return cmdDumpZir(arena, io, cmd_args); } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "llvm-ints")) { - return cmdDumpLlvmInts(gpa, arena, cmd_args); + return cmdDumpLlvmInts(gpa, arena, io, cmd_args); } else { std.log.info("{s}", .{usage}); fatal("unknown command: {s}", .{args[1]}); @@ -701,7 +702,7 @@ const Emit = union(enum) { yes: []const u8, const OutputToCacheReason = enum { listen, @"zig run", @"zig test" }; - fn resolve(io: Io, emit: Emit, default_basename: []const u8, output_to_cache: ?OutputToCacheReason) Compilation.CreateOptions.Emit { + fn resolve(emit: Emit, io: Io, default_basename: []const u8, output_to_cache: ?OutputToCacheReason) Compilation.CreateOptions.Emit { return switch (emit) { .no => .no, .yes_default_path => if (output_to_cache != null) .yes_cache else .{ .yes_path = default_basename }, @@ -1036,7 +1037,7 @@ fn buildOutputType( fatal("unable to read response file '{s}': {t}", .{ resp_file_path, err }); } else if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(usage_build_generic); + try Io.File.stdout().writeStreamingAll(io, usage_build_generic); return cleanExit(); } else if (mem.eql(u8, arg, "--")) { if (arg_mode == .run) { @@ -1858,9 +1859,7 @@ fn buildOutputType( var must_link = false; var file_ext: ?Compilation.FileExt = null; while (it.has_next) { - it.next() catch |err| { - fatal("unable to parse command line parameters: {s}", .{@errorName(err)}); - }; + it.next(io) catch |err| fatal("unable to parse command line parameters: {t}", .{err}); switch (it.zig_equivalent) { .target => target_arch_os_abi = it.only_arg, // example: -target riscv64-linux-unknown .o => { @@ -2836,9 +2835,9 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "-V")) { warn("ignoring request for supported emulations: unimplemented", .{}); } else if (mem.eql(u8, arg, "-v")) { - try Io.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); + try Io.File.stdout().writeStreamingAll(io, "zig ld " ++ build_options.version ++ "\n"); } else if (mem.eql(u8, arg, "--version")) { - try Io.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); + try Io.File.stdout().writeStreamingAll(io, "zig ld " ++ build_options.version ++ "\n"); process.exit(0); } else { fatal("unsupported linker arg: {s}", .{arg}); @@ -3077,14 +3076,13 @@ fn buildOutputType( const self_exe_path = switch (native_os) { .wasi => {}, - else => fs.selfExePathAlloc(arena) catch |err| { - fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); - }, + else => process.executablePathAlloc(io, arena) catch |err| fatal("unable to find zig self exe path: {t}", .{err}), }; // This `init` calls `fatal` on error. var dirs: Compilation.Directories = .init( arena, + io, override_lib_dir, override_global_cache_dir, s: { @@ -3097,11 +3095,9 @@ fn buildOutputType( if (native_os == .wasi) wasi_preopens, self_exe_path, ); - defer dirs.deinit(); + defer dirs.deinit(io); - if (linker_optimization) |o| { - warn("ignoring deprecated linker optimization setting '{s}'", .{o}); - } + if (linker_optimization) |o| warn("ignoring deprecated linker optimization setting '{s}'", .{o}); create_module.dirs = dirs; create_module.opts.emit_llvm_ir = emit_llvm_ir != .no; @@ -3324,18 +3320,18 @@ fn buildOutputType( }; const default_h_basename = try std.fmt.allocPrint(arena, "{s}.h", .{root_name}); - const emit_h_resolved = emit_h.resolve(default_h_basename, output_to_cache); + const emit_h_resolved = emit_h.resolve(io, default_h_basename, output_to_cache); const default_asm_basename = try std.fmt.allocPrint(arena, "{s}.s", .{root_name}); - const emit_asm_resolved = emit_asm.resolve(default_asm_basename, output_to_cache); + const emit_asm_resolved = emit_asm.resolve(io, default_asm_basename, output_to_cache); const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{s}.ll", .{root_name}); - const emit_llvm_ir_resolved = emit_llvm_ir.resolve(default_llvm_ir_basename, output_to_cache); + const emit_llvm_ir_resolved = emit_llvm_ir.resolve(io, default_llvm_ir_basename, output_to_cache); const default_llvm_bc_basename = try std.fmt.allocPrint(arena, "{s}.bc", .{root_name}); - const emit_llvm_bc_resolved = emit_llvm_bc.resolve(default_llvm_bc_basename, output_to_cache); + const emit_llvm_bc_resolved = emit_llvm_bc.resolve(io, default_llvm_bc_basename, output_to_cache); - const emit_docs_resolved = emit_docs.resolve("docs", output_to_cache); + const emit_docs_resolved = emit_docs.resolve(io, "docs", output_to_cache); const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) { .Obj => false, @@ -3356,7 +3352,7 @@ fn buildOutputType( const default_implib_basename = try std.fmt.allocPrint(arena, "{s}.lib", .{root_name}); const emit_implib_resolved: Compilation.CreateOptions.Emit = switch (emit_implib) { .no => .no, - .yes => emit_implib.resolve(default_implib_basename, output_to_cache), + .yes => emit_implib.resolve(io, default_implib_basename, output_to_cache), .yes_default_path => emit: { if (output_to_cache != null) break :emit .yes_cache; const p = try fs.path.join(arena, &.{ @@ -3399,7 +3395,7 @@ fn buildOutputType( // for the hashing algorithm here and in the cache are the same. // We are providing our own cache key, because this file has nothing // to do with the cache manifest. - var file_writer = f.writer(&.{}); + var file_writer = f.writer(io, &.{}); var buffer: [1000]u8 = undefined; var hasher = file_writer.interface.hashed(Cache.Hasher.init("0123456789abcdef"), &buffer); var stdin_reader = Io.File.stdin().readerStreaming(io, &.{}); @@ -3633,13 +3629,13 @@ fn buildOutputType( if (show_builtin) { const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config); const source = try builtin_opts.generate(arena); - return Io.File.stdout().writeAll(source); + return Io.File.stdout().writeStreamingAll(io, source); } switch (listen) { .none => {}, .stdio => { var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); try serve( comp, &stdin_reader.interface, @@ -3930,11 +3926,8 @@ fn createModule( } if (target.isMinGW()) { - const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| { - fatal("failed to check zig installation for DLL import libs: {s}", .{ - @errorName(err), - }); - }; + const exists = mingw.libExists(arena, io, target, create_module.dirs.zig_lib, lib_name) catch |err| + fatal("failed to check zig installation for DLL import libs: {t}", .{err}); if (exists) { try create_module.windows_libs.put(arena, lib_name, {}); continue; @@ -4009,11 +4002,8 @@ fn createModule( } if (create_module.libc_paths_file) |paths_file| { - create_module.libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| { - fatal("unable to parse libc paths file at path {s}: {s}", .{ - paths_file, @errorName(err), - }); - }; + create_module.libc_installation = LibCInstallation.parse(arena, io, paths_file, target) catch |err| + fatal("unable to parse libc paths file at path {s}: {t}", .{ paths_file, err }); } if (target.os.tag == .windows and (target.abi == .msvc or target.abi == .itanium) and @@ -4024,7 +4014,7 @@ fn createModule( .verbose = true, .target = target, }) catch |err| { - fatal("unable to find native libc installation: {s}", .{@errorName(err)}); + fatal("unable to find native libc installation: {t}", .{err}); }; } try create_module.lib_directories.ensureUnusedCapacity(arena, 2); @@ -4163,7 +4153,7 @@ fn serve( var child_pid: ?std.process.Child.Id = null; - const main_progress_node = std.Progress.start(.{}); + const main_progress_node = std.Progress.start(io, .{}); const file_system_inputs = comp.file_system_inputs.?; const IncrementalDebugServer = if (build_options.enable_debug_extensions and !builtin.single_threaded) @@ -4694,7 +4684,7 @@ fn cmdTranslateC( }); }; defer zig_file.close(io); - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); var file_reader = zig_file.reader(io, &.{}); _ = try stdout_writer.interface.sendFileAll(&file_reader, .unlimited); try stdout_writer.interface.flush(); @@ -4744,7 +4734,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! if (mem.eql(u8, arg, "-m") or mem.eql(u8, arg, "--minimal")) { template = .minimal; } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(usage_init); + try Io.File.stdout().writeStreamingAll(io, usage_init); return cleanExit(); } else { fatal("unrecognized parameter: '{s}'", .{arg}); @@ -4764,7 +4754,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! switch (template) { .example => { var templates = findTemplates(gpa, arena, io); - defer templates.deinit(); + defer templates.deinit(io); const s = fs.path.sep_str; const template_paths = [_][]const u8{ @@ -4898,7 +4888,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) const argv_index_exe = child_argv.items.len; _ = try child_argv.addOne(); - const self_exe_path = try fs.selfExePathAlloc(arena); + const self_exe_path = try process.executablePathAlloc(io, arena); try child_argv.append(self_exe_path); const argv_index_zig_lib_dir = child_argv.items.len; @@ -5079,7 +5069,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) const work_around_btrfs_bug = native_os == .linux and EnvVar.ZIG_BTRFS_WORKAROUND.isSet(); - const root_prog_node = std.Progress.start(.{ + const root_prog_node = std.Progress.start(io, .{ .disable_printing = (color == .off), .root_name = "Compile Build Script", }); @@ -5114,7 +5104,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) const paths_file = debug_libc_paths_file orelse break :lci null; if (!build_options.enable_debug_extensions) unreachable; const lci = try arena.create(LibCInstallation); - lci.* = try .parse(arena, paths_file, &resolved_target.result); + lci.* = try .parse(arena, io, paths_file, &resolved_target.result); break :lci lci; }; @@ -5129,6 +5119,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) // This `init` calls `fatal` on error. var dirs: Compilation.Directories = .init( arena, + io, override_lib_dir, override_global_cache_dir, .{ .override = path: { @@ -5138,7 +5129,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) {}, self_exe_path, ); - defer dirs.deinit(); + defer dirs.deinit(io); child_argv.items[argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path; child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; @@ -5421,11 +5412,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) child.stderr_behavior = .Inherit; const term = t: { - std.debug.lockStdErr(); - defer std.debug.unlockStdErr(); - break :t child.spawnAndWait(io) catch |err| { + _ = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + break :t child.spawnAndWait(io) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); - }; }; switch (term) { @@ -5517,7 +5507,7 @@ fn jitCmd( dev.check(.jit_command); const color: Color = .auto; - const root_prog_node = if (options.progress_node) |node| node else std.Progress.start(.{ + const root_prog_node = if (options.progress_node) |node| node else std.Progress.start(io, .{ .disable_printing = (color == .off), }); @@ -5529,9 +5519,8 @@ fn jitCmd( .is_explicit_dynamic_linker = false, }; - const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { - fatal("unable to find self exe path: {s}", .{@errorName(err)}); - }; + const self_exe_path = process.executablePathAlloc(io, arena) catch |err| + fatal("unable to find self exe path: {t}", .{err}); const optimize_mode: std.builtin.OptimizeMode = if (EnvVar.ZIG_DEBUG_CMD.isSet()) .Debug @@ -5544,13 +5533,14 @@ fn jitCmd( // This `init` calls `fatal` on error. var dirs: Compilation.Directories = .init( arena, + io, override_lib_dir, override_global_cache_dir, .global, if (native_os == .wasi) wasi_preopens, self_exe_path, ); - defer dirs.deinit(); + defer dirs.deinit(io); const thread_limit = @min( @max(std.Thread.getCpuCount() catch 1, 1), @@ -5629,7 +5619,7 @@ fn jitCmd( defer comp.destroy(); if (options.server) { - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); var server: std.zig.Server = .{ .out = &stdout_writer.interface, .in = undefined, // won't be receiving messages @@ -5696,7 +5686,7 @@ fn jitCmd( ptr.* = try stdout_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32))); } - const term = try child.wait(); + const term = try child.wait(io); switch (term) { .Exited => |code| { if (code == 0) { @@ -6160,7 +6150,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(usage_ast_check); + try Io.File.stdout().writeStreamingAll(io, usage_ast_check); return cleanExit(); } else if (mem.eql(u8, arg, "-t")) { want_output_text = true; @@ -6211,7 +6201,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { const tree = try Ast.parse(arena, source, mode); - var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const stdout_bw = &stdout_writer.interface; switch (mode) { .zig => { @@ -6334,7 +6324,7 @@ fn cmdDetectCpu(io: Io, args: []const []const u8) !void { const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(detect_cpu_usage); + try Io.File.stdout().writeStreamingAll(io, detect_cpu_usage); return cleanExit(); } else if (mem.eql(u8, arg, "--llvm")) { use_llvm = true; @@ -6355,10 +6345,10 @@ fn cmdDetectCpu(io: Io, args: []const []const u8) !void { const name = llvm.GetHostCPUName() orelse fatal("LLVM could not figure out the host cpu name", .{}); const features = llvm.GetHostCPUFeatures() orelse fatal("LLVM could not figure out the host cpu feature set", .{}); const cpu = try detectNativeCpuWithLLVM(builtin.cpu.arch, name, features); - try printCpu(cpu); + try printCpu(io, cpu); } else { const host_target = std.zig.resolveTargetQueryOrFatal(io, .{}); - try printCpu(host_target.cpu); + try printCpu(io, host_target.cpu); } } @@ -6425,8 +6415,8 @@ fn detectNativeCpuWithLLVM( return result; } -fn printCpu(cpu: std.Target.Cpu) !void { - var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); +fn printCpu(io: Io, cpu: std.Target.Cpu) !void { + var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const stdout_bw = &stdout_writer.interface; if (cpu.model.llvm_name) |llvm_name| { @@ -6448,6 +6438,7 @@ fn printCpu(cpu: std.Target.Cpu) !void { fn cmdDumpLlvmInts( gpa: Allocator, arena: Allocator, + io: Io, args: []const []const u8, ) !void { dev.check(.llvm_ints_command); @@ -6475,7 +6466,7 @@ fn cmdDumpLlvmInts( const dl = tm.createTargetDataLayout(); const context = llvm.Context.create(); - var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const stdout_bw = &stdout_writer.interface; for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { const int_type = context.intType(bits); @@ -6501,7 +6492,7 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { defer f.close(io); const zir = try Zcu.loadZirCache(arena, io, f); - var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const stdout_bw = &stdout_writer.interface; { const instruction_bytes = zir.instructions.len * @@ -6585,7 +6576,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); - var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); + var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const stdout_bw = &stdout_writer.interface; { try stdout_bw.print("Instruction mappings:\n", .{}); @@ -6917,7 +6908,7 @@ fn cmdFetch( const arg = args[i]; if (mem.startsWith(u8, arg, "-")) { if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try Io.File.stdout().writeAll(usage_fetch); + try Io.File.stdout().writeStreamingAll(io, usage_fetch); return cleanExit(); } else if (mem.eql(u8, arg, "--global-cache-dir")) { if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); @@ -6951,7 +6942,7 @@ fn cmdFetch( try http_client.initDefaultProxies(arena); - var root_prog_node = std.Progress.start(.{ + var root_prog_node = std.Progress.start(io, .{ .root_name = "Fetch", }); defer root_prog_node.end(); @@ -6959,7 +6950,7 @@ fn cmdFetch( var global_cache_directory: Directory = l: { const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); break :l .{ - .handle = try Io.Dir.cwd().makeOpenPath(p, .{}), + .handle = try Io.Dir.cwd().makeOpenPath(io, p, .{}), .path = p, }; }; @@ -7026,7 +7017,7 @@ fn cmdFetch( const name = switch (save) { .no => { - var stdout = Io.File.stdout().writerStreaming(&stdout_buffer); + var stdout = Io.File.stdout().writerStreaming(io, &stdout_buffer); try stdout.interface.print("{s}\n", .{package_hash_slice}); try stdout.interface.flush(); return cleanExit(); @@ -7044,7 +7035,7 @@ fn cmdFetch( var build_root = try findBuildRoot(arena, io, .{ .cwd_path = cwd_path, }); - defer build_root.deinit(); + defer build_root.deinit(io); // The name to use in case the manifest file needs to be created now. const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path); @@ -7205,7 +7196,7 @@ fn createDependenciesModule( const rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); { - var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); + var tmp_dir = try dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}); defer tmp_dir.close(io); try tmp_dir.writeFile(io, .{ .sub_path = basename, .data = source }); } @@ -7446,28 +7437,28 @@ fn writeSimpleTemplateFile(io: Io, file_name: []const u8, comptime fmt: []const const f = try Io.Dir.cwd().createFile(io, file_name, .{ .exclusive = true }); defer f.close(io); var buf: [4096]u8 = undefined; - var fw = f.writer(&buf); + var fw = f.writer(io, &buf); try fw.interface.print(fmt, args); try fw.interface.flush(); } fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates { const cwd_path = introspect.getResolvedCwd(arena) catch |err| { - fatal("unable to get cwd: {s}", .{@errorName(err)}); + fatal("unable to get cwd: {t}", .{err}); }; - const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { - fatal("unable to find self exe path: {s}", .{@errorName(err)}); + const self_exe_path = process.executablePathAlloc(io, arena) catch |err| { + fatal("unable to find self exe path: {t}", .{err}); }; var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, io, cwd_path, self_exe_path) catch |err| { - fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); + fatal("unable to find zig installation directory '{s}': {t}", .{ self_exe_path, err }); }; const s = fs.path.sep_str; const template_sub_path = "init"; const template_dir = zig_lib_directory.handle.openDir(io, template_sub_path, .{}) catch |err| { const path = zig_lib_directory.path orelse "."; - fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ - path, s, template_sub_path, @errorName(err), + fatal("unable to open zig project template directory '{s}{s}{s}': {t}", .{ + path, s, template_sub_path, err, }); }; diff --git a/src/print_env.zig b/src/print_env.zig index e1847688ad..3540a58d18 100644 --- a/src/print_env.zig +++ b/src/print_env.zig @@ -1,13 +1,17 @@ -const std = @import("std"); const builtin = @import("builtin"); -const build_options = @import("build_options"); -const Compilation = @import("Compilation.zig"); + +const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const EnvVar = std.zig.EnvVar; const fatal = std.process.fatal; +const build_options = @import("build_options"); +const Compilation = @import("Compilation.zig"); + pub fn cmdEnv( arena: Allocator, + io: Io, out: *std.Io.Writer, args: []const []const u8, wasi_preopens: switch (builtin.target.os.tag) { @@ -21,20 +25,21 @@ pub fn cmdEnv( const self_exe_path = switch (builtin.target.os.tag) { .wasi => args[0], - else => std.fs.selfExePathAlloc(arena) catch |err| { - fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); + else => std.process.executablePathAlloc(io, arena) catch |err| { + fatal("unable to find zig self exe path: {t}", .{err}); }, }; var dirs: Compilation.Directories = .init( arena, + io, override_lib_dir, override_global_cache_dir, .global, if (builtin.target.os.tag == .wasi) wasi_preopens, if (builtin.target.os.tag != .wasi) self_exe_path, ); - defer dirs.deinit(); + defer dirs.deinit(io); const zig_lib_dir = dirs.zig_lib.path orelse ""; const zig_std_dir = try dirs.zig_lib.join(arena, &.{"std"}); diff --git a/src/print_targets.zig b/src/print_targets.zig index 2f80187de1..a5e89506ad 100644 --- a/src/print_targets.zig +++ b/src/print_targets.zig @@ -1,14 +1,16 @@ const std = @import("std"); +const Io = std.Io; const fs = std.fs; const mem = std.mem; const meta = std.meta; const fatal = std.process.fatal; const Allocator = std.mem.Allocator; const Target = std.Target; -const target = @import("target.zig"); const assert = std.debug.assert; + const glibc = @import("libs/glibc.zig"); const introspect = @import("introspect.zig"); +const target = @import("target.zig"); pub fn cmdTargets( allocator: Allocator, @@ -18,19 +20,19 @@ pub fn cmdTargets( native_target: *const Target, ) !void { _ = args; - var zig_lib_directory = introspect.findZigLibDir(allocator) catch |err| { - fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); - }; + var zig_lib_directory = introspect.findZigLibDir(allocator, io) catch |err| + fatal("unable to find zig installation directory: {t}", .{err}); defer zig_lib_directory.handle.close(io); defer allocator.free(zig_lib_directory.path.?); const abilists_contents = zig_lib_directory.handle.readFileAlloc( + io, glibc.abilists_path, allocator, .limited(glibc.abilists_max_size), ) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - else => fatal("unable to read " ++ glibc.abilists_path ++ ": {s}", .{@errorName(err)}), + else => fatal("unable to read " ++ glibc.abilists_path ++ ": {t}", .{err}), }; defer allocator.free(abilists_contents); @@ -49,9 +51,7 @@ pub fn cmdTargets( { var libc_obj = try root_obj.beginTupleField("libc", .{}); for (std.zig.target.available_libcs) |libc| { - const tmp = try std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ - @tagName(libc.arch), @tagName(libc.os), @tagName(libc.abi), - }); + const tmp = try std.fmt.allocPrint(allocator, "{t}-{t}-{t}", .{ libc.arch, libc.os, libc.abi }); defer allocator.free(tmp); try libc_obj.field(tmp, .{}); } diff --git a/test/standalone/self_exe_symlink/main.zig b/test/standalone/self_exe_symlink/main.zig index 4df5b02720..dfe3acb7a0 100644 --- a/test/standalone/self_exe_symlink/main.zig +++ b/test/standalone/self_exe_symlink/main.zig @@ -9,7 +9,7 @@ pub fn main() !void { defer threaded.deinit(); const io = threaded.io(); - const self_path = try std.fs.selfExePathAlloc(gpa); + const self_path = try std.process.executablePathAlloc(io, gpa); defer gpa.free(self_path); var self_exe = try std.fs.openSelfExe(.{}); -- cgit v1.2.3 From 1925e0319f1337b4856bd5a181bf4f6d3ac7d428 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 12 Dec 2025 19:04:35 -0800 Subject: update lockStderrWriter sites use the application's Io implementation where possible. This correctly makes writing to stderr cancelable, fallible, and participate in the application's event loop. It also removes one more hard-coded dependency on a secondary Io implementation. --- lib/compiler/build_runner.zig | 18 +++---- lib/compiler/resinator/cli.zig | 8 ++-- lib/compiler/resinator/errors.zig | 8 ++-- lib/compiler/resinator/main.zig | 98 ++++++++++++++++++++------------------- lib/compiler/std-docs.zig | 2 +- lib/compiler/test_runner.zig | 3 -- lib/std/Build.zig | 31 +++++++++---- lib/std/Build/Fuzz.zig | 21 +++++---- lib/std/Build/Step/Compile.zig | 17 ++++--- lib/std/Build/Step/Run.zig | 5 +- lib/std/Build/WebServer.zig | 2 +- lib/std/Progress.zig | 2 +- lib/std/json/dynamic.zig | 5 +- lib/std/process.zig | 2 +- lib/std/testing.zig | 16 +++++-- lib/std/zig.zig | 4 +- lib/std/zig/ErrorBundle.zig | 10 ++-- lib/std/zig/parser_test.zig | 30 +++++++----- src/Air/print.zig | 28 +++++++---- src/Compilation.zig | 53 ++++++++++++--------- src/InternPool.zig | 63 ++++++++++++------------- src/Sema.zig | 8 ++-- src/Zcu/PerThread.zig | 5 +- src/codegen/aarch64/Select.zig | 11 +++-- src/crash_report.zig | 9 ++-- src/fmt.zig | 8 ++-- src/libs/mingw.zig | 29 ++++++++---- src/libs/mingw/def.zig | 32 +++++++++---- src/link.zig | 2 +- src/link/Coff.zig | 15 ++++-- src/link/Elf2.zig | 14 ++++-- src/main.zig | 33 ++++++------- 32 files changed, 345 insertions(+), 247 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index acba1a4621..d284d85747 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -522,7 +522,7 @@ pub fn main() !void { // Perhaps in the future there could be an Advanced Options flag // such as --debug-build-runner-leaks which would make this code // return instead of calling exit. - _ = std.debug.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; process.exit(1); }, else => |e| return e, @@ -554,8 +554,8 @@ pub fn main() !void { } rebuild: while (true) : (if (run.error_style.clearOnUpdate()) { - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); + defer io.unlockStderrWriter(); try stderr.writeAllUnescaped("\x1B[2J\x1B[3J\x1B[H"); }) { if (run.web_server) |*ws| ws.startBuild(); @@ -856,8 +856,8 @@ fn runStepNames( .none => break :summary, } - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); + defer io.unlockStderrWriter(); const w = &stderr.interface; const fwm = stderr.mode; @@ -954,7 +954,7 @@ fn runStepNames( if (run.error_style.verboseContext()) break :code 1; // failure; print build command break :code 2; // failure; do not print build command }; - _ = std.debug.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; process.exit(code); } @@ -1369,8 +1369,10 @@ fn workerMakeOneStep( const show_error_msgs = s.result_error_msgs.items.len > 0; const show_stderr = s.result_stderr.len > 0; if (show_error_msgs or show_compile_errors or show_stderr) { - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&stdio_buffer_allocation) catch |err| switch (err) { + error.Canceled => return, + }; + defer io.unlockStderrWriter(); printErrorMessages(gpa, s, .{}, &stderr.interface, stderr.mode, run.error_style, run.multiline_errors) catch {}; } diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index d2dd71b1f6..08befbe1fa 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -125,10 +125,10 @@ pub const Diagnostics = struct { try self.errors.append(self.allocator, error_details); } - pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void { - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - self.renderToWriter(args, stderr, ttyconf) catch return; + pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) void { + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + self.renderToWriter(args, &stderr.interface, stderr.mode) catch return; } pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void { diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 14ff28a697..031b5d3574 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -67,12 +67,12 @@ pub const Diagnostics = struct { return @intCast(index); } - pub fn renderToStdErr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { + pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { const io = self.io; - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); for (self.errors.items) |err_details| { - renderErrorMessage(io, stderr, ttyconf, cwd, err_details, source, self.strings.items, source_mappings) catch return; + renderErrorMessage(io, &stderr.interface, stderr.mode, cwd, err_details, source, self.strings.items, source_mappings) catch return; } } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 6c12903f06..bd2fcc912e 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -24,6 +24,10 @@ pub fn main() !void { defer std.debug.assert(debug_allocator.deinit() == .ok); const gpa = debug_allocator.allocator(); + var threaded: std.Io.Threaded = .init(gpa); + defer threaded.deinit(); + const io = threaded.io(); + var arena_state = std.heap.ArenaAllocator.init(gpa); defer arena_state.deinit(); const arena = arena_state.allocator(); @@ -31,8 +35,8 @@ pub fn main() !void { const args = try std.process.argsAlloc(arena); if (args.len < 2) { - const w, const ttyconf = std.debug.lockStderrWriter(&.{}); - try renderErrorMessage(w, ttyconf, .err, "expected zig lib dir as first argument", .{}); + const stderr = io.lockStderrWriter(&.{}); + try renderErrorMessage(&stderr.interface, stderr.mode, .err, "expected zig lib dir as first argument", .{}); std.process.exit(1); } const zig_lib_dir = args[1]; @@ -45,7 +49,7 @@ pub fn main() !void { } var stdout_buffer: [1024]u8 = undefined; - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); const stdout = &stdout_writer.interface; var error_handler: ErrorHandler = switch (zig_integration) { true => .{ @@ -71,24 +75,20 @@ pub fn main() !void { if (!zig_integration) { // print any warnings/notes - cli_diagnostics.renderToStdErr(cli_args); + cli_diagnostics.renderToStderr(io, cli_args); // If there was something printed, then add an extra newline separator // so that there is a clear separation between the cli diagnostics and whatever // gets printed after if (cli_diagnostics.errors.items.len > 0) { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try stderr.writeByte('\n'); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try stderr.interface.writeByte('\n'); } } break :options options; }; defer options.deinit(); - var threaded: std.Io.Threaded = .init(gpa); - defer threaded.deinit(); - const io = threaded.io(); - if (options.print_help_and_exit) { try cli.writeUsage(stdout, "zig rc"); try stdout.flush(); @@ -130,10 +130,10 @@ pub fn main() !void { var stderr_buf: [512]u8 = undefined; var diagnostics: aro.Diagnostics = .{ .output = output: { if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } }; - const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf); + const stderr = io.lockStderrWriter(&stderr_buf); break :output .{ .to_writer = .{ - .writer = w, - .color = ttyconf, + .writer = &stderr.interface, + .color = stderr.mode, } }; } }; defer { @@ -175,11 +175,11 @@ pub fn main() !void { std.process.exit(1); }, error.FileTooBig => { - try error_handler.emitMessage(gpa, .err, "failed during preprocessing: maximum file size exceeded", .{}); + try error_handler.emitMessage(gpa, io, .err, "failed during preprocessing: maximum file size exceeded", .{}); std.process.exit(1); }, error.WriteFailed => { - try error_handler.emitMessage(gpa, .err, "failed during preprocessing: error writing the preprocessed output", .{}); + try error_handler.emitMessage(gpa, io, .err, "failed during preprocessing: error writing the preprocessed output", .{}); std.process.exit(1); }, error.OutOfMemory => |e| return e, @@ -191,13 +191,13 @@ pub fn main() !void { .stdio => |file| { var file_reader = file.reader(io, &.{}); break :full_input file_reader.interface.allocRemaining(gpa, .unlimited) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read input from stdin: {s}", .{@errorName(err)}); + try error_handler.emitMessage(gpa, io, .err, "unable to read input from stdin: {s}", .{@errorName(err)}); std.process.exit(1); }; }, .filename => |input_filename| { break :full_input Io.Dir.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); std.process.exit(1); }; }, @@ -228,12 +228,12 @@ pub fn main() !void { } else if (options.input_format == .res) IoStream.fromIoSource(options.input_source, .input) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) }); std.process.exit(1); } else IoStream.fromIoSource(options.output_source, .output) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); std.process.exit(1); }; defer res_stream.deinit(gpa); @@ -246,17 +246,17 @@ pub fn main() !void { var mapping_results = parseAndRemoveLineCommands(gpa, full_input, full_input, .{ .initial_filename = options.input_source.filename }) catch |err| switch (err) { error.InvalidLineCommand => { // TODO: Maybe output the invalid line command - try error_handler.emitMessage(gpa, .err, "invalid line command in the preprocessed source", .{}); + try error_handler.emitMessage(gpa, io, .err, "invalid line command in the preprocessed source", .{}); if (options.preprocess == .no) { - try error_handler.emitMessage(gpa, .note, "line commands must be of the format: #line \"\"", .{}); + try error_handler.emitMessage(gpa, io, .note, "line commands must be of the format: #line \"\"", .{}); } else { - try error_handler.emitMessage(gpa, .note, "this is likely to be a bug, please report it", .{}); + try error_handler.emitMessage(gpa, io, .note, "this is likely to be a bug, please report it", .{}); } std.process.exit(1); }, error.LineNumberOverflow => { // TODO: Better error message - try error_handler.emitMessage(gpa, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)}); + try error_handler.emitMessage(gpa, io, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)}); std.process.exit(1); }, error.OutOfMemory => |e| return e, @@ -306,13 +306,13 @@ pub fn main() !void { // print any warnings/notes if (!zig_integration) { - diagnostics.renderToStdErr(Io.Dir.cwd(), final_input, mapping_results.mappings); + diagnostics.renderToStderr(io, Io.Dir.cwd(), final_input, mapping_results.mappings); } // write the depfile if (options.depfile_path) |depfile_path| { var depfile = Io.Dir.cwd().createFile(io, depfile_path, .{}) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); std.process.exit(1); }; defer depfile.close(io); @@ -340,7 +340,7 @@ pub fn main() !void { if (options.output_format != .coff) return; break :res_data res_stream.source.readAll(gpa, io) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); std.process.exit(1); }; }; @@ -353,14 +353,14 @@ pub fn main() !void { var res_reader: std.Io.Reader = .fixed(res_data.bytes); break :resources cvtres.parseRes(gpa, &res_reader, .{ .max_size = res_data.bytes.len }) catch |err| { // TODO: Better errors - try error_handler.emitMessage(gpa, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); std.process.exit(1); }; }; defer resources.deinit(); var coff_stream = IoStream.fromIoSource(options.output_source, .output) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); std.process.exit(1); }; defer coff_stream.deinit(gpa); @@ -373,7 +373,7 @@ pub fn main() !void { switch (err) { error.DuplicateResource => { const duplicate_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{ duplicate_resource.name_value, fmtResourceType(duplicate_resource.type_value), duplicate_resource.language, @@ -381,8 +381,8 @@ pub fn main() !void { }, error.ResourceDataTooLong => { const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "resource has a data length that is too large to be written into a coff section", .{}); - try error_handler.emitMessage(gpa, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "resource has a data length that is too large to be written into a coff section", .{}); + try error_handler.emitMessage(gpa, io, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{ overflow_resource.name_value, fmtResourceType(overflow_resource.type_value), overflow_resource.language, @@ -390,15 +390,15 @@ pub fn main() !void { }, error.TotalResourceDataTooLong => { const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{}); - try error_handler.emitMessage(gpa, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{}); + try error_handler.emitMessage(gpa, io, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{ overflow_resource.name_value, fmtResourceType(overflow_resource.type_value), overflow_resource.language, }); }, else => { - try error_handler.emitMessage(gpa, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) }); }, } // Delete the output file on error @@ -550,16 +550,16 @@ const LazyIncludePaths = struct { else => |e| { switch (e) { error.UnsupportedAutoIncludesMachineType => { - try error_handler.emitMessage(self.arena, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)}); + try error_handler.emitMessage(self.arena, io, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)}); }, error.MsvcIncludesNotFound => { - try error_handler.emitMessage(self.arena, .err, "MSVC include paths could not be automatically detected", .{}); + try error_handler.emitMessage(self.arena, io, .err, "MSVC include paths could not be automatically detected", .{}); }, error.MingwIncludesNotFound => { - try error_handler.emitMessage(self.arena, .err, "MinGW include paths could not be automatically detected", .{}); + try error_handler.emitMessage(self.arena, io, .err, "MinGW include paths could not be automatically detected", .{}); }, } - try error_handler.emitMessage(self.arena, .note, "to disable auto includes, use the option /:auto-includes none", .{}); + try error_handler.emitMessage(self.arena, io, .note, "to disable auto includes, use the option /:auto-includes none", .{}); std.process.exit(1); }, }; @@ -664,6 +664,7 @@ const ErrorHandler = union(enum) { pub fn emitCliDiagnostics( self: *ErrorHandler, allocator: Allocator, + io: Io, args: []const []const u8, diagnostics: *cli.Diagnostics, ) !void { @@ -674,7 +675,7 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, - .stderr => diagnostics.renderToStdErr(args), + .stderr => diagnostics.renderToStderr(io, args), } } @@ -684,6 +685,7 @@ const ErrorHandler = union(enum) { fail_msg: []const u8, comp: *aro.Compilation, ) !void { + const io = comp.io; switch (self.*) { .server => |*server| { var error_bundle = try compiler_util.aroDiagnosticsToErrorBundle( @@ -697,9 +699,9 @@ const ErrorHandler = union(enum) { }, .stderr => { // aro errors have already been emitted - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg}); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try renderErrorMessage(&stderr.interface, stderr.mode, .err, "{s}", .{fail_msg}); }, } } @@ -707,6 +709,7 @@ const ErrorHandler = union(enum) { pub fn emitDiagnostics( self: *ErrorHandler, allocator: Allocator, + io: Io, cwd: Io.Dir, source: []const u8, diagnostics: *Diagnostics, @@ -719,13 +722,14 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, - .stderr => diagnostics.renderToStdErr(cwd, source, mappings), + .stderr => diagnostics.renderToStderr(io, cwd, source, mappings), } } pub fn emitMessage( self: *ErrorHandler, allocator: Allocator, + io: Io, msg_type: @import("utils.zig").ErrorMessageType, comptime format: []const u8, args: anytype, @@ -741,9 +745,9 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, .stderr => { - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try renderErrorMessage(stderr, ttyconf, msg_type, format, args); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try renderErrorMessage(&stderr.interface, stderr.mode, msg_type, format, args); }, } } diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 538558fe48..9ff199d07b 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -407,7 +407,7 @@ fn buildWasmBinary( } if (result_error_bundle.errorMessageCount() > 0) { - result_error_bundle.renderToStdErr(.{}, true); + result_error_bundle.renderToStderr(io, .{}, true); std.log.err("the following command failed with {d} compilation errors:\n{s}", .{ result_error_bundle.errorMessageCount(), try std.Build.Step.allocPrintCmd(arena, null, argv.items), diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index f7f59a5bf3..3a135ab8fd 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -411,16 +411,13 @@ pub fn fuzz( std.debug.writeStackTrace(trace, &stderr.interface, stderr.mode) catch break :p; } stderr.interface.print("failed with error.{t}\n", .{err}) catch break :p; - stderr.interface.flush() catch break :p; } - stderr.interface.flush() catch {}; std.process.exit(1); }, }; if (log_err_count != 0) { const stderr = std.debug.lockStderrWriter(&.{}); stderr.interface.print("error logs detected\n", .{}) catch {}; - stderr.interface.flush() catch {}; std.process.exit(1); } } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index b7300cb5df..de2985d2b5 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2238,7 +2238,7 @@ pub const GeneratedFile = struct { /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards. path: ?[]const u8 = null, - /// Deprecated, see `getPath2`. + /// Deprecated, see `getPath3`. pub fn getPath(gen: GeneratedFile) []const u8 { return gen.step.owner.pathFromCwd(gen.path orelse std.debug.panic( "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?", @@ -2246,11 +2246,18 @@ pub const GeneratedFile = struct { )); } + /// Deprecated, see `getPath3`. pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 { + return getPath3(gen, src_builder, asking_step) catch |err| switch (err) { + error.Canceled => std.process.exit(1), + }; + } + + pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 { return gen.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const io = gen.step.owner.graph.io; + const stderr = try io.lockStderrWriter(&.{}); dumpBadGetPathHelp(gen.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - std.debug.unlockStderrWriter(); @panic("misconfigured build script"); }; } @@ -2425,22 +2432,29 @@ pub const LazyPath = union(enum) { } } - /// Deprecated, see `getPath3`. + /// Deprecated, see `getPath4`. pub fn getPath(lazy_path: LazyPath, src_builder: *Build) []const u8 { return getPath2(lazy_path, src_builder, null); } - /// Deprecated, see `getPath3`. + /// Deprecated, see `getPath4`. pub fn getPath2(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 { const p = getPath3(lazy_path, src_builder, asking_step); return src_builder.pathResolve(&.{ p.root_dir.path orelse ".", p.sub_path }); } + /// Deprecated, see `getPath4`. + pub fn getPath3(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Cache.Path { + return getPath4(lazy_path, src_builder, asking_step) catch |err| switch (err) { + error.Canceled => std.process.exit(1), + }; + } + /// Intended to be used during the make phase only. /// /// `asking_step` is only used for debugging purposes; it's the step being /// run that is asking for the path. - pub fn getPath3(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Cache.Path { + pub fn getPath4(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Io.Cancelable!Cache.Path { switch (lazy_path) { .src_path => |sp| return .{ .root_dir = sp.owner.build_root, @@ -2457,9 +2471,10 @@ pub const LazyPath = union(enum) { var file_path: Cache.Path = .{ .root_dir = Cache.Directory.cwd(), .sub_path = gen.file.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const io = src_builder.graph.io; + const stderr = try io.lockStderrWriter(&.{}); dumpBadGetPathHelp(gen.file.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic("misconfigured build script"); }, }; diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index c2b7d1e9e9..4770e03a0c 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -158,6 +158,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, parent_prog_node: std.P } fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_node: std.Progress.Node) !void { + const io = run.step.owner.graph.io; const compile = run.producer.?; const prog_node = parent_prog_node.start(compile.step.name, 0); defer prog_node.end(); @@ -170,8 +171,8 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod if (show_error_msgs or show_compile_errors or show_stderr) { var buf: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buf); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buf); + defer io.unlockStderrWriter(); build_runner.printErrorMessages(gpa, &compile.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; } @@ -182,12 +183,10 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod run.rebuilt_executable = try rebuilt_bin_path.join(gpa, compile.out_filename); } -fn fuzzWorkerRun( - fuzz: *Fuzz, - run: *Step.Run, - unit_test_index: u32, -) void { - const gpa = run.step.owner.allocator; +fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { + const owner = run.step.owner; + const gpa = owner.allocator; + const io = owner.graph.io; const test_name = run.cached_test_metadata.?.testName(unit_test_index); const prog_node = fuzz.prog_node.start(test_name, 0); @@ -196,8 +195,10 @@ fn fuzzWorkerRun( run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) { error.MakeFailed => { var buf: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buf); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&buf) catch |e| switch (e) { + error.Canceled => return, + }; + defer io.unlockStderrWriter(); build_runner.printErrorMessages(gpa, &run.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; return; }, diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index d703e55b87..888775884d 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -922,20 +922,23 @@ const CliNamedModules = struct { } }; -fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 { +fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 { + const step = &compile.step; + const b = step.owner; + const io = b.graph.io; const maybe_path: ?*GeneratedFile = @field(compile, tag_name); const generated_file = maybe_path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic("missing emit option for " ++ tag_name); }; const path = generated_file.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic(tag_name ++ " is null. Is there a missing step dependency?"); }; @@ -1149,9 +1152,9 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { // For everything else, we directly link // against the library file. const full_path_lib = if (other_produces_implib) - other.getGeneratedFilePath("generated_implib", &compile.step) + try other.getGeneratedFilePath("generated_implib", &compile.step) else - other.getGeneratedFilePath("generated_bin", &compile.step); + try other.getGeneratedFilePath("generated_bin", &compile.step); try zig_args.append(full_path_lib); total_linker_objects += 1; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index f1e5313905..67cf201374 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1559,6 +1559,7 @@ fn spawnChildAndCollect( ) !?EvalGenericResult { const b = run.step.owner; const arena = b.allocator; + const io = b.graph.io; if (fuzz_context != null) { assert(!has_side_effects); @@ -1625,10 +1626,10 @@ fn spawnChildAndCollect( child.progress_node = options.progress_node; } if (inherit) { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); try setColorEnvironmentVariables(run, env_map, stderr.mode); } - defer if (inherit) std.debug.unlockStderrWriter(); + defer if (inherit) io.unlockStderrWriter(); var timer = try std.time.Timer.start(); const res = try evalGeneric(run, &child); run.step.result_duration_ns = timer.read(); diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index ccb7159192..a2b35e3522 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -655,7 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim } if (result_error_bundle.errorMessageCount() > 0) { - result_error_bundle.renderToStdErr(.{}, .auto); + try result_error_bundle.renderToStderr(io, .{}, .auto); log.err("the following command failed with {d} compilation errors:\n{s}", .{ result_error_bundle.errorMessageCount(), try Build.Step.allocPrintCmd(arena, null, argv.items), diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 603f53091e..6edbf9e471 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -764,7 +764,7 @@ fn appendTreeSymbol(symbol: TreeSymbol, buf: []u8, start_i: usize) usize { } } -pub fn clearWrittenWithEscapeCodes(file_writer: *Io.File.Writer) anyerror!void { +pub fn clearWrittenWithEscapeCodes(file_writer: *Io.File.Writer) Io.Writer.Error!void { if (noop_impl or !global_progress.need_clear) return; try file_writer.writeAllUnescaped(clear ++ progress_remove); global_progress.need_clear = false; diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig index c3cccd1a91..f85916670b 100644 --- a/lib/std/json/dynamic.zig +++ b/lib/std/json/dynamic.zig @@ -47,10 +47,9 @@ pub const Value = union(enum) { } pub fn dump(v: Value) void { - const w, _ = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); - - json.Stringify.value(v, .{}, w) catch return; + json.Stringify.value(v, .{}, &stderr.interface) catch return; } pub fn jsonStringify(value: @This(), jws: anytype) !void { diff --git a/lib/std/process.zig b/lib/std/process.zig index 216e793cbe..4b4c27fe20 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1849,7 +1849,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { /// and does not return. pub fn cleanExit(io: Io) void { if (builtin.mode == .Debug) return; - _ = io.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; exit(0); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 092b65d71a..64ea3d1a4d 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -368,13 +368,21 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const break :diff_index if (expected.len == actual.len) return else shortest; }; if (!backend_can_print) return error.TestExpectedEqual; - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; + if (io.lockStderrWriter(&.{})) |stderr| { + defer io.unlockStderrWriter(); + failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; + } else |_| {} return error.TestExpectedEqual; } -fn failEqualSlices(comptime T: type, expected: []const T, actual: []const T, diff_index: usize, w: *Io.Writer, fwm: Io.File.Writer.Mode) !void { +fn failEqualSlices( + comptime T: type, + expected: []const T, + actual: []const T, + diff_index: usize, + w: *Io.Writer, + fwm: Io.File.Writer.Mode, +) !void { try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); // TODO: Should this be configurable by the caller? diff --git a/lib/std/zig.zig b/lib/std/zig.zig index b6203326f2..a094dee83f 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -639,7 +639,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, file_reader: *Io.File.Reader) ![ return buffer.toOwnedSliceSentinel(gpa, 0); } -pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void { +pub fn printAstErrorsToStderr(gpa: Allocator, io: Io, tree: Ast, path: []const u8, color: Color) !void { var wip_errors: std.zig.ErrorBundle.Wip = undefined; try wip_errors.init(gpa); defer wip_errors.deinit(); @@ -648,7 +648,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); } pub fn putAstErrorsIntoBundle( diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index cc6182c8aa..0342874cf9 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -162,11 +162,13 @@ pub const RenderOptions = struct { include_log_text: bool = true, }; -pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void { +pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Mode.SetColorError; + +pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void { var buffer: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch return; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + try renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)); } pub fn renderToWriter( diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 9d9a6a48ce..5318eab2df 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,7 +1,6 @@ const std = @import("std"); -const mem = std.mem; -const print = std.debug.print; -const maxInt = std.math.maxInt; +const Io = std.Io; +const Allocator = std.mem.Allocator; test "zig fmt: remove extra whitespace at start and end of file with comment between" { try testTransform( @@ -6332,10 +6331,10 @@ test "ampersand" { var fixed_buffer_mem: [100 * 1024]u8 = undefined; -fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 { +fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 { var buffer: [64]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); var tree = try std.zig.Ast.parse(allocator, source, .zig); defer tree.deinit(allocator); @@ -6359,27 +6358,36 @@ fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: * } const formatted = try tree.renderAlloc(allocator); - anything_changed.* = !mem.eql(u8, formatted, source); + anything_changed.* = !std.mem.eql(u8, formatted, source); return formatted; } -fn testTransformImpl(allocator: mem.Allocator, fba: *std.heap.FixedBufferAllocator, source: [:0]const u8, expected_source: []const u8) !void { +fn testTransformImpl( + io: Io, + allocator: Allocator, + fba: *std.heap.FixedBufferAllocator, + source: [:0]const u8, + expected_source: []const u8, +) !void { // reset the fixed buffer allocator each run so that it can be re-used for each // iteration of the failing index fba.reset(); var anything_changed: bool = undefined; - const result_source = try testParse(source, allocator, &anything_changed); + const result_source = try testParse(io, source, allocator, &anything_changed); try std.testing.expectEqualStrings(expected_source, result_source); const changes_expected = source.ptr != expected_source.ptr; if (anything_changed != changes_expected) { - print("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); + std.debug.print("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); return error.TestFailed; } try std.testing.expect(anything_changed == changes_expected); allocator.free(result_source); } fn testTransform(source: [:0]const u8, expected_source: []const u8) !void { + const io = std.testing.io; var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); - return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{ &fixed_allocator, source, expected_source }); + return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{ + io, &fixed_allocator, source, expected_source, + }); } fn testCanonical(source: [:0]const u8) !void { return testTransform(source, source); diff --git a/src/Air/print.zig b/src/Air/print.zig index 95c8a1fcda..05614a0ed3 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -9,7 +9,7 @@ const Type = @import("../Type.zig"); const Air = @import("../Air.zig"); const InternPool = @import("../InternPool.zig"); -pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { +pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) !void { comptime assert(build_options.enable_debug_extensions); const instruction_bytes = air.instructions.len * // Here we don't use @sizeOf(Air.Inst.Data) because it would include @@ -24,7 +24,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air liveness_special_bytes + tomb_bytes; // zig fmt: off - stream.print( + try stream.print( \\# Total AIR+Liveness bytes: {Bi} \\# AIR Instructions: {d} ({Bi}) \\# AIR Extra Data: {d} ({Bi}) @@ -39,7 +39,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air tomb_bytes, if (liveness) |l| l.extra.len else 0, liveness_extra_bytes, if (liveness) |l| l.special.count() else 0, liveness_special_bytes, - }) catch return; + }); // zig fmt: on var writer: Writer = .{ @@ -50,7 +50,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air .indent = 2, .skip_body = false, }; - writer.writeBody(stream, air.getMainBody()) catch return; + try writer.writeBody(stream, air.getMainBody()); } pub fn writeInst( @@ -73,15 +73,23 @@ pub fn writeInst( } pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - const stderr_bw, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - air.write(stderr_bw, pt, liveness); + const comp = pt.zcu.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + air.write(w, pt, liveness); } pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - const stderr_bw, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - air.writeInst(stderr_bw, inst, pt, liveness); + const comp = pt.zcu.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + air.writeInst(w, inst, pt, liveness); } const Writer = struct { diff --git a/src/Compilation.zig b/src/Compilation.zig index 9e76b8feca..47098317b5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2088,12 +2088,13 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, if (options.verbose_llvm_cpu_features) { if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { - const stderr_w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print; - stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; - stderr_w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; - stderr_w.print(" features: {s}\n", .{cf}) catch {}; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.print("compilation: {s}\n", .{options.root_name}) catch break :print; + w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; + w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; + w.print(" features: {s}\n", .{cf}) catch {}; } } @@ -4257,12 +4258,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { // However, we haven't reported any such error. // This is a compiler bug. print_ctx: { - var stderr_w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; - stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; + w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; while (ref) |r| { - stderr_w.print("referenced by: {f}{s}\n", .{ + w.print("referenced by: {f}{s}\n", .{ zcu.fmtAnalUnit(r.referencer), if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", }) catch break :print_ctx; @@ -5756,7 +5758,7 @@ pub fn translateC( try argv.appendSlice(comp.global_cc_argv); try argv.appendSlice(owner_mod.cc_argv); try argv.appendSlice(&.{ source_path, "-o", translated_path }); - if (comp.verbose_cimport) dump_argv(argv.items); + if (comp.verbose_cimport) dumpArgv(io, argv.items); } var stdout: []u8 = undefined; @@ -6264,7 +6266,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dump_argv(argv.items); + dumpArgv(io, argv.items); } const err = std.process.execv(arena, argv.items); @@ -6310,7 +6312,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dump_argv(argv.items); + dumpArgv(io, argv.items); } // Just to save disk space, we delete the files that are never needed again. @@ -7773,17 +7775,22 @@ pub fn lockAndSetMiscFailure( return setMiscFailure(comp, tag, format, args); } -pub fn dump_argv(argv: []const []const u8) void { +pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - nosuspend { - for (argv, 0..) |arg, i| { - if (i != 0) stderr.writeByte(' ') catch return; - stderr.writeAll(arg) catch return; - } - stderr.writeByte('\n') catch return; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + return dumpArgvWriter(w, argv) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; +} + +fn dumpArgvWriter(w: *Io.Writer, argv: []const []const u8) Io.Writer.Error!void { + for (argv, 0..) |arg, i| { + if (i != 0) try w.writeByte(' '); + try w.writeAll(arg); } + try w.writeByte('\n'); } pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend { diff --git a/src/InternPool.zig b/src/InternPool.zig index 5568c493d9..539cb441c5 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -1,8 +1,11 @@ //! All interned objects have both a value and a type. //! This data structure is self-contained. +const InternPool = @This(); const builtin = @import("builtin"); + const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; @@ -11,10 +14,9 @@ const Cache = std.Build.Cache; const Io = std.Io; const Limb = std.math.big.Limb; const Hash = std.hash.Wyhash; +const Zir = std.zig.Zir; -const InternPool = @This(); const Zcu = @import("Zcu.zig"); -const Zir = std.zig.Zir; /// One item per thread, indexed by `tid`, which is dense and unique per thread. locals: []Local, @@ -11165,12 +11167,16 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release); } -pub fn dump(ip: *const InternPool) void { - dumpStatsFallible(ip, std.heap.page_allocator) catch return; - dumpAllFallible(ip) catch return; +pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { + var buffer: [4096]u8 = undefined; + const stderr_writer = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr_writer.interface; + try dumpStatsFallible(ip, w, std.heap.page_allocator); + try dumpAllFallible(ip, w); } -fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { +fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) anyerror!void { var items_len: usize = 0; var extra_len: usize = 0; var limbs_len: usize = 0; @@ -11423,18 +11429,13 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { }; counts.sort(SortContext{ .map = &counts }); const len = @min(50, counts.count()); - std.debug.print(" top 50 tags:\n", .{}); + w.print(" top 50 tags:\n", .{}); for (counts.keys()[0..len], counts.values()[0..len]) |tag, stats| { - std.debug.print(" {s}: {d} occurrences, {d} total bytes\n", .{ - @tagName(tag), stats.count, stats.bytes, - }); + w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); } } -fn dumpAllFallible(ip: *const InternPool) anyerror!void { - var buffer: [4096]u8 = undefined; - const stderr_bw, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); +fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { for (ip.locals, 0..) |*local, tid| { const items = local.shared.items.view(); for ( @@ -11443,12 +11444,12 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { 0.., ) |tag, data, index| { const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip); - try stderr_bw.print("${d} = {s}(", .{ i, @tagName(tag) }); + try w.print("${d} = {s}(", .{ i, @tagName(tag) }); switch (tag) { .removed => {}, - .simple_type => try stderr_bw.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}), - .simple_value => try stderr_bw.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}), + .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}), + .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}), .type_int_signed, .type_int_unsigned, @@ -11521,23 +11522,27 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { .func_coerced, .union_value, .memoized_call, - => try stderr_bw.print("{d}", .{data}), + => try w.print("{d}", .{data}), .opt_null, .type_slice, .only_possible_value, - => try stderr_bw.print("${d}", .{data}), + => try w.print("${d}", .{data}), } - try stderr_bw.writeAll(")\n"); + try w.writeAll(")\n"); } } } -pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void { - ip.dumpGenericInstancesFallible(allocator) catch return; +pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { + var buffer: [4096]u8 = undefined; + const stderr_writer = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr_writer.interface; + try ip.dumpGenericInstancesFallible(allocator, w); } -pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) anyerror!void { +pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, w: *Io.Writer) !void { var arena_allocator = std.heap.ArenaAllocator.init(allocator); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -11564,10 +11569,6 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) } } - var buffer: [4096]u8 = undefined; - const stderr_bw, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - const SortContext = struct { values: []std.ArrayList(Index), pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { @@ -11579,19 +11580,19 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) var it = instances.iterator(); while (it.next()) |entry| { const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav); - try stderr_bw.print("{f} ({d}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len }); + try w.print("{f} ({d}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len }); for (entry.value_ptr.items) |index| { const unwrapped_index = index.unwrap(ip); const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip)); const owner_nav = ip.getNav(func.owner_nav); - try stderr_bw.print(" {f}: (", .{owner_nav.name.fmt(ip)}); + try w.print(" {f}: (", .{owner_nav.name.fmt(ip)}); for (func.comptime_args.get(ip)) |arg| { if (arg != .none) { const key = ip.indexToKey(arg); - try stderr_bw.print(" {} ", .{key}); + try w.print(" {} ", .{key}); } } - try stderr_bw.writeAll(")\n"); + try w.writeAll(")\n"); } } } diff --git a/src/Sema.zig b/src/Sema.zig index fec6850c4c..1f6a577f60 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2668,16 +2668,18 @@ fn failWithTypeMismatch(sema: *Sema, block: *Block, src: LazySrcLoc, expected: T pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) error{ AnalysisFail, OutOfMemory } { @branchHint(.cold); - const gpa = sema.gpa; const zcu = sema.pt.zcu; + const comp = zcu.comp; + const gpa = comp.gpa; + const io = comp.io; - if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) { + if (build_options.enable_debug_extensions and comp.debug_compile_errors) { var wip_errors: std.zig.ErrorBundle.Wip = undefined; wip_errors.init(gpa) catch @panic("out of memory"); Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory"); std.debug.print("compile error during Sema:\n", .{}); var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); - error_bundle.renderToStdErr(.{}, .auto); + error_bundle.renderToStderr(io, .{}, .auto); std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{}); } diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 2333d7f286..408f16bd74 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4556,8 +4556,9 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e defer if (liveness) |*l| l.deinit(gpa); if (build_options.enable_debug_extensions and comp.verbose_air) { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + const io = comp.io; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {}; air.write(stderr, pt, liveness); stderr.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}) catch {}; diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index f390d83f03..138c70fecf 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11273,15 +11273,18 @@ fn initValueAdvanced( return @enumFromInt(isel.values.items.len); } pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { - errdefer |err| @panic(@errorName(err)); - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const zcu = isel.pt.zcu; + const io = zcu.comp.io; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const nav = ip.getNav(isel.nav_index); + errdefer |err| @panic(@errorName(err)); + + const stderr_writer = io.lockStderrWriter(&.{}) catch return; + defer io.unlockStderrWriter(); + const stderr = &stderr_writer.interface; + var reverse_live_values: std.AutoArrayHashMapUnmanaged(Value.Index, std.ArrayList(Air.Inst.Index)) = .empty; defer { for (reverse_live_values.values()) |*list| list.deinit(gpa); diff --git a/src/crash_report.zig b/src/crash_report.zig index 76503fdc53..f23806b758 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -97,17 +97,18 @@ fn dumpCrashContext() Io.Writer.Error!void { // and the actual panic printing, which would be quite confusing. const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); + const w = &stderr.interface; - try stderr.interface.writeAll("Compiler crash context:\n"); + try w.writeAll("Compiler crash context:\n"); if (CodegenFunc.current) |*cg| { const func_nav = cg.zcu.funcInfo(cg.func_index).owner_nav; const func_fqn = cg.zcu.intern_pool.getNav(func_nav).fqn; - try stderr.interface.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); + try w.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); } else if (AnalyzeBody.current) |anal| { - try dumpCrashContextSema(anal, &stderr.interface, &S.crash_heap); + try dumpCrashContextSema(anal, w, &S.crash_heap); } else { - try stderr.interface.writeAll("(no context)\n\n"); + try w.writeAll("(no context)\n\n"); } } fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8) Io.Writer.Error!void { diff --git a/src/fmt.zig b/src/fmt.zig index 55a68d1dc8..b9b1cc1363 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZirErrorMessages(zir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(2); } } else { @@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZoirErrorMessages(zoir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(2); } } @@ -319,7 +319,7 @@ fn fmtPathFile( try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, fmt.color); + error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, @@ -334,7 +334,7 @@ fn fmtPathFile( try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, fmt.color); + error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 05a9de71e7..a76fec9237 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -312,11 +312,17 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" }); - if (comp.verbose_cc) print: { - var stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print; - nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print; + if (comp.verbose_cc) { + var buffer: [256]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.print("def file: {s}\n", .{def_file_path}) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; + w.print("include dir: {s}\n", .{include_dir}) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } try aro_comp.search_path.append(gpa, .{ .path = include_dir, .kind = .normal }); @@ -333,11 +339,13 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) { var buffer: [64]u8 = undefined; - const w, const ttyconf = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); for (aro_comp.diagnostics.output.to_list.messages.items) |msg| { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { - msg.write(w, ttyconf, true) catch {}; + msg.write(&stderr.interface, stderr.mode, true) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; return error.AroPreprocessorFailed; } } @@ -357,8 +365,9 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { error.OutOfMemory => |e| return e, error.ParseError => { var buffer: [64]u8 = undefined; - const w, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; try w.writeAll("error: "); try def_diagnostics.writeMsg(w, input); try w.writeByte('\n'); diff --git a/src/libs/mingw/def.zig b/src/libs/mingw/def.zig index 24dc95c13c..9a105b6182 100644 --- a/src/libs/mingw/def.zig +++ b/src/libs/mingw/def.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; pub const ModuleDefinitionType = enum { mingw, @@ -663,7 +664,9 @@ test parse { \\ ; - try testParse(.AMD64, source, "foo.dll", &[_]ModuleDefinition.Export{ + const io = std.testing.io; + + try testParse(io, .AMD64, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -743,7 +746,7 @@ test parse { }, }); - try testParse(.I386, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .I386, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "_foo", .mangled_symbol_name = null, @@ -823,7 +826,7 @@ test parse { }, }); - try testParse(.ARMNT, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .ARMNT, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -903,7 +906,7 @@ test parse { }, }); - try testParse(.ARM64, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .ARM64, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -997,7 +1000,9 @@ test "ntdll" { \\RtlActivateActivationContextUnsafeFast@0 ; - try testParse(.AMD64, source, "ntdll.dll", &[_]ModuleDefinition.Export{ + const io = std.testing.io; + + try testParse(io, .AMD64, source, "ntdll.dll", &[_]ModuleDefinition.Export{ .{ .name = "RtlDispatchAPC@12", .mangled_symbol_name = null, @@ -1023,15 +1028,22 @@ test "ntdll" { }); } -fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, expected_module_name: []const u8, expected_exports: []const ModuleDefinition.Export) !void { +fn testParse( + io: Io, + machine_type: std.coff.IMAGE.FILE.MACHINE, + source: [:0]const u8, + expected_module_name: []const u8, + expected_exports: []const ModuleDefinition.Export, +) !void { var diagnostics: Diagnostics = undefined; const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) { error.OutOfMemory => |e| return e, error.ParseError => { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try diagnostics.writeMsg(stderr, source); - try stderr.writeByte('\n'); + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + try diagnostics.writeMsg(w, source); + try w.writeByte('\n'); return err; }, }; diff --git a/src/link.zig b/src/link.zig index e37ba98cd9..a4729f296c 100644 --- a/src/link.zig +++ b/src/link.zig @@ -2246,7 +2246,7 @@ fn resolvePathInputLib( var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); std.process.exit(1); } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 8954266e3f..d379669613 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -4,6 +4,7 @@ const builtin = @import("builtin"); const native_endian = builtin.cpu.arch.endian(); const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const log = std.log.scoped(.link); @@ -2377,10 +2378,16 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe _ = name; } -pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void { - const w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - coff.printNode(tid, w, .root, 0) catch {}; +pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void { + const comp = coff.base.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + coff.printNode(tid, w, .root, 0) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } pub fn printNode( diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index fc4794a7b0..3c511f1ee9 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -3729,10 +3729,16 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm _ = name; } -pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void { - const w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - elf.printNode(tid, w, .root, 0) catch {}; +pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { + const comp = elf.base.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + elf.printNode(tid, w, .root, 0) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } pub fn printNode( diff --git a/src/main.zig b/src/main.zig index 115c1b5212..f735f671c6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4429,9 +4429,9 @@ fn runOrTest( // the error message and invocation below. if (process.can_execv and arg_mode == .run) { // execv releases the locks; no need to destroy the Compilation here. - _ = std.debug.lockStderrWriter(&.{}); + _ = try io.lockStderrWriter(&.{}); const err = process.execve(gpa, argv.items, &env_map); - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd }); @@ -4448,8 +4448,8 @@ fn runOrTest( comp_destroyed.* = true; const term_result = t: { - _ = std.debug.lockStderrWriter(); - defer std.debug.unlockStderrWriter(); + _ = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); break :t child.spawnAndWait(io); }; const term = term_result catch |err| { @@ -4606,7 +4606,8 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) defer errors.deinit(comp.gpa); if (errors.errorMessageCount() > 0) { - errors.renderToStdErr(.{}, color); + const io = comp.io; + errors.renderToStderr(io, .{}, color); return error.CompileErrorsReported; } } @@ -4659,7 +4660,7 @@ fn cmdTranslateC( return; } else { const color: Color = .auto; - result.errors.renderToStdErr(.{}, color); + result.errors.renderToStderr(io, .{}, color); process.exit(1); } } @@ -5280,7 +5281,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) if (fetch.error_bundle.root_list.items.len > 0) { var errors = try fetch.error_bundle.toOwnedBundle(""); - errors.renderToStdErr(.{}, color); + errors.renderToStderr(io, .{}, color); process.exit(1); } @@ -5412,8 +5413,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) child.stderr_behavior = .Inherit; const term = t: { - _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + _ = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); break :t child.spawnAndWait(io) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); }; @@ -6212,7 +6213,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(zir, tree, source, display_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); if (zir.loweringFailed()) { process.exit(1); } @@ -6283,7 +6284,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -6557,7 +6558,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -6569,7 +6570,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -7005,7 +7006,7 @@ fn cmdFetch( if (fetch.error_bundle.root_list.items.len > 0) { var errors = try fetch.error_bundle.toOwnedBundle(""); - errors.renderToStdErr(.{}, color); + errors.renderToStderr(io, .{}, color); process.exit(1); } @@ -7345,7 +7346,7 @@ fn loadManifest( errdefer ast.deinit(gpa); if (ast.errors.len > 0) { - try std.zig.printAstErrorsToStderr(gpa, ast, Package.Manifest.basename, options.color); + try std.zig.printAstErrorsToStderr(gpa, io, ast, Package.Manifest.basename, options.color); process.exit(2); } @@ -7362,7 +7363,7 @@ fn loadManifest( var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, options.color); + error_bundle.renderToStderr(io, .{}, options.color); process.exit(2); } -- cgit v1.2.3 From 16bd2e137e56f842a9ff5e015425f9e08eeb97fd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 14 Dec 2025 23:35:33 -0800 Subject: compiler: fix most compilation errors from std.fs changes --- lib/compiler/aro/aro/Diagnostics.zig | 2 +- lib/compiler/aro/aro/Preprocessor.zig | 6 +- lib/std/Build/Cache/Path.zig | 3 +- lib/std/Io/Dir.zig | 2 +- lib/std/crypto/Certificate/Bundle.zig | 3 +- lib/std/fs/test.zig | 2 +- lib/std/zig.zig | 2 +- lib/std/zig/ErrorBundle.zig | 4 +- lib/std/zig/LibCDirs.zig | 19 +++-- lib/std/zig/LibCInstallation.zig | 6 +- src/Builtin.zig | 2 +- src/Compilation.zig | 138 +++++++++++++++++----------------- src/Package/Fetch.zig | 37 ++++----- src/Package/Fetch/git.zig | 2 +- src/Sema.zig | 2 +- src/Zcu.zig | 17 ++--- src/Zcu/PerThread.zig | 50 ++++++++---- src/fmt.zig | 12 +-- src/libs/freebsd.zig | 4 +- src/libs/glibc.zig | 4 +- src/libs/netbsd.zig | 4 +- src/link.zig | 5 +- src/main.zig | 7 +- 23 files changed, 177 insertions(+), 156 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index 9cbc134f02..bebcf4e3d2 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -24,7 +24,7 @@ pub const Message = struct { @"fatal error", }; - pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.tty.Config, details: bool) std.Io.tty.Config.SetColorError!void { + pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.File.Writer.Mode, details: bool) std.Io.tty.Config.SetColorError!void { try config.setColor(w, .bold); if (msg.location) |loc| { try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col }); diff --git a/lib/compiler/aro/aro/Preprocessor.zig b/lib/compiler/aro/aro/Preprocessor.zig index e8343dc83a..6e36703df1 100644 --- a/lib/compiler/aro/aro/Preprocessor.zig +++ b/lib/compiler/aro/aro/Preprocessor.zig @@ -1065,11 +1065,13 @@ fn fatalNotFound(pp: *Preprocessor, tok: TokenWithExpansionLocs, filename: []con fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void { @branchHint(.cold); - const source = pp.comp.getSource(raw.source); + const comp = pp.comp; + const io = comp.io; + const source = comp.getSource(raw.source); const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start }); var stderr_buf: [4096]u8 = undefined; - var stderr = Io.File.stderr().writer(&stderr_buf); + var stderr = Io.File.stderr().writer(io, &stderr_buf); const w = &stderr.interface; w.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return; diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 51f9e7aecd..3ef4dec658 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -106,6 +106,7 @@ pub fn statFile(p: Path, io: Io, sub_path: []const u8) !Io.Dir.Stat { pub fn atomicFile( p: Path, + io: Io, sub_path: []const u8, options: Io.Dir.AtomicFileOptions, buf: *[fs.max_path_bytes]u8, @@ -115,7 +116,7 @@ pub fn atomicFile( p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.atomicFile(joined_path, options); + return p.root_dir.handle.atomicFile(io, joined_path, options); } pub fn access(p: Path, io: Io, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void { diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 5cd3b898d8..94c159d0bf 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1645,7 +1645,7 @@ pub fn copyFile( .permissions = permissions, .write_buffer = &buffer, }); - defer atomic_file.deinit(io); + defer atomic_file.deinit(); _ = atomic_file.file_writer.interface.sendFileAll(&file_reader, .unlimited) catch |err| switch (err) { error.ReadFailed => return file_reader.err.?, diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index a4af82b2f2..385ef23c9c 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -202,7 +202,7 @@ pub const AddCertsFromDirError = AddCertsFromFilePathError; pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, iterable_dir: Io.Dir) AddCertsFromDirError!void { var it = iterable_dir.iterate(); - while (try it.next()) |entry| { + while (try it.next(io)) |entry| { switch (entry.kind) { .file, .sym_link => {}, else => continue, @@ -243,6 +243,7 @@ pub fn addCertsFromFilePath( pub const AddCertsFromFileError = Allocator.Error || Io.File.Reader.Error || + Io.File.Reader.SizeError || ParseCertError || std.base64.Error || error{ CertificateAuthorityBundleTooBig, MissingEndCertificateMarker, Streaming }; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index fa3eaed3fa..53612e4f96 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1598,7 +1598,7 @@ test "AtomicFile" { { var buffer: [100]u8 = undefined; - var af = try ctx.dir.atomicFile(test_out_file, .{ .write_buffer = &buffer }); + var af = try ctx.dir.atomicFile(io, test_out_file, .{ .write_buffer = &buffer }); defer af.deinit(); try af.file_writer.interface.writeAll(test_content); try af.finish(); diff --git a/lib/std/zig.zig b/lib/std/zig.zig index a094dee83f..6e89c75d91 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -648,7 +648,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, io: Io, tree: Ast, path: []const u var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, color); + return error_bundle.renderToStderr(io, .{}, color); } pub fn putAstErrorsIntoBundle( diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index 907256c2e4..556b1167a3 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -162,14 +162,14 @@ pub const RenderOptions = struct { include_log_text: bool = true, }; -pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Mode.SetColorError; +pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Error; pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void { var buffer: [256]u8 = undefined; const stderr = try io.lockStderrWriter(&buffer); defer io.unlockStderrWriter(); renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch |err| switch (err) { - error.WriteFailed => return stderr.interface.err.?, + error.WriteFailed => return stderr.err.?, else => |e| return e, }; } diff --git a/lib/std/zig/LibCDirs.zig b/lib/std/zig/LibCDirs.zig index fa297cd53a..e05ccde589 100644 --- a/lib/std/zig/LibCDirs.zig +++ b/lib/std/zig/LibCDirs.zig @@ -1,3 +1,11 @@ +const LibCDirs = @This(); +const builtin = @import("builtin"); + +const std = @import("../std.zig"); +const Io = std.Io; +const LibCInstallation = std.zig.LibCInstallation; +const Allocator = std.mem.Allocator; + libc_include_dir_list: []const []const u8, libc_installation: ?*const LibCInstallation, libc_framework_dir_list: []const []const u8, @@ -14,6 +22,7 @@ pub const DarwinSdkLayout = enum { pub fn detect( arena: Allocator, + io: Io, zig_lib_dir: []const u8, target: *const std.Target, is_native_abi: bool, @@ -38,7 +47,7 @@ pub fn detect( // using the system libc installation. if (is_native_abi and !target.isMinGW()) { const libc = try arena.create(LibCInstallation); - libc.* = LibCInstallation.findNative(.{ .allocator = arena, .target = target }) catch |err| switch (err) { + libc.* = LibCInstallation.findNative(arena, io, .{ .target = target }) catch |err| switch (err) { error.CCompilerExitCode, error.CCompilerCrashed, error.CCompilerCannotFindHeaders, @@ -75,7 +84,7 @@ pub fn detect( if (use_system_abi) { const libc = try arena.create(LibCInstallation); - libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, .target = target }); + libc.* = try LibCInstallation.findNative(arena, io, .{ .verbose = true, .target = target }); return detectFromInstallation(arena, target, libc); } @@ -265,9 +274,3 @@ fn libCGenericName(target: *const std.Target) [:0]const u8 { => unreachable, } } - -const LibCDirs = @This(); -const builtin = @import("builtin"); -const std = @import("../std.zig"); -const LibCInstallation = std.zig.LibCInstallation; -const Allocator = std.mem.Allocator; diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index 6051eecb94..c1fc8fccaa 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -204,7 +204,7 @@ pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!Lib try self.findNativeIncludeDirWindows(gpa, io, args, sdk); try self.findNativeCrtDirWindows(gpa, io, args.target, sdk); } else if (is_haiku) { - try self.findNativeIncludeDirPosix(args); + try self.findNativeIncludeDirPosix(gpa, io, args); try self.findNativeGccDirHaiku(gpa, io, args); self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib"); } else if (builtin.target.os.tag == .illumos) { @@ -213,7 +213,7 @@ pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!Lib self.sys_include_dir = try gpa.dupeZ(u8, "/usr/include"); self.crt_dir = try gpa.dupeZ(u8, "/usr/lib/64"); } else if (std.process.can_spawn) { - try self.findNativeIncludeDirPosix(args); + try self.findNativeIncludeDirPosix(gpa, io, args); switch (builtin.target.os.tag) { .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"), .linux => try self.findNativeCrtDirPosix(gpa, io, args), @@ -335,7 +335,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar defer search_dir.close(io); if (self.include_dir == null) { - if (search_dir.access(include_dir_example_file, .{})) |_| { + if (search_dir.access(io, include_dir_example_file, .{})) |_| { self.include_dir = try gpa.dupeZ(u8, search_path); } else |err| switch (err) { error.FileNotFound => {}, diff --git a/src/Builtin.zig b/src/Builtin.zig index 9e4fae8e6a..a097e88734 100644 --- a/src/Builtin.zig +++ b/src/Builtin.zig @@ -343,7 +343,7 @@ pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { } // `make_path` matters because the dir hasn't actually been created yet. - var af = try root_dir.atomicFile(sub_path, .{ .make_path = true, .write_buffer = &.{} }); + var af = try root_dir.atomicFile(io, sub_path, .{ .make_path = true, .write_buffer = &.{} }); defer af.deinit(); try af.file_writer.interface.writeAll(file.source.?); af.finish() catch |err| switch (err) { diff --git a/src/Compilation.zig b/src/Compilation.zig index 47098317b5..37e15ab171 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -771,8 +771,8 @@ pub const Directories = struct { const zig_lib: Cache.Directory = d: { if (override_zig_lib) |path| break :d openUnresolved(arena, io, cwd, path, .@"zig lib"); if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib"); - break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| { - fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); + break :d introspect.findZigLibDirFromSelfExe(arena, io, cwd, self_exe_path) catch |err| { + fatal("unable to find zig installation directory '{s}': {t}", .{ self_exe_path, err }); }; }; @@ -780,7 +780,7 @@ pub const Directories = struct { if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache"); if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache"); const path = introspect.resolveGlobalCacheDir(arena) catch |err| { - fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); + fatal("unable to resolve zig cache directory: {t}", .{err}); }; break :d openUnresolved(arena, io, cwd, path, .@"global cache"); }; @@ -789,7 +789,7 @@ pub const Directories = struct { .override => |path| openUnresolved(arena, io, cwd, path, .@"local cache"), .search => d: { const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, io, cwd) catch |err| { - fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); + fatal("unable to resolve zig cache directory: {t}", .{err}); }; const path = maybe_path orelse break :d global_cache; break :d openUnresolved(arena, io, cwd, path, .@"local cache"); @@ -919,8 +919,8 @@ pub const CrtFile = struct { lock: Cache.Lock, full_object_path: Cache.Path, - pub fn deinit(self: *CrtFile, gpa: Allocator) void { - self.lock.release(); + pub fn deinit(self: *CrtFile, gpa: Allocator, io: Io) void { + self.lock.release(io); gpa.free(self.full_object_path.sub_path); self.* = undefined; } @@ -1317,7 +1317,7 @@ pub const CObject = struct { }; /// Returns if there was failure. - pub fn clearStatus(self: *CObject, gpa: Allocator) bool { + pub fn clearStatus(self: *CObject, gpa: Allocator, io: Io) bool { switch (self.status) { .new => return false, .failure, .failure_retryable => { @@ -1326,15 +1326,15 @@ pub const CObject = struct { }, .success => |*success| { gpa.free(success.object_path.sub_path); - success.lock.release(); + success.lock.release(io); self.status = .new; return false; }, } } - pub fn destroy(self: *CObject, gpa: Allocator) void { - _ = self.clearStatus(gpa); + pub fn destroy(self: *CObject, gpa: Allocator, io: Io) void { + _ = self.clearStatus(gpa, io); gpa.destroy(self); } }; @@ -1364,7 +1364,7 @@ pub const Win32Resource = struct { }, /// Returns true if there was failure. - pub fn clearStatus(self: *Win32Resource, gpa: Allocator) bool { + pub fn clearStatus(self: *Win32Resource, gpa: Allocator, io: Io) bool { switch (self.status) { .new => return false, .failure, .failure_retryable => { @@ -1373,15 +1373,15 @@ pub const Win32Resource = struct { }, .success => |*success| { gpa.free(success.res_path); - success.lock.release(); + success.lock.release(io); self.status = .new; return false; }, } } - pub fn destroy(self: *Win32Resource, gpa: Allocator) void { - _ = self.clearStatus(gpa); + pub fn destroy(self: *Win32Resource, gpa: Allocator, io: Io) void { + _ = self.clearStatus(gpa, io); gpa.destroy(self); } }; @@ -1610,9 +1610,9 @@ const CacheUse = union(CacheMode) { /// Prevents other processes from clobbering files in the output directory. lock: ?Cache.Lock, - fn releaseLock(whole: *Whole) void { + fn releaseLock(whole: *Whole, io: Io) void { if (whole.lock) |*lock| { - lock.release(); + lock.release(io); whole.lock = null; } } @@ -1634,7 +1634,7 @@ const CacheUse = union(CacheMode) { }, .whole => |whole| { assert(whole.tmp_artifact_directory == null); - whole.releaseLock(); + whole.releaseLock(io); }, } } @@ -1903,13 +1903,17 @@ pub const CreateDiagnostic = union(enum) { return error.CreateFail; } }; -pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, options: CreateOptions) error{ + +pub const CreateError = error{ OutOfMemory, + Canceled, Unexpected, CurrentWorkingDirectoryUnlinked, /// An error has been stored to `diag`. CreateFail, -}!*Compilation { +}; + +pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, options: CreateOptions) CreateError!*Compilation { const output_mode = options.config.output_mode; const is_dyn_lib = switch (output_mode) { .Obj, .Exe => false, @@ -1957,6 +1961,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, const libc_dirs = std.zig.LibCDirs.detect( arena, + io, options.dirs.zig_lib.path.?, target, options.root_mod.resolved_target.is_native_abi, @@ -2701,7 +2706,7 @@ pub fn destroy(comp: *Compilation) void { if (comp.bin_file) |lf| lf.destroy(); if (comp.zcu) |zcu| zcu.deinit(); - comp.cache_use.deinit(); + comp.cache_use.deinit(io); for (&comp.work_queues) |*work_queue| work_queue.deinit(gpa); comp.c_object_work_queue.deinit(gpa); @@ -2714,36 +2719,36 @@ pub fn destroy(comp: *Compilation) void { var it = comp.crt_files.iterator(); while (it.next()) |entry| { gpa.free(entry.key_ptr.*); - entry.value_ptr.deinit(gpa); + entry.value_ptr.deinit(gpa, io); } comp.crt_files.deinit(gpa); } - if (comp.libcxx_static_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.libcxxabi_static_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.libunwind_static_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.tsan_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.ubsan_rt_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.ubsan_rt_obj) |*crt_file| crt_file.deinit(gpa); - if (comp.zigc_static_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.compiler_rt_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.compiler_rt_obj) |*crt_file| crt_file.deinit(gpa); - if (comp.compiler_rt_dyn_lib) |*crt_file| crt_file.deinit(gpa); - if (comp.fuzzer_lib) |*crt_file| crt_file.deinit(gpa); + if (comp.libcxx_static_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.libcxxabi_static_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.libunwind_static_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.tsan_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.ubsan_rt_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.ubsan_rt_obj) |*crt_file| crt_file.deinit(gpa, io); + if (comp.zigc_static_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.compiler_rt_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.compiler_rt_obj) |*crt_file| crt_file.deinit(gpa, io); + if (comp.compiler_rt_dyn_lib) |*crt_file| crt_file.deinit(gpa, io); + if (comp.fuzzer_lib) |*crt_file| crt_file.deinit(gpa, io); if (comp.glibc_so_files) |*glibc_file| { - glibc_file.deinit(gpa); + glibc_file.deinit(gpa, io); } if (comp.freebsd_so_files) |*freebsd_file| { - freebsd_file.deinit(gpa); + freebsd_file.deinit(gpa, io); } if (comp.netbsd_so_files) |*netbsd_file| { - netbsd_file.deinit(gpa); + netbsd_file.deinit(gpa, io); } for (comp.c_object_table.keys()) |key| { - key.destroy(gpa); + key.destroy(gpa, io); } comp.c_object_table.deinit(gpa); @@ -2753,7 +2758,7 @@ pub fn destroy(comp: *Compilation) void { comp.failed_c_objects.deinit(gpa); for (comp.win32_resource_table.keys()) |key| { - key.destroy(gpa); + key.destroy(gpa, io); } comp.win32_resource_table.deinit(gpa); @@ -2906,7 +2911,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE .whole => |whole| { assert(comp.bin_file == null); // We are about to obtain this lock, so here we give other processes a chance first. - whole.releaseLock(); + whole.releaseLock(io); man = comp.cache_parent.obtain(); whole.cache_manifest = &man; @@ -3092,17 +3097,12 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE } if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { - std.debug.print("intern pool stats for '{s}':\n", .{ - comp.root_name, - }); - zcu.intern_pool.dump(); + std.debug.print("intern pool stats for '{s}':\n", .{comp.root_name}); + zcu.intern_pool.dump(io); } if (build_options.enable_debug_extensions and comp.verbose_generic_instances) { - std.debug.print("generic instances for '{s}:0x{x}':\n", .{ - comp.root_name, - @intFromPtr(zcu), - }); + std.debug.print("generic instances for '{s}:0x{x}':\n", .{ comp.root_name, @intFromPtr(zcu) }); zcu.intern_pool.dumpGenericInstances(gpa); } } @@ -3680,6 +3680,7 @@ pub fn saveState(comp: *Compilation) !void { const lf = comp.bin_file orelse return; const gpa = comp.gpa; + const io = comp.io; var bufs = std.array_list.Managed([]const u8).init(gpa); defer bufs.deinit(); @@ -3900,7 +3901,7 @@ pub fn saveState(comp: *Compilation) !void { // Using an atomic file prevents a crash or power failure from corrupting // the previous incremental compilation state. var write_buffer: [1024]u8 = undefined; - var af = try lf.emit.root_dir.handle.atomicFile(basename, .{ .write_buffer = &write_buffer }); + var af = try lf.emit.root_dir.handle.atomicFile(io, basename, .{ .write_buffer = &write_buffer }); defer af.deinit(); try af.file_writer.interface.writeVecAll(bufs.items); try af.finish(); @@ -4258,8 +4259,8 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { // However, we haven't reported any such error. // This is a compiler bug. print_ctx: { - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + const stderr = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); const w = &stderr.interface; w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; @@ -5219,13 +5220,10 @@ fn processOneJob( } } -fn createDepFile( - comp: *Compilation, - depfile: []const u8, - binfile: Cache.Path, -) anyerror!void { +fn createDepFile(comp: *Compilation, depfile: []const u8, binfile: Cache.Path) anyerror!void { + const io = comp.io; var buf: [4096]u8 = undefined; - var af = try Io.Dir.cwd().atomicFile(depfile, .{ .write_buffer = &buf }); + var af = try Io.Dir.cwd().atomicFile(io, depfile, .{ .write_buffer = &buf }); defer af.deinit(); comp.writeDepFile(binfile, &af.file_writer.interface) catch return af.file_writer.err.?; @@ -5280,13 +5278,8 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { const basename = fs.path.basename(sub_path); - comp.dirs.zig_lib.handle.copyFile(sub_path, out_dir, basename, .{}) catch |err| { - comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {s}", .{ - sub_path, - @errorName(err), - }); - return; - }; + comp.dirs.zig_lib.handle.copyFile(sub_path, out_dir, basename, io, .{}) catch |err| + return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {t}", .{ sub_path, err }); } var tar_file = out_dir.createFile(io, "sources.tar", .{}) catch |err| { @@ -5350,7 +5343,7 @@ fn docsCopyModule( var buffer: [1024]u8 = undefined; - while (try walker.next()) |entry| { + while (try walker.next(io)) |entry| { switch (entry.kind) { .file => { if (!std.mem.endsWith(u8, entry.basename, ".zig")) continue; @@ -5505,7 +5498,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU try comp.updateSubCompilation(sub_compilation, .docs_wasm, prog_node); var crt_file = try sub_compilation.toCrtFile(); - defer crt_file.deinit(gpa); + defer crt_file.deinit(gpa, io); const docs_bin_file = crt_file.full_object_path; assert(docs_bin_file.sub_path.len > 0); // emitted binary is not a directory @@ -5521,10 +5514,12 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU }; defer out_dir.close(io); - crt_file.full_object_path.root_dir.handle.copyFile( + Io.Dir.copyFile( + crt_file.full_object_path.root_dir.handle, crt_file.full_object_path.sub_path, out_dir, "main.wasm", + io, .{}, ) catch |err| { comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{f}' to '{f}': {t}", .{ @@ -5758,7 +5753,7 @@ pub fn translateC( try argv.appendSlice(comp.global_cc_argv); try argv.appendSlice(owner_mod.cc_argv); try argv.appendSlice(&.{ source_path, "-o", translated_path }); - if (comp.verbose_cimport) dumpArgv(io, argv.items); + if (comp.verbose_cimport) try dumpArgv(io, argv.items); } var stdout: []u8 = undefined; @@ -6153,7 +6148,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr const gpa = comp.gpa; const io = comp.io; - if (c_object.clearStatus(gpa)) { + if (c_object.clearStatus(gpa, io)) { // There was previous failure. comp.mutex.lockUncancelable(io); defer comp.mutex.unlock(io); @@ -6500,7 +6495,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - if (win32_resource.clearStatus(comp.gpa)) { + if (win32_resource.clearStatus(comp.gpa, io)) { // There was previous failure. comp.mutex.lockUncancelable(io); defer comp.mutex.unlock(io); @@ -6768,7 +6763,7 @@ fn spawnZigRc( // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) const stderr = poller.reader(.stderr); - const term = child.wait() catch |err| { + const term = child.wait(io) catch |err| { return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv[0], @errorName(err) }); }; @@ -7781,7 +7776,10 @@ pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { defer io.unlockStderrWriter(); const w = &stderr.interface; return dumpArgvWriter(w, argv) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + error.WriteFailed => switch (stderr.err.?) { + error.Canceled => return error.Canceled, + else => return, + }, }; } diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 33214a47db..823015574b 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -501,7 +501,7 @@ fn runResource( .path = tmp_directory_path, .handle = handle: { const dir = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ - .iterate = true, + .open_options = .{ .iterate = true }, }) catch |err| { try eb.addRootErrorMessage(.{ .msg = try eb.printString("unable to create temporary directory '{s}': {t}", .{ @@ -525,7 +525,7 @@ fn runResource( // https://github.com/ziglang/zig/issues/17095 pkg_path.root_dir.handle.close(io); pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ - .iterate = true, + .open_options = .{ .iterate = true }, }) catch @panic("btrfs workaround failed"); } @@ -1334,7 +1334,7 @@ fn unzip( f.location_tok, try eb.printString("failed writing temporary zip file: {t}", .{err}), ); - break :b zip_file_writer.moveToReader(io); + break :b zip_file_writer.moveToReader(); }; var diagnostics: std.zip.Diagnostics = .{ .allocator = f.arena.allocator() }; @@ -1376,7 +1376,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U const fetch_reader = &resource.fetch_stream.reader; _ = try fetch_reader.streamRemaining(&pack_file_writer.interface); try pack_file_writer.interface.flush(); - break :b pack_file_writer.moveToReader(io); + break :b pack_file_writer.moveToReader(); }; var index_file = try pack_dir.createFile(io, "pkg.idx", .{ .read = true }); @@ -1421,26 +1421,21 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void // Recursive directory copy. var it = try dir.walk(gpa); defer it.deinit(); - while (try it.next()) |entry| { + while (try it.next(io)) |entry| { switch (entry.kind) { .directory => {}, // omit empty directories .file => { - dir.copyFile( - entry.path, - tmp_dir, - entry.path, - .{}, - ) catch |err| switch (err) { + dir.copyFile(entry.path, tmp_dir, entry.path, io, .{}) catch |err| switch (err) { error.FileNotFound => { if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); - try dir.copyFile(entry.path, tmp_dir, entry.path, .{}); + try dir.copyFile(entry.path, tmp_dir, entry.path, io, .{}); }, else => |e| return e, }; }, .sym_link => { var buf: [fs.max_path_bytes]u8 = undefined; - const link_name = try dir.readLink(io, entry.path, &buf); + const link_name = buf[0..try dir.readLink(io, entry.path, &buf)]; // TODO: if this would create a symlink to outside // the destination directory, fail with an error instead. tmp_dir.symLink(io, link_name, entry.path, .{}) catch |err| switch (err) { @@ -1524,7 +1519,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute var group: Io.Group = .init; defer group.wait(io); - while (walker.next() catch |err| { + while (walker.next(io) catch |err| { try eb.addRootErrorMessage(.{ .msg = try eb.printString( "unable to walk temporary directory '{f}': {s}", .{ pkg_path, @errorName(err) }, @@ -1575,7 +1570,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute .failure = undefined, // to be populated by the worker .size = undefined, // to be populated by the worker }; - group.async(io, workerHashFile, .{ root_dir, hashed_file }); + group.async(io, workerHashFile, .{ io, root_dir, hashed_file }); try all_files.append(hashed_file); } } @@ -1643,7 +1638,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute assert(!f.job_queue.recursive); // Print something to stdout that can be text diffed to figure out why // the package hash is different. - dumpHashInfo(all_files.items) catch |err| { + dumpHashInfo(io, all_files.items) catch |err| { std.debug.print("unable to write to stdout: {s}\n", .{@errorName(err)}); std.process.exit(1); }; @@ -1655,9 +1650,9 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute }; } -fn dumpHashInfo(all_files: []const *const HashedFile) !void { +fn dumpHashInfo(io: Io, all_files: []const *const HashedFile) !void { var stdout_buffer: [1024]u8 = undefined; - var stdout_writer: Io.File.Writer = .initStreaming(.stdout(), &stdout_buffer); + var stdout_writer: Io.File.Writer = .initStreaming(.stdout(), io, &stdout_buffer); const w = &stdout_writer.interface; for (all_files) |hashed_file| { try w.print("{t}: {x}: {s}\n", .{ hashed_file.kind, &hashed_file.hash, hashed_file.normalized_path }); @@ -1665,8 +1660,8 @@ fn dumpHashInfo(all_files: []const *const HashedFile) !void { try w.flush(); } -fn workerHashFile(dir: Io.Dir, hashed_file: *HashedFile) void { - hashed_file.failure = hashFileFallible(dir, hashed_file); +fn workerHashFile(io: Io, dir: Io.Dir, hashed_file: *HashedFile) void { + hashed_file.failure = hashFileFallible(io, dir, hashed_file); } fn workerDeleteFile(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) void { @@ -1745,7 +1740,7 @@ const HashedFile = struct { Io.File.OpenError || Io.File.Reader.Error || Io.File.StatError || - Io.File.ChmodError || + Io.File.SetPermissionsError || Io.Dir.ReadLinkError; const Kind = enum { file, link }; diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index f53c96cc3d..fd48b0a9b1 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -274,7 +274,7 @@ pub const Repository = struct { continue; }; defer file.close(io); - try file.writeAll(file_object.data); + try file.writePositionalAll(io, file_object.data, 0); }, .symlink => { try repository.odb.seekOid(entry.oid); diff --git a/src/Sema.zig b/src/Sema.zig index 1f6a577f60..298de783b8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2679,7 +2679,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory"); std.debug.print("compile error during Sema:\n", .{}); var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); - error_bundle.renderToStderr(io, .{}, .auto); + error_bundle.renderToStderr(io, .{}, .auto) catch @panic("failed to print to stderr"); std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{}); } diff --git a/src/Zcu.zig b/src/Zcu.zig index e0e254d807..07fb1bdc94 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -2988,11 +2988,10 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_br: *Io.Reader pub fn saveZirCache( gpa: Allocator, - io: Io, - cache_file: Io.File, + cache_file_writer: *Io.File.Writer, stat: Io.File.Stat, zir: Zir, -) (Io.File.WriteError || Allocator.Error)!void { +) (Io.File.Writer.Error || Allocator.Error)!void { const safety_buffer = if (data_has_safety_tag) try gpa.alloc([8]u8, zir.instructions.len) else @@ -3026,13 +3025,12 @@ pub fn saveZirCache( zir.string_bytes, @ptrCast(zir.extra), }; - var cache_fw = cache_file.writer(io, &.{}); - cache_fw.interface.writeVecAll(&vecs) catch |err| switch (err) { - error.WriteFailed => return cache_fw.err.?, + cache_file_writer.interface.writeVecAll(&vecs) catch |err| switch (err) { + error.WriteFailed => return cache_file_writer.err.?, }; } -pub fn saveZoirCache(io: Io, cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir) Io.File.WriteError!void { +pub fn saveZoirCache(cache_file_writer: *Io.File.Writer, stat: Io.File.Stat, zoir: Zoir) Io.File.Writer.Error!void { const header: Zoir.Header = .{ .nodes_len = @intCast(zoir.nodes.len), .extra_len = @intCast(zoir.extra.len), @@ -3056,9 +3054,8 @@ pub fn saveZoirCache(io: Io, cache_file: Io.File, stat: Io.File.Stat, zoir: Zoir @ptrCast(zoir.compile_errors), @ptrCast(zoir.error_notes), }; - var cache_fw = cache_file.writer(io, &.{}); - cache_fw.interface.writeVecAll(&vecs) catch |err| switch (err) { - error.WriteFailed => return cache_fw.err.?, + cache_file_writer.interface.writeVecAll(&vecs) catch |err| switch (err) { + error.WriteFailed => return cache_file_writer.err.?, }; } diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 408f16bd74..76ab3e229c 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -238,18 +238,13 @@ pub fn updateFile( if (builtin.os.tag == .wasi or lock == .exclusive) break true; // Otherwise, unlock to give someone a chance to get the exclusive lock // and then upgrade to an exclusive lock. - cache_file.unlock(); + cache_file.unlock(io); lock = .exclusive; - try cache_file.lock(lock); + try cache_file.lock(io, lock); }; if (need_update) { - // The cache is definitely stale so delete the contents to avoid an underwrite later. - cache_file.setLength(io, 0) catch |err| switch (err) { - error.FileTooBig => unreachable, // 0 is not too big - else => |e| return e, - }; - try cache_file.seekTo(0); + var cache_file_writer: Io.File.Writer = .init(cache_file, io, &.{}); if (stat.size > std.math.maxInt(u32)) return error.FileTooBig; @@ -278,7 +273,7 @@ pub fn updateFile( switch (file.getMode()) { .zig => { file.zir = try AstGen.generate(gpa, file.tree.?); - Zcu.saveZirCache(gpa, io, cache_file, stat, file.zir.?) catch |err| switch (err) { + Zcu.saveZirCache(gpa, &cache_file_writer, stat, file.zir.?) catch |err| switch (err) { error.OutOfMemory => |e| return e, else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {t}", .{ file.path.fmt(comp), cache_directory, &hex_digest, err, @@ -287,13 +282,19 @@ pub fn updateFile( }, .zon => { file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); - Zcu.saveZoirCache(io, cache_file, stat, file.zoir.?) catch |err| { + Zcu.saveZoirCache(&cache_file_writer, stat, file.zoir.?) catch |err| { log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {t}", .{ file.path.fmt(comp), cache_directory, &hex_digest, err, }); }; }, } + + cache_file_writer.end() catch |err| switch (err) { + error.WriteFailed => return cache_file_writer.err.?, + else => |e| return e, + }; + if (timer.finish()) |ns_astgen| { comp.mutex.lockUncancelable(io); defer comp.mutex.unlock(io); @@ -4524,12 +4525,14 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru .stage2_llvm, => {}, }, + error.Canceled => |e| return e, } return error.AlreadyReported; }; } fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ OutOfMemory, + Canceled, CodegenFail, NoLinkFile, BackendDoesNotProduceMir, @@ -4555,13 +4558,16 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e null; defer if (liveness) |*l| l.deinit(gpa); - if (build_options.enable_debug_extensions and comp.verbose_air) { + if (build_options.enable_debug_extensions and comp.verbose_air) p: { const io = comp.io; const stderr = try io.lockStderrWriter(&.{}); defer io.unlockStderrWriter(); - stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {}; - air.write(stderr, pt, liveness); - stderr.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}) catch {}; + printVerboseAir(pt, liveness, fqn, air, &stderr.interface) catch |err| switch (err) { + error.WriteFailed => switch (stderr.err.?) { + error.Canceled => |e| return e, + else => break :p, + }, + }; } if (std.debug.runtime_safety) verify_liveness: { @@ -4576,7 +4582,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e verify.verify() catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, - else => return zcu.codegenFail(nav, "invalid liveness: {s}", .{@errorName(err)}), + else => return zcu.codegenFail(nav, "invalid liveness: {t}", .{err}), }; } @@ -4612,3 +4618,17 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e => return zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)}), }; } + +fn printVerboseAir( + pt: Zcu.PerThread, + liveness: ?Air.Liveness, + fqn: InternPool.NullTerminatedString, + air: *const Air, + w: *Io.Writer, +) Io.Writer.Error!void { + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + try w.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}); + try air.write(w, pt, liveness); + try w.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}); +} diff --git a/src/fmt.zig b/src/fmt.zig index b9b1cc1363..ca6885d24e 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZirErrorMessages(zir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, color); + error_bundle.renderToStderr(io, .{}, color) catch {}; process.exit(2); } } else { @@ -138,12 +138,12 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZoirErrorMessages(zoir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, color); + error_bundle.renderToStderr(io, .{}, color) catch {}; process.exit(2); } } } else if (tree.errors.len != 0) { - try std.zig.printAstErrorsToStderr(gpa, tree, "", color); + std.zig.printAstErrorsToStderr(gpa, io, tree, "", color) catch {}; process.exit(2); } const formatted = try tree.renderAlloc(gpa); @@ -298,7 +298,7 @@ fn fmtPathFile( defer tree.deinit(gpa); if (tree.errors.len != 0) { - try std.zig.printAstErrorsToStderr(gpa, tree, file_path, fmt.color); + try std.zig.printAstErrorsToStderr(gpa, io, tree, file_path, fmt.color); fmt.any_error = true; return; } @@ -319,7 +319,7 @@ fn fmtPathFile( try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, fmt.color); + try error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, @@ -334,7 +334,7 @@ fn fmtPathFile( try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, fmt.color); + try error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index ee638718b7..44676007e2 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -401,8 +401,8 @@ pub const BuiltSharedObjects = struct { lock: Cache.Lock, dir_path: Path, - pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator) void { - self.lock.release(); + pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator, io: Io) void { + self.lock.release(io); gpa.free(self.dir_path.sub_path); self.* = undefined; } diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index de86413cfd..8371b3288d 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -640,8 +640,8 @@ pub const BuiltSharedObjects = struct { lock: Cache.Lock, dir_path: Path, - pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator) void { - self.lock.release(); + pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator, io: Io) void { + self.lock.release(io); gpa.free(self.dir_path.sub_path); self.* = undefined; } diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index 33dd62d851..9c09c35b0a 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -346,8 +346,8 @@ pub const BuiltSharedObjects = struct { lock: Cache.Lock, dir_path: Path, - pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator) void { - self.lock.release(); + pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator, io: Io) void { + self.lock.release(io); gpa.free(self.dir_path.sub_path); self.* = undefined; } diff --git a/src/link.zig b/src/link.zig index a4729f296c..3b822b2e69 100644 --- a/src/link.zig +++ b/src/link.zig @@ -2246,13 +2246,12 @@ fn resolvePathInputLib( var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStderr(io, .{}, color); - + error_bundle.renderToStderr(io, .{}, color) catch {}; std.process.exit(1); } var ld_script = ld_script_result catch |err| - fatal("{f}: failed to parse linker script: {s}", .{ test_path, @errorName(err) }); + fatal("{f}: failed to parse linker script: {t}", .{ test_path, err }); defer ld_script.deinit(gpa); try unresolved_inputs.ensureUnusedCapacity(gpa, ld_script.args.len); diff --git a/src/main.zig b/src/main.zig index 56a014bb92..c5ed278921 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4598,6 +4598,8 @@ const UpdateModuleError = Compilation.UpdateError || error{ /// The update caused compile errors. The error bundle has already been /// reported to the user by being rendered to stderr. CompileErrorsReported, + /// Error occurred printing compilation errors to stderr. + PrintingErrorsFailed, }; fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) UpdateModuleError!void { try comp.update(prog_node); @@ -4607,7 +4609,10 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) if (errors.errorMessageCount() > 0) { const io = comp.io; - try errors.renderToStderr(io, .{}, color); + errors.renderToStderr(io, .{}, color) catch |err| switch (err) { + error.Canceled => |e| return e, + else => return error.PrintingErrorsFailed, + }; return error.CompileErrorsReported; } } -- cgit v1.2.3 From 608145c2f07d90c46cdaa8bc2013f31b965a5b8b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Dec 2025 17:00:41 -0800 Subject: fix more fallout from locking stderr --- lib/compiler/aro/aro/Diagnostics.zig | 28 ++- lib/compiler/build_runner.zig | 338 +++++++++++++++++------------------ lib/compiler/resinator/cli.zig | 10 +- lib/compiler/resinator/errors.zig | 6 +- lib/compiler/resinator/main.zig | 31 ++-- lib/compiler/test_runner.zig | 8 +- lib/std/Build.zig | 73 ++++---- lib/std/Build/Fuzz.zig | 18 +- lib/std/Build/Step.zig | 9 +- lib/std/Build/Step/Compile.zig | 17 +- lib/std/Build/Step/Run.zig | 22 +-- lib/std/Io.zig | 2 +- lib/std/Io/File/Writer.zig | 2 +- lib/std/Io/Terminal.zig | 22 --- lib/std/Io/Threaded.zig | 6 +- lib/std/debug.zig | 24 +-- lib/std/debug/simple_panic.zig | 6 +- lib/std/json/dynamic.zig | 6 +- lib/std/log.zig | 2 +- lib/std/process.zig | 2 +- lib/std/testing.zig | 21 +-- lib/std/zig.zig | 21 +-- lib/std/zig/ErrorBundle.zig | 72 ++++---- lib/std/zig/parser_test.zig | 16 +- src/Air/print.zig | 12 +- src/Compilation.zig | 45 +++-- src/InternPool.zig | 10 +- src/Zcu/PerThread.zig | 8 +- src/codegen/aarch64/Select.zig | 7 +- src/crash_report.zig | 6 +- src/libs/mingw.zig | 24 +-- src/libs/mingw/def.zig | 6 +- src/link/Coff.zig | 6 +- src/link/Elf2.zig | 6 +- src/main.zig | 12 +- 35 files changed, 446 insertions(+), 458 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index bebcf4e3d2..b33efa3f85 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -24,20 +24,21 @@ pub const Message = struct { @"fatal error", }; - pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.File.Writer.Mode, details: bool) std.Io.tty.Config.SetColorError!void { - try config.setColor(w, .bold); + pub fn write(msg: Message, t: std.Io.Terminal, details: bool) std.Io.Terminal.SetColorError!void { + const w = t.writer; + try t.setColor(.bold); if (msg.location) |loc| { try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col }); } switch (msg.effective_kind) { - .@"fatal error", .@"error" => try config.setColor(w, .bright_red), - .note => try config.setColor(w, .bright_cyan), - .warning => try config.setColor(w, .bright_magenta), + .@"fatal error", .@"error" => try t.setColor(.bright_red), + .note => try t.setColor(.bright_cyan), + .warning => try t.setColor(.bright_magenta), .off => unreachable, } try w.print("{s}: ", .{@tagName(msg.effective_kind)}); - try config.setColor(w, .white); + try t.setColor(.white); try w.writeAll(msg.text); if (msg.opt) |some| { if (msg.effective_kind == .@"error" and msg.kind != .@"error") { @@ -55,17 +56,17 @@ pub const Message = struct { if (!details or msg.location == null) { try w.writeAll("\n"); - try config.setColor(w, .reset); + try t.setColor(.reset); } else { const loc = msg.location.?; const trailer = if (loc.end_with_splice) "\\ " else ""; - try config.setColor(w, .reset); + try t.setColor(.reset); try w.print("\n{s}{s}\n", .{ loc.line, trailer }); try w.splatByteAll(' ', loc.width); - try config.setColor(w, .bold); - try config.setColor(w, .bright_green); + try t.setColor(.bold); + try t.setColor(.bright_green); try w.writeAll("^\n"); - try config.setColor(w, .reset); + try t.setColor(.reset); } try w.flush(); } @@ -290,10 +291,7 @@ pub const State = struct { const Diagnostics = @This(); output: union(enum) { - to_writer: struct { - writer: *std.Io.Writer, - color: std.Io.File.Writer.Mode, - }, + to_writer: std.Io.Terminal, to_list: struct { messages: std.ArrayList(Message) = .empty, arena: std.heap.ArenaAllocator, diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index d284d85747..1c30ecaadc 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -286,8 +286,8 @@ pub fn main() !void { const next_arg = nextArg(args, &arg_idx) orelse fatalWithHint("expected u16 after '{s}'", .{arg}); debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| { - fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {s}\n", .{ - next_arg, @errorName(err), + fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {t}\n", .{ + next_arg, err, }); }; } else if (mem.eql(u8, arg, "--webui")) { @@ -429,6 +429,12 @@ pub fn main() !void { } } + graph.stderr_mode = switch (color) { + .auto => try .detect(io, .stderr()), + .on => .escape_codes, + .off => .no_color, + }; + if (webui_listen != null) { if (watch) fatal("using '--webui' and '--watch' together is not yet supported; consider omitting '--watch' in favour of the web UI \"Rebuild\" button", .{}); if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{}); @@ -522,7 +528,7 @@ pub fn main() !void { // Perhaps in the future there could be an Advanced Options flag // such as --debug-build-runner-leaks which would make this code // return instead of calling exit. - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; process.exit(1); }, else => |e| return e, @@ -554,9 +560,9 @@ pub fn main() !void { } rebuild: while (true) : (if (run.error_style.clearOnUpdate()) { - const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); - defer io.unlockStderrWriter(); - try stderr.writeAllUnescaped("\x1B[2J\x1B[3J\x1B[H"); + const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode); + defer io.unlockStderr(); + try stderr.file_writer.interface.writeAll("\x1B[2J\x1B[3J\x1B[H"); }) { if (run.web_server) |*ws| ws.startBuild(); @@ -730,7 +736,8 @@ fn runStepNames( fuzz: ?std.Build.Fuzz.Mode, ) !void { const gpa = run.gpa; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const step_stack = &run.step_stack; { @@ -856,20 +863,19 @@ fn runStepNames( .none => break :summary, } - const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); - defer io.unlockStderrWriter(); - - const w = &stderr.interface; - const fwm = stderr.mode; + const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode); + defer io.unlockStderr(); + const t = stderr.terminal(); + const w = &stderr.file_writer.interface; const total_count = success_count + failure_count + pending_count + skipped_count; - fwm.setColor(w, .cyan) catch {}; - fwm.setColor(w, .bold) catch {}; + t.setColor(.cyan) catch {}; + t.setColor(.bold) catch {}; w.writeAll("Build Summary: ") catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; w.print("{d}/{d} steps succeeded", .{ success_count, total_count }) catch {}; { - fwm.setColor(w, .dim) catch {}; + t.setColor(.dim) catch {}; var first = true; if (skipped_count > 0) { w.print("{s}{d} skipped", .{ if (first) " (" else ", ", skipped_count }) catch {}; @@ -880,12 +886,12 @@ fn runStepNames( first = false; } if (!first) w.writeByte(')') catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } if (test_count > 0) { w.print("; {d}/{d} tests passed", .{ test_pass_count, test_count }) catch {}; - fwm.setColor(w, .dim) catch {}; + t.setColor(.dim) catch {}; var first = true; if (test_skip_count > 0) { w.print("{s}{d} skipped", .{ if (first) " (" else ", ", test_skip_count }) catch {}; @@ -904,7 +910,7 @@ fn runStepNames( first = false; } if (!first) w.writeByte(')') catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } w.writeAll("\n") catch {}; @@ -918,7 +924,7 @@ fn runStepNames( var print_node: PrintNode = .{ .parent = null }; if (step_names.len == 0) { print_node.last = true; - printTreeStep(b, b.default_step, run, w, fwm, &print_node, &step_stack_copy) catch {}; + printTreeStep(b, b.default_step, run, t, &print_node, &step_stack_copy) catch {}; } else { const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: { var i: usize = step_names.len; @@ -937,7 +943,7 @@ fn runStepNames( for (step_names, 0..) |step_name, i| { const tls = b.top_level_steps.get(step_name).?; print_node.last = i + 1 == last_index; - printTreeStep(b, &tls.step, run, w, fwm, &print_node, &step_stack_copy) catch {}; + printTreeStep(b, &tls.step, run, t, &print_node, &step_stack_copy) catch {}; } } w.writeByte('\n') catch {}; @@ -954,7 +960,7 @@ fn runStepNames( if (run.error_style.verboseContext()) break :code 1; // failure; print build command break :code 2; // failure; do not print build command }; - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; process.exit(code); } @@ -963,33 +969,30 @@ const PrintNode = struct { last: bool = false, }; -fn printPrefix(node: *PrintNode, w: *Writer, fwm: File.Writer.Mode) !void { +fn printPrefix(node: *PrintNode, stderr: Io.Terminal) !void { const parent = node.parent orelse return; + const writer = stderr.writer; if (parent.parent == null) return; - try printPrefix(parent, w, fwm); + try printPrefix(parent, stderr); if (parent.last) { - try w.writeAll(" "); + try writer.writeAll(" "); } else { - try w.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │ + try writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │ else => "| ", }); } } -fn printChildNodePrefix(w: *Writer, fwm: File.Writer.Mode) !void { - try w.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ +fn printChildNodePrefix(stderr: Io.Terminal) !void { + try stderr.writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ else => "+- ", }); } -fn printStepStatus( - s: *Step, - stderr: *Writer, - fwm: File.Writer.Mode, - run: *const Run, -) !void { +fn printStepStatus(s: *Step, stderr: Io.Terminal, run: *const Run) !void { + const writer = stderr.writer; switch (s.state) { .precheck_unstarted => unreachable, .precheck_started => unreachable, @@ -997,139 +1000,135 @@ fn printStepStatus( .running => unreachable, .dependency_failure => { - try fwm.setColor(stderr, .dim); - try stderr.writeAll(" transitive failure\n"); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.dim); + try writer.writeAll(" transitive failure\n"); + try stderr.setColor(.reset); }, .success => { - try fwm.setColor(stderr, .green); + try stderr.setColor(.green); if (s.result_cached) { - try stderr.writeAll(" cached"); + try writer.writeAll(" cached"); } else if (s.test_results.test_count > 0) { const pass_count = s.test_results.passCount(); assert(s.test_results.test_count == pass_count + s.test_results.skip_count); - try stderr.print(" {d} pass", .{pass_count}); + try writer.print(" {d} pass", .{pass_count}); if (s.test_results.skip_count > 0) { - try fwm.setColor(stderr, .reset); - try stderr.writeAll(", "); - try fwm.setColor(stderr, .yellow); - try stderr.print("{d} skip", .{s.test_results.skip_count}); + try stderr.setColor(.reset); + try writer.writeAll(", "); + try stderr.setColor(.yellow); + try writer.print("{d} skip", .{s.test_results.skip_count}); } - try fwm.setColor(stderr, .reset); - try stderr.print(" ({d} total)", .{s.test_results.test_count}); + try stderr.setColor(.reset); + try writer.print(" ({d} total)", .{s.test_results.test_count}); } else { - try stderr.writeAll(" success"); + try writer.writeAll(" success"); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); if (s.result_duration_ns) |ns| { - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); if (ns >= std.time.ns_per_min) { - try stderr.print(" {d}m", .{ns / std.time.ns_per_min}); + try writer.print(" {d}m", .{ns / std.time.ns_per_min}); } else if (ns >= std.time.ns_per_s) { - try stderr.print(" {d}s", .{ns / std.time.ns_per_s}); + try writer.print(" {d}s", .{ns / std.time.ns_per_s}); } else if (ns >= std.time.ns_per_ms) { - try stderr.print(" {d}ms", .{ns / std.time.ns_per_ms}); + try writer.print(" {d}ms", .{ns / std.time.ns_per_ms}); } else if (ns >= std.time.ns_per_us) { - try stderr.print(" {d}us", .{ns / std.time.ns_per_us}); + try writer.print(" {d}us", .{ns / std.time.ns_per_us}); } else { - try stderr.print(" {d}ns", .{ns}); + try writer.print(" {d}ns", .{ns}); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } if (s.result_peak_rss != 0) { const rss = s.result_peak_rss; - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); if (rss >= 1000_000_000) { - try stderr.print(" MaxRSS:{d}G", .{rss / 1000_000_000}); + try writer.print(" MaxRSS:{d}G", .{rss / 1000_000_000}); } else if (rss >= 1000_000) { - try stderr.print(" MaxRSS:{d}M", .{rss / 1000_000}); + try writer.print(" MaxRSS:{d}M", .{rss / 1000_000}); } else if (rss >= 1000) { - try stderr.print(" MaxRSS:{d}K", .{rss / 1000}); + try writer.print(" MaxRSS:{d}K", .{rss / 1000}); } else { - try stderr.print(" MaxRSS:{d}B", .{rss}); + try writer.print(" MaxRSS:{d}B", .{rss}); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } - try stderr.writeAll("\n"); + try writer.writeAll("\n"); }, .skipped, .skipped_oom => |skip| { - try fwm.setColor(stderr, .yellow); - try stderr.writeAll(" skipped"); + try stderr.setColor(.yellow); + try writer.writeAll(" skipped"); if (skip == .skipped_oom) { - try stderr.writeAll(" (not enough memory)"); - try fwm.setColor(stderr, .dim); - try stderr.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss }); - try fwm.setColor(stderr, .yellow); + try writer.writeAll(" (not enough memory)"); + try stderr.setColor(.dim); + try writer.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss }); + try stderr.setColor(.yellow); } - try stderr.writeAll("\n"); - try fwm.setColor(stderr, .reset); + try writer.writeAll("\n"); + try stderr.setColor(.reset); }, .failure => { - try printStepFailure(s, stderr, fwm, false); - try fwm.setColor(stderr, .reset); + try printStepFailure(s, stderr, false); + try stderr.setColor(.reset); }, } } -fn printStepFailure( - s: *Step, - stderr: *Writer, - fwm: File.Writer.Mode, - dim: bool, -) !void { +fn printStepFailure(s: *Step, stderr: Io.Terminal, dim: bool) !void { + const w = stderr.writer; if (s.result_error_bundle.errorMessageCount() > 0) { - try fwm.setColor(stderr, .red); - try stderr.print(" {d} errors\n", .{ + try stderr.setColor(.red); + try w.print(" {d} errors\n", .{ s.result_error_bundle.errorMessageCount(), }); } else if (!s.test_results.isSuccess()) { // These first values include all of the test "statuses". Every test is either passsed, // skipped, failed, crashed, or timed out. - try fwm.setColor(stderr, .green); - try stderr.print(" {d} pass", .{s.test_results.passCount()}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try stderr.setColor(.green); + try w.print(" {d} pass", .{s.test_results.passCount()}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); if (s.test_results.skip_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .yellow); - try stderr.print("{d} skip", .{s.test_results.skip_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.yellow); + try w.print("{d} skip", .{s.test_results.skip_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.fail_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} fail", .{s.test_results.fail_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} fail", .{s.test_results.fail_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.crash_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} crash", .{s.test_results.crash_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} crash", .{s.test_results.crash_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.timeout_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} timeout", .{s.test_results.timeout_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} timeout", .{s.test_results.timeout_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } - try stderr.print(" ({d} total)", .{s.test_results.test_count}); + try w.print(" ({d} total)", .{s.test_results.test_count}); // Memory leaks are intentionally written after the total, because is isn't a test *status*, // but just a flag that any tests -- even passed ones -- can have. We also use a different // separator, so it looks like: // 2 pass, 1 skip, 2 fail (5 total); 2 leaks if (s.test_results.leak_count > 0) { - try stderr.writeAll("; "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} leaks", .{s.test_results.leak_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll("; "); + try stderr.setColor(.red); + try w.print("{d} leaks", .{s.test_results.leak_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } // It's usually not helpful to know how many error logs there were because they tend to @@ -1142,21 +1141,21 @@ fn printStepFailure( break :show alt_results.isSuccess(); }; if (show_err_logs) { - try stderr.writeAll("; "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} error logs", .{s.test_results.log_err_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll("; "); + try stderr.setColor(.red); + try w.print("{d} error logs", .{s.test_results.log_err_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } - try stderr.writeAll("\n"); + try w.writeAll("\n"); } else if (s.result_error_msgs.items.len > 0) { - try fwm.setColor(stderr, .red); - try stderr.writeAll(" failure\n"); + try stderr.setColor(.red); + try w.writeAll(" failure\n"); } else { assert(s.result_stderr.len > 0); - try fwm.setColor(stderr, .red); - try stderr.writeAll(" stderr\n"); + try stderr.setColor(.red); + try w.writeAll(" w\n"); } } @@ -1164,11 +1163,11 @@ fn printTreeStep( b: *std.Build, s: *Step, run: *const Run, - stderr: *Writer, - fwm: File.Writer.Mode, + stderr: Io.Terminal, parent_node: *PrintNode, step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), ) !void { + const writer = stderr.writer; const first = step_stack.swapRemove(s); const summary = run.summary; const skip = switch (summary) { @@ -1178,26 +1177,26 @@ fn printTreeStep( .failures => s.state == .success, }; if (skip) return; - try printPrefix(parent_node, stderr, fwm); + try printPrefix(parent_node, stderr); if (parent_node.parent != null) { if (parent_node.last) { - try printChildNodePrefix(stderr, fwm); + try printChildNodePrefix(stderr); } else { - try stderr.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─ + try writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─ else => "+- ", }); } } - if (!first) try fwm.setColor(stderr, .dim); + if (!first) try stderr.setColor(.dim); // dep_prefix omitted here because it is redundant with the tree. - try stderr.writeAll(s.name); + try writer.writeAll(s.name); if (first) { - try printStepStatus(s, stderr, fwm, run); + try printStepStatus(s, stderr, run); const last_index = if (summary == .all) s.dependencies.items.len -| 1 else blk: { var i: usize = s.dependencies.items.len; @@ -1219,17 +1218,17 @@ fn printTreeStep( .parent = parent_node, .last = i == last_index, }; - try printTreeStep(b, dep, run, stderr, fwm, &print_node, step_stack); + try printTreeStep(b, dep, run, stderr, &print_node, step_stack); } } else { if (s.dependencies.items.len == 0) { - try stderr.writeAll(" (reused)\n"); + try writer.writeAll(" (reused)\n"); } else { - try stderr.print(" (+{d} more reused dependencies)\n", .{ + try writer.print(" (+{d} more reused dependencies)\n", .{ s.dependencies.items.len, }); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } } @@ -1300,7 +1299,8 @@ fn workerMakeOneStep( prog_node: std.Progress.Node, run: *Run, ) void { - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const gpa = run.gpa; // First, check the conditions for running this step. If they are not met, @@ -1369,11 +1369,11 @@ fn workerMakeOneStep( const show_error_msgs = s.result_error_msgs.items.len > 0; const show_stderr = s.result_stderr.len > 0; if (show_error_msgs or show_compile_errors or show_stderr) { - const stderr = io.lockStderrWriter(&stdio_buffer_allocation) catch |err| switch (err) { + const stderr = io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode) catch |err| switch (err) { error.Canceled => return, }; - defer io.unlockStderrWriter(); - printErrorMessages(gpa, s, .{}, &stderr.interface, stderr.mode, run.error_style, run.multiline_errors) catch {}; + defer io.unlockStderr(); + printErrorMessages(gpa, s, .{}, stderr.terminal(), run.error_style, run.multiline_errors) catch {}; } handle_result: { @@ -1440,11 +1440,11 @@ pub fn printErrorMessages( gpa: Allocator, failing_step: *Step, options: std.zig.ErrorBundle.RenderOptions, - stderr: *Writer, - fwm: File.Writer.Mode, + stderr: Io.Terminal, error_style: ErrorStyle, multiline_errors: MultilineErrors, ) !void { + const writer = stderr.writer; if (error_style.verboseContext()) { // Provide context for where these error messages are coming from by // printing the corresponding Step subtree. @@ -1456,70 +1456,70 @@ pub fn printErrorMessages( } // Now, `step_stack` has the subtree that we want to print, in reverse order. - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); var indent: usize = 0; while (step_stack.pop()) |s| : (indent += 1) { if (indent > 0) { - try stderr.splatByteAll(' ', (indent - 1) * 3); - try printChildNodePrefix(stderr, fwm); + try writer.splatByteAll(' ', (indent - 1) * 3); + try printChildNodePrefix(stderr); } - try stderr.writeAll(s.name); + try writer.writeAll(s.name); if (s == failing_step) { - try printStepFailure(s, stderr, fwm, true); + try printStepFailure(s, stderr, true); } else { - try stderr.writeAll("\n"); + try writer.writeAll("\n"); } } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } else { // Just print the failing step itself. - try fwm.setColor(stderr, .dim); - try stderr.writeAll(failing_step.name); - try printStepFailure(failing_step, stderr, fwm, true); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.dim); + try writer.writeAll(failing_step.name); + try printStepFailure(failing_step, stderr, true); + try stderr.setColor(.reset); } if (failing_step.result_stderr.len > 0) { - try stderr.writeAll(failing_step.result_stderr); + try writer.writeAll(failing_step.result_stderr); if (!mem.endsWith(u8, failing_step.result_stderr, "\n")) { - try stderr.writeAll("\n"); + try writer.writeAll("\n"); } } - try failing_step.result_error_bundle.renderToWriter(options, stderr, fwm); + try failing_step.result_error_bundle.renderToTerminal(options, stderr); for (failing_step.result_error_msgs.items) |msg| { - try fwm.setColor(stderr, .red); - try stderr.writeAll("error:"); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.red); + try writer.writeAll("error:"); + try stderr.setColor(.reset); if (std.mem.indexOfScalar(u8, msg, '\n') == null) { - try stderr.print(" {s}\n", .{msg}); + try writer.print(" {s}\n", .{msg}); } else switch (multiline_errors) { .indent => { var it = std.mem.splitScalar(u8, msg, '\n'); - try stderr.print(" {s}\n", .{it.first()}); + try writer.print(" {s}\n", .{it.first()}); while (it.next()) |line| { - try stderr.print(" {s}\n", .{line}); + try writer.print(" {s}\n", .{line}); } }, - .newline => try stderr.print("\n{s}\n", .{msg}), - .none => try stderr.print(" {s}\n", .{msg}), + .newline => try writer.print("\n{s}\n", .{msg}), + .none => try writer.print(" {s}\n", .{msg}), } } if (error_style.verboseContext()) { if (failing_step.result_failed_command) |cmd_str| { - try fwm.setColor(stderr, .red); - try stderr.writeAll("failed command: "); - try fwm.setColor(stderr, .reset); - try stderr.writeAll(cmd_str); - try stderr.writeByte('\n'); + try stderr.setColor(.red); + try writer.writeAll("failed command: "); + try stderr.setColor(.reset); + try writer.writeAll(cmd_str); + try writer.writeByte('\n'); } } - try stderr.writeByte('\n'); + try writer.writeByte('\n'); } fn printSteps(builder: *std.Build, w: *Writer) !void { diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index 08befbe1fa..ddf3ca18b7 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -126,14 +126,14 @@ pub const Diagnostics = struct { } pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) void { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - self.renderToWriter(args, &stderr.interface, stderr.mode) catch return; + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); + self.renderToWriter(args, stderr.terminal()) catch return; } - pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void { + pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, t: Io.Terminal) !void { for (self.errors.items) |err_details| { - try renderErrorMessage(writer, config, err_details, args); + try renderErrorMessage(t, err_details, args); } } diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 031b5d3574..6146f777cd 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -69,10 +69,10 @@ pub const Diagnostics = struct { pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { const io = self.io; - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); for (self.errors.items) |err_details| { - renderErrorMessage(io, &stderr.interface, stderr.mode, cwd, err_details, source, self.strings.items, source_mappings) catch return; + renderErrorMessage(io, stderr.terminal(), cwd, err_details, source, self.strings.items, source_mappings) catch return; } } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index bd2fcc912e..81a3a8689a 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -35,8 +35,8 @@ pub fn main() !void { const args = try std.process.argsAlloc(arena); if (args.len < 2) { - const stderr = io.lockStderrWriter(&.{}); - try renderErrorMessage(&stderr.interface, stderr.mode, .err, "expected zig lib dir as first argument", .{}); + const stderr = try io.lockStderr(&.{}, null); + try renderErrorMessage(stderr.terminal(), .err, "expected zig lib dir as first argument", .{}); std.process.exit(1); } const zig_lib_dir = args[1]; @@ -80,9 +80,9 @@ pub fn main() !void { // so that there is a clear separation between the cli diagnostics and whatever // gets printed after if (cli_diagnostics.errors.items.len > 0) { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try stderr.interface.writeByte('\n'); + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try stderr.file_writer.interface.writeByte('\n'); } } break :options options; @@ -130,15 +130,12 @@ pub fn main() !void { var stderr_buf: [512]u8 = undefined; var diagnostics: aro.Diagnostics = .{ .output = output: { if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } }; - const stderr = io.lockStderrWriter(&stderr_buf); - break :output .{ .to_writer = .{ - .writer = &stderr.interface, - .color = stderr.mode, - } }; + const stderr = try io.lockStderr(&stderr_buf, null); + break :output .{ .to_writer = stderr.terminal() }; } }; defer { diagnostics.deinit(); - if (!zig_integration) std.debug.unlockStderrWriter(); + if (!zig_integration) std.debug.unlockStderr(); } var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd()); @@ -699,9 +696,9 @@ const ErrorHandler = union(enum) { }, .stderr => { // aro errors have already been emitted - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try renderErrorMessage(&stderr.interface, stderr.mode, .err, "{s}", .{fail_msg}); + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try renderErrorMessage(stderr.terminal(), .err, "{s}", .{fail_msg}); }, } } @@ -745,9 +742,9 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, .stderr => { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try renderErrorMessage(&stderr.interface, stderr.mode, msg_type, format, args); + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try renderErrorMessage(stderr.terminal(), msg_type, format, args); }, } } diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 3a135ab8fd..3d97944a7f 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -405,18 +405,18 @@ pub fn fuzz( testOne(ctx, input.toSlice()) catch |err| switch (err) { error.SkipZigTest => return, else => { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderr(&.{}, null).terminal(); p: { if (@errorReturnTrace()) |trace| { - std.debug.writeStackTrace(trace, &stderr.interface, stderr.mode) catch break :p; + std.debug.writeStackTrace(trace, stderr) catch break :p; } - stderr.interface.print("failed with error.{t}\n", .{err}) catch break :p; + stderr.writer.print("failed with error.{t}\n", .{err}) catch break :p; } std.process.exit(1); }, }; if (log_err_count != 0) { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderr(&.{}, .no_color); stderr.interface.print("error logs detected\n", .{}) catch {}; std.process.exit(1); } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index de2985d2b5..cf0b9e5b0d 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -129,6 +129,9 @@ pub const Graph = struct { dependency_cache: InitializedDepMap = .empty, allow_so_scripts: ?bool = null, time_report: bool, + /// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also + /// respects the '--color' flag. + stderr_mode: ?Io.Terminal.Mode = null, }; const AvailableDeps = []const struct { []const u8, []const u8 }; @@ -2255,9 +2258,10 @@ pub const GeneratedFile = struct { pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 { return gen.path orelse { - const io = gen.step.owner.graph.io; - const stderr = try io.lockStderrWriter(&.{}); - dumpBadGetPathHelp(gen.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; + const graph = gen.step.owner.graph; + const io = graph.io; + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + dumpBadGetPathHelp(gen.step, stderr.terminal(), src_builder, asking_step) catch {}; @panic("misconfigured build script"); }; } @@ -2468,13 +2472,15 @@ pub const LazyPath = union(enum) { // TODO make gen.file.path not be absolute and use that as the // basis for not traversing up too many directories. + const graph = src_builder.graph; + var file_path: Cache.Path = .{ .root_dir = Cache.Directory.cwd(), .sub_path = gen.file.path orelse { - const io = src_builder.graph.io; - const stderr = try io.lockStderrWriter(&.{}); - dumpBadGetPathHelp(gen.file.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - io.unlockStderrWriter(); + const io = graph.io; + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + dumpBadGetPathHelp(gen.file.step, stderr.terminal(), src_builder, asking_step) catch {}; + io.unlockStderr(); @panic("misconfigured build script"); }, }; @@ -2564,43 +2570,36 @@ fn dumpBadDirnameHelp( comptime msg: []const u8, args: anytype, ) anyerror!void { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - - const w = &stderr.interface; - const fwm = stderr.mode; + const stderr = std.debug.lockStderr(&.{}).terminal(); + defer std.debug.unlockStderr(); + const w = stderr.writer; try w.print(msg, args); if (fail_step) |s| { - fwm.setColor(w, .red) catch {}; + stderr.setColor(.red) catch {}; try w.writeAll(" The step was created by this stack trace:\n"); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.reset) catch {}; - s.dump(w, fwm); + s.dump(stderr); } if (asking_step) |as| { - fwm.setColor(w, .red) catch {}; + stderr.setColor(.red) catch {}; try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.reset) catch {}; - as.dump(w, fwm); + as.dump(stderr); } - fwm.setColor(w, .red) catch {}; - try w.writeAll(" Hope that helps. Proceeding to panic.\n"); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.red) catch {}; + try w.writeAll(" Proceeding to panic.\n"); + stderr.setColor(.reset) catch {}; } /// In this function the stderr mutex has already been locked. -pub fn dumpBadGetPathHelp( - s: *Step, - w: *Io.Writer, - fwm: File.Writer.Mode, - src_builder: *Build, - asking_step: ?*Step, -) anyerror!void { +pub fn dumpBadGetPathHelp(s: *Step, t: Io.Terminal, src_builder: *Build, asking_step: ?*Step) anyerror!void { + const w = t.writer; try w.print( \\getPath() was called on a GeneratedFile that wasn't built yet. \\ source package path: {s} @@ -2611,21 +2610,21 @@ pub fn dumpBadGetPathHelp( s.name, }); - fwm.setColor(w, .red) catch {}; + t.setColor(.red) catch {}; try w.writeAll(" The step was created by this stack trace:\n"); - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; - s.dump(w, fwm); + s.dump(t); if (asking_step) |as| { - fwm.setColor(w, .red) catch {}; + t.setColor(.red) catch {}; try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; - as.dump(w, fwm); + as.dump(t); } - fwm.setColor(w, .red) catch {}; - try w.writeAll(" Hope that helps. Proceeding to panic.\n"); - fwm.setColor(w, .reset) catch {}; + t.setColor(.red) catch {}; + try w.writeAll(" Proceeding to panic.\n"); + t.setColor(.reset) catch {}; } pub const InstallDir = union(enum) { diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index 4770e03a0c..d308efdf70 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -158,7 +158,8 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, parent_prog_node: std.P } fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_node: std.Progress.Node) !void { - const io = run.step.owner.graph.io; + const graph = run.step.owner.graph; + const io = graph.io; const compile = run.producer.?; const prog_node = parent_prog_node.start(compile.step.name, 0); defer prog_node.end(); @@ -171,9 +172,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod if (show_error_msgs or show_compile_errors or show_stderr) { var buf: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buf); - defer io.unlockStderrWriter(); - build_runner.printErrorMessages(gpa, &compile.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; + const stderr = try io.lockStderr(&buf, graph.stderr_mode); + defer io.unlockStderr(); + build_runner.printErrorMessages(gpa, &compile.step, .{}, stderr.terminal(), .verbose, .indent) catch {}; } const rebuilt_bin_path = result catch |err| switch (err) { @@ -186,7 +187,8 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { const owner = run.step.owner; const gpa = owner.allocator; - const io = owner.graph.io; + const graph = owner.graph; + const io = graph.io; const test_name = run.cached_test_metadata.?.testName(unit_test_index); const prog_node = fuzz.prog_node.start(test_name, 0); @@ -195,11 +197,11 @@ fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) { error.MakeFailed => { var buf: [256]u8 = undefined; - const stderr = io.lockStderrWriter(&buf) catch |e| switch (e) { + const stderr = io.lockStderr(&buf, graph.stderr_mode) catch |e| switch (e) { error.Canceled => return, }; - defer io.unlockStderrWriter(); - build_runner.printErrorMessages(gpa, &run.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; + defer io.unlockStderr(); + build_runner.printErrorMessages(gpa, &run.step, .{}, stderr.terminal(), .verbose, .indent) catch {}; return; }, else => { diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 0df58b24b7..74b41634a7 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -328,16 +328,17 @@ pub fn cast(step: *Step, comptime T: type) ?*T { } /// For debugging purposes, prints identifying information about this Step. -pub fn dump(step: *Step, w: *Io.Writer, fwm: Io.File.Writer.Mode) void { +pub fn dump(step: *Step, t: Io.Terminal) void { + const w = t.writer; if (step.debug_stack_trace.instruction_addresses.len > 0) { w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {}; - std.debug.writeStackTrace(&step.debug_stack_trace, w, fwm) catch {}; + std.debug.writeStackTrace(&step.debug_stack_trace, t) catch {}; } else { const field = "debug_stack_frames_count"; comptime assert(@hasField(Build, field)); - fwm.setColor(w, .yellow) catch {}; + t.setColor(.yellow) catch {}; w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } } diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 888775884d..4752046089 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -925,20 +925,21 @@ const CliNamedModules = struct { fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 { const step = &compile.step; const b = step.owner; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const maybe_path: ?*GeneratedFile = @field(compile, tag_name); const generated_file = maybe_path orelse { - const stderr = try io.lockStderrWriter(&.{}); - std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - io.unlockStderrWriter(); + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {}; + io.unlockStderr(); @panic("missing emit option for " ++ tag_name); }; const path = generated_file.path orelse { - const stderr = try io.lockStderrWriter(&.{}); - std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - io.unlockStderrWriter(); + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {}; + io.unlockStderr(); @panic(tag_name ++ " is null. Is there a missing step dependency?"); }; @@ -1907,7 +1908,7 @@ fn checkCompileErrors(compile: *Compile) !void { try actual_eb.renderToWriter(.{ .include_reference_trace = false, .include_source_line = false, - }, &aw.writer, .streaming); + }, &aw.writer); break :ae try aw.toOwnedSlice(); }; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 67cf201374..157a0292e7 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1559,7 +1559,8 @@ fn spawnChildAndCollect( ) !?EvalGenericResult { const b = run.step.owner; const arena = b.allocator; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; if (fuzz_context != null) { assert(!has_side_effects); @@ -1625,11 +1626,12 @@ fn spawnChildAndCollect( if (!run.disable_zig_progress and !inherit) { child.progress_node = options.progress_node; } - if (inherit) { - const stderr = try io.lockStderrWriter(&.{}); - try setColorEnvironmentVariables(run, env_map, stderr.mode); - } - defer if (inherit) io.unlockStderrWriter(); + const terminal_mode: Io.Terminal.Mode = if (inherit) m: { + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + break :m stderr.terminal_mode; + } else .no_color; + defer if (inherit) io.unlockStderr(); + try setColorEnvironmentVariables(run, env_map, terminal_mode); var timer = try std.time.Timer.start(); const res = try evalGeneric(run, &child); run.step.result_duration_ns = timer.read(); @@ -1637,7 +1639,7 @@ fn spawnChildAndCollect( } } -fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer.Mode) !void { +fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, terminal_mode: Io.Terminal.Mode) !void { color: switch (run.color) { .manual => {}, .enable => { @@ -1648,9 +1650,9 @@ fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer try env_map.put("NO_COLOR", "1"); env_map.remove("CLICOLOR_FORCE"); }, - .inherit => switch (fwm) { - .terminal_escaped => continue :color .enable, - else => continue :color .disable, + .inherit => switch (terminal_mode) { + .no_color, .windows_api => continue :color .disable, + .escape_codes => continue :color .enable, }, .auto => { const capture_stderr = run.captured_stderr != null or switch (run.stdio) { diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 6fa05b16d2..78049633a0 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -713,7 +713,7 @@ pub const VTable = struct { processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File, processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize, lockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!LockedStderr, - tryLockStderr: *const fn (?*anyopaque, buffer: []u8) Cancelable!?LockedStderr, + tryLockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!?LockedStderr, unlockStderr: *const fn (?*anyopaque) void, now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp, diff --git a/lib/std/Io/File/Writer.zig b/lib/std/Io/File/Writer.zig index 1d0494c674..56a1c09340 100644 --- a/lib/std/Io/File/Writer.zig +++ b/lib/std/Io/File/Writer.zig @@ -229,7 +229,7 @@ pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { .positional, .positional_simple => { w.pos = offset; }, - .streaming, .streaming_simple, .terminal_escaped, .terminal_winapi => { + .streaming, .streaming_simple => { if (w.seek_err) |err| return err; io.vtable.fileSeekTo(io.userdata, w.file, offset) catch |err| { w.seek_err = err; diff --git a/lib/std/Io/Terminal.zig b/lib/std/Io/Terminal.zig index cd0ec56caa..a39f2175d2 100644 --- a/lib/std/Io/Terminal.zig +++ b/lib/std/Io/Terminal.zig @@ -130,25 +130,3 @@ pub fn setColor(t: Terminal, color: Color) Io.Writer.Error!void { }, } } - -pub fn disableEscape(t: *Terminal) Mode { - const prev = t.mode; - t.mode = t.mode.toUnescaped(); - return prev; -} - -pub fn restoreEscape(t: *Terminal, mode: Mode) void { - t.mode = mode; -} - -pub fn writeAllUnescaped(t: *Terminal, bytes: []const u8) Io.Writer.Error!void { - const prev_mode = t.disableEscape(); - defer t.restoreEscape(prev_mode); - return t.interface.writeAll(bytes); -} - -pub fn printUnescaped(t: *Terminal, comptime fmt: []const u8, args: anytype) Io.Writer.Error!void { - const prev_mode = t.disableEscape(); - defer t.restoreEscape(prev_mode); - return t.interface.print(fmt, args); -} diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 3e7b6950d4..b07a9bb9a8 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -7178,7 +7178,7 @@ fn fileWriteFileStreaming( break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) }; }, .streaming => .{ null, limit.minInt(max_count) }, - .streaming_reading, .positional_reading => break :sf, + .streaming_simple, .positional_simple => break :sf, .failure => return error.ReadFailed, }; const current_thread = Thread.getCurrent(t); @@ -7251,7 +7251,7 @@ fn fileWriteFileStreaming( } var off_in: i64 = undefined; const off_in_ptr: ?*i64 = switch (file_reader.mode) { - .positional_reading, .streaming_reading => return error.Unimplemented, + .positional_simple, .streaming_simple => return error.Unimplemented, .positional => p: { off_in = @intCast(file_reader.pos); break :p &off_in; @@ -7427,7 +7427,7 @@ fn fileWriteFilePositional( } var off_in: i64 = undefined; const off_in_ptr: ?*i64 = switch (file_reader.mode) { - .positional_reading, .streaming_reading => return error.Unimplemented, + .positional_simple, .streaming_simple => return error.Unimplemented, .positional => p: { off_in = @intCast(file_reader.pos); break :p &off_in; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index fd3a456ff7..e33a2bd575 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -283,12 +283,12 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded; /// /// Alternatively, use the higher-level `Io.lockStderr` to integrate with the /// application's chosen `Io` implementation. -pub fn lockStderr(buffer: []u8) Io.Terminal { - return (static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) { +pub fn lockStderr(buffer: []u8) Io.LockedStderr { + return static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) { // Impossible to cancel because no calls to cancel using // `static_single_threaded_io` exist. error.Canceled => unreachable, - }).terminal(); + }; } pub fn unlockStderr() void { @@ -311,7 +311,7 @@ pub fn print(comptime fmt: []const u8, args: anytype) void { var buffer: [64]u8 = undefined; const stderr = lockStderr(&buffer); defer unlockStderr(); - stderr.writer.print(fmt, args) catch return; + stderr.file_writer.interface.print(fmt, args) catch return; } } @@ -327,7 +327,7 @@ pub inline fn getSelfDebugInfo() !*SelfInfo { /// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned. /// Obtains the stderr mutex while dumping. pub fn dumpHex(bytes: []const u8) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); dumpHexFallible(stderr, bytes) catch {}; } @@ -551,7 +551,7 @@ pub fn defaultPanic( _ = panicking.fetchAdd(1, .seq_cst); trace: { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); const writer = stderr.writer; @@ -581,7 +581,7 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); stderr.writer.writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. @@ -751,7 +751,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin } /// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors. pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); writeCurrentStackTrace(.{ .first_address = a: { @@ -814,7 +814,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void } /// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors. pub fn dumpStackTrace(st: *const StackTrace) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); writeStackTrace(st, stderr) catch |err| switch (err) { error.WriteFailed => {}, @@ -1550,7 +1550,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex _ = panicking.fetchAdd(1, .seq_cst); trace: { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); if (addr) |a| { @@ -1571,7 +1571,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex // A segfault happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); stderr.writer.writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. @@ -1678,7 +1678,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize pub fn dump(t: @This()) void { if (!enabled) return; - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); const end = @min(t.index, size); for (t.addrs[0..end], 0..) |frames_array, i| { diff --git a/lib/std/debug/simple_panic.zig b/lib/std/debug/simple_panic.zig index 2d0e5abf4e..34e8f7b43c 100644 --- a/lib/std/debug/simple_panic.zig +++ b/lib/std/debug/simple_panic.zig @@ -14,9 +14,9 @@ const std = @import("../std.zig"); pub fn call(msg: []const u8, ra: ?usize) noreturn { @branchHint(.cold); _ = ra; - const stderr = std.debug.lockStderrWriter(&.{}); - stderr.interface.writeAll(msg) catch {}; - stderr.interface.flush(msg) catch {}; + const stderr_writer = std.debug.lockStderr(&.{}, null).terminal().writer; + stderr_writer.writeAll(msg) catch {}; + stderr_writer.flush(msg) catch {}; @trap(); } diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig index f85916670b..e38ea9cb17 100644 --- a/lib/std/json/dynamic.zig +++ b/lib/std/json/dynamic.zig @@ -47,9 +47,9 @@ pub const Value = union(enum) { } pub fn dump(v: Value) void { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - json.Stringify.value(v, .{}, &stderr.interface) catch return; + const stderr = std.debug.lockStderr(&.{}, null); + defer std.debug.unlockStderr(); + json.Stringify.value(v, .{}, &stderr.file_writer.interface) catch return; } pub fn jsonStringify(value: @This(), jws: anytype) !void { diff --git a/lib/std/log.zig b/lib/std/log.zig index 8579bb04e0..81bfc4ebb6 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -92,7 +92,7 @@ pub fn defaultLog( args: anytype, ) void { var buffer: [64]u8 = undefined; - const stderr = std.debug.lockStderr(&buffer); + const stderr = std.debug.lockStderr(&buffer).terminal(); defer std.debug.unlockStderr(); return defaultLogFileTerminal(level, scope, format, args, stderr) catch {}; } diff --git a/lib/std/process.zig b/lib/std/process.zig index 45cd575133..23a3d92e9b 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1856,7 +1856,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { /// and does not return. pub fn cleanExit(io: Io) void { if (builtin.mode == .Debug) return; - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, .no_color) catch {}; exit(0); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index be6f316804..98fca2f2d5 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -368,8 +368,8 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const break :diff_index if (expected.len == actual.len) return else shortest; }; if (!backend_can_print) return error.TestExpectedEqual; - if (io.lockStderrWriter(&.{})) |stderr| { - defer io.unlockStderrWriter(); + if (io.lockStderr(&.{}, null)) |stderr| { + defer io.unlockStderr(); failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; } else |_| {} return error.TestExpectedEqual; @@ -381,7 +381,7 @@ fn failEqualSlices( actual: []const T, diff_index: usize, w: *Io.Writer, - fwm: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, ) !void { try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); @@ -404,12 +404,12 @@ fn failEqualSlices( var differ = if (T == u8) BytesDiffer{ .expected = expected_window, .actual = actual_window, - .file_writer_mode = fwm, + .terminal_mode = terminal_mode, } else SliceDiffer(T){ .start_index = window_start, .expected = expected_window, .actual = actual_window, - .file_writer_mode = fwm, + .terminal_mode = terminal_mode, }; // Print indexes as hex for slices of u8 since it's more likely to be binary data where @@ -466,21 +466,22 @@ fn SliceDiffer(comptime T: type) type { start_index: usize, expected: []const T, actual: []const T, - file_writer_mode: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, const Self = @This(); pub fn write(self: Self, writer: *Io.Writer) !void { + const t: Io.Terminal = .{ .writer = writer, .mode = self.terminal_mode }; for (self.expected, 0..) |value, i| { const full_index = self.start_index + i; const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; - if (diff) try self.file_writer_mode.setColor(writer, .red); + if (diff) try t.setColor(writer, .red); if (@typeInfo(T) == .pointer) { try writer.print("[{}]{*}: {any}\n", .{ full_index, value, value }); } else { try writer.print("[{}]: {any}\n", .{ full_index, value }); } - if (diff) try self.file_writer_mode.setColor(writer, .reset); + if (diff) try t.setColor(writer, .reset); } } }; @@ -489,7 +490,7 @@ fn SliceDiffer(comptime T: type) type { const BytesDiffer = struct { expected: []const u8, actual: []const u8, - file_writer_mode: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, pub fn write(self: BytesDiffer, writer: *Io.Writer) !void { var expected_iterator = std.mem.window(u8, self.expected, 16, 16); @@ -516,7 +517,7 @@ const BytesDiffer = struct { try self.writeDiff(writer, "{c}", .{byte}, diff); } else { // TODO: remove this `if` when https://github.com/ziglang/zig/issues/7600 is fixed - if (self.file_writer_mode == .terminal_winapi) { + if (self.terminal_mode == .windows_api) { try self.writeDiff(writer, ".", .{}, diff); continue; } diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 6e89c75d91..6212264005 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -46,25 +46,18 @@ pub const SrcHasher = std.crypto.hash.Blake3; pub const SrcHash = [16]u8; pub const Color = enum { - /// Determine whether stderr is a terminal or not automatically. + /// Auto-detect whether stream supports terminal colors. auto, - /// Assume stderr is not a terminal. + /// Force-enable colors. off, - /// Assume stderr is a terminal. + /// Suppress colors. on, - pub fn getTtyConf(color: Color, detected: Io.File.Writer.Mode) Io.File.Writer.Mode { + pub fn terminalMode(color: Color) ?Io.Terminal.Mode { return switch (color) { - .auto => detected, - .on => .terminal_escaped, - .off => .streaming, - }; - } - pub fn detectTtyConf(color: Color, io: Io) Io.File.Writer.Mode { - return switch (color) { - .auto => .detect(io, .stderr()), - .on => .terminal_escaped, - .off => .streaming, + .auto => null, + .on => .escape_codes, + .off => .no_color, }; } }; diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index 556b1167a3..c5275729ae 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -166,51 +166,53 @@ pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Error; pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void { var buffer: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + const stderr = try io.lockStderr(&buffer, color.terminalMode()); + defer io.unlockStderr(); + renderToTerminal(eb, options, stderr.terminal()) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, else => |e| return e, }; } -pub fn renderToWriter( - eb: ErrorBundle, - options: RenderOptions, - w: *Writer, - fwm: Io.File.Writer.Mode, -) Io.File.Writer.Mode.SetColorError!void { +pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) Writer.Error!void { + return renderToTerminal(eb, options, .{ .writer = w, .mode = .no_color }) catch |err| switch (err) { + error.WriteFailed => |e| return e, + else => unreachable, + }; +} + +pub fn renderToTerminal(eb: ErrorBundle, options: RenderOptions, t: Io.Terminal) Io.Terminal.SetColorError!void { if (eb.extra.len == 0) return; for (eb.getMessages()) |err_msg| { - try renderErrorMessageToWriter(eb, options, err_msg, w, fwm, "error", .red, 0); + try renderErrorMessage(eb, options, err_msg, t, "error", .red, 0); } if (options.include_log_text) { const log_text = eb.getCompileLogOutput(); if (log_text.len != 0) { - try w.writeAll("\nCompile Log Output:\n"); - try w.writeAll(log_text); + try t.writer.writeAll("\nCompile Log Output:\n"); + try t.writer.writeAll(log_text); } } } -fn renderErrorMessageToWriter( +fn renderErrorMessage( eb: ErrorBundle, options: RenderOptions, err_msg_index: MessageIndex, - w: *Writer, - fwm: Io.File.Writer.Mode, + t: Io.Terminal, kind: []const u8, - color: Io.File.Writer.Color, + color: Io.Terminal.Color, indent: usize, -) Io.File.Writer.Mode.SetColorError!void { +) Io.Terminal.SetColorError!void { + const w = t.writer; const err_msg = eb.getErrorMessage(err_msg_index); if (err_msg.src_loc != .none) { const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc)); var prefix: Writer.Discarding = .init(&.{}); try w.splatByteAll(' ', indent); prefix.count += indent; - try fwm.setColor(w, .bold); + try t.setColor(.bold); try w.print("{s}:{d}:{d}: ", .{ eb.nullTerminatedString(src.data.src_path), src.data.line + 1, @@ -221,7 +223,7 @@ fn renderErrorMessageToWriter( src.data.line + 1, src.data.column + 1, }); - try fwm.setColor(w, color); + try t.setColor(color); try w.writeAll(kind); prefix.count += kind.len; try w.writeAll(": "); @@ -229,17 +231,17 @@ fn renderErrorMessageToWriter( // This is the length of the part before the error message: // e.g. "file.zig:4:5: error: " const prefix_len: usize = @intCast(prefix.count); - try fwm.setColor(w, .reset); - try fwm.setColor(w, .bold); + try t.setColor(.reset); + try t.setColor(.bold); if (err_msg.count == 1) { try writeMsg(eb, err_msg, w, prefix_len); try w.writeByte('\n'); } else { try writeMsg(eb, err_msg, w, prefix_len); - try fwm.setColor(w, .dim); + try t.setColor(.dim); try w.print(" ({d} times)\n", .{err_msg.count}); } - try fwm.setColor(w, .reset); + try t.setColor(.reset); if (src.data.source_line != 0 and options.include_source_line) { const line = eb.nullTerminatedString(src.data.source_line); for (line) |b| switch (b) { @@ -252,19 +254,19 @@ fn renderErrorMessageToWriter( // -1 since span.main includes the caret const after_caret = src.data.span_end -| src.data.span_main -| 1; try w.splatByteAll(' ', src.data.column - before_caret); - try fwm.setColor(w, .green); + try t.setColor(.green); try w.splatByteAll('~', before_caret); try w.writeByte('^'); try w.splatByteAll('~', after_caret); try w.writeByte('\n'); - try fwm.setColor(w, .reset); + try t.setColor(.reset); } for (eb.getNotes(err_msg_index)) |note| { - try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent); + try renderErrorMessage(eb, options, note, t, "note", .cyan, indent); } if (src.data.reference_trace_len > 0 and options.include_reference_trace) { - try fwm.setColor(w, .reset); - try fwm.setColor(w, .dim); + try t.setColor(.reset); + try t.setColor(.dim); try w.print("referenced by:\n", .{}); var ref_index = src.end; for (0..src.data.reference_trace_len) |_| { @@ -291,25 +293,25 @@ fn renderErrorMessageToWriter( ); } } - try fwm.setColor(w, .reset); + try t.setColor(.reset); } } else { - try fwm.setColor(w, color); + try t.setColor(color); try w.splatByteAll(' ', indent); try w.writeAll(kind); try w.writeAll(": "); - try fwm.setColor(w, .reset); + try t.setColor(.reset); const msg = eb.nullTerminatedString(err_msg.msg); if (err_msg.count == 1) { try w.print("{s}\n", .{msg}); } else { try w.print("{s}", .{msg}); - try fwm.setColor(w, .dim); + try t.setColor(.dim); try w.print(" ({d} times)\n", .{err_msg.count}); } - try fwm.setColor(w, .reset); + try t.setColor(.reset); for (eb.getNotes(err_msg_index)) |note| { - try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent + 4); + try renderErrorMessage(eb, options, note, t, "note", .cyan, indent + 4); } } } diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 6c11c3021b..94d877b406 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -6333,25 +6333,25 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined; fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); var tree = try std.zig.Ast.parse(allocator, source, .zig); defer tree.deinit(allocator); for (tree.errors) |parse_error| { const loc = tree.tokenLocation(0, parse_error.token); - try stderr.printUnescaped("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 }); - try tree.renderError(parse_error, &stderr.interface); - try stderr.interface.print("\n{s}\n", .{source[loc.line_start..loc.line_end]}); + try stderr.writer.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 }); + try tree.renderError(parse_error, stderr.writer); + try stderr.writer.print("\n{s}\n", .{source[loc.line_start..loc.line_end]}); { var i: usize = 0; while (i < loc.column) : (i += 1) { - try stderr.writeAllUnescaped(" "); + try stderr.writer.writeAll(" "); } - try stderr.writeAllUnescaped("^"); + try stderr.writer.writeAll("^"); } - try stderr.writeAllUnescaped("\n"); + try stderr.writer.writeAll("\n"); } if (tree.errors.len != 0) { return error.ParseError; diff --git a/src/Air/print.zig b/src/Air/print.zig index 05614a0ed3..98b0a0b242 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -76,9 +76,9 @@ pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { const comp = pt.zcu.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; air.write(w, pt, liveness); } @@ -86,9 +86,9 @@ pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Ai const comp = pt.zcu.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; air.writeInst(w, inst, pt, liveness); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 37e15ab171..f3fcef40a0 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2092,14 +2092,16 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, } if (options.verbose_llvm_cpu_features) { - if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - const w = &stderr.interface; - w.print("compilation: {s}\n", .{options.root_name}) catch break :print; - w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; - w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; - w.print(" features: {s}\n", .{cf}) catch {}; + if (options.root_mod.resolved_target.llvm_cpu_features) |cf| { + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; + printVerboseLlvmCpuFeatures(w, arena, options.root_name, target, cf) catch |err| switch (err) { + error.WriteFailed => switch (stderr.file_writer.err.?) { + error.Canceled => |e| return e, + else => {}, + }, + }; } } @@ -2700,6 +2702,19 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, return comp; } +fn printVerboseLlvmCpuFeatures( + w: *Writer, + arena: Allocator, + root_name: []const u8, + target: *const std.Target, + cf: [*:0]const u8, +) Writer.Error!void { + try w.print("compilation: {s}\n", .{root_name}); + try w.print(" target: {s}\n", .{try target.zigTriple(arena)}); + try w.print(" cpu: {s}\n", .{target.cpu.model.name}); + try w.print(" features: {s}\n", .{cf}); +} + pub fn destroy(comp: *Compilation) void { const gpa = comp.gpa; const io = comp.io; @@ -4259,9 +4274,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { // However, we haven't reported any such error. // This is a compiler bug. print_ctx: { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = std.debug.lockStderr(&.{}).terminal(); + defer std.debug.unlockStderr(); + const w = stderr.writer; w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; while (ref) |r| { @@ -7772,11 +7787,11 @@ pub fn lockAndSetMiscFailure( pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; return dumpArgvWriter(w, argv) catch |err| switch (err) { - error.WriteFailed => switch (stderr.err.?) { + error.WriteFailed => switch (stderr.file_writer.err.?) { error.Canceled => return error.Canceled, else => return, }, diff --git a/src/InternPool.zig b/src/InternPool.zig index 539cb441c5..98bde244c5 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11169,9 +11169,9 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr_writer.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try dumpStatsFallible(ip, w, std.heap.page_allocator); try dumpAllFallible(ip, w); } @@ -11536,8 +11536,8 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr_writer = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); const w = &stderr_writer.interface; try ip.dumpGenericInstancesFallible(allocator, w); } diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 76ab3e229c..103cbaaaae 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4560,10 +4560,10 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e if (build_options.enable_debug_extensions and comp.verbose_air) p: { const io = comp.io; - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - printVerboseAir(pt, liveness, fqn, air, &stderr.interface) catch |err| switch (err) { - error.WriteFailed => switch (stderr.err.?) { + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + printVerboseAir(pt, liveness, fqn, air, &stderr.file_writer.interface) catch |err| switch (err) { + error.WriteFailed => switch (stderr.file_writer.err.?) { error.Canceled => |e| return e, else => break :p, }, diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 138c70fecf..93a6e0a768 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11274,16 +11274,15 @@ fn initValueAdvanced( } pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { const zcu = isel.pt.zcu; - const io = zcu.comp.io; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const nav = ip.getNav(isel.nav_index); errdefer |err| @panic(@errorName(err)); - const stderr_writer = io.lockStderrWriter(&.{}) catch return; - defer io.unlockStderrWriter(); - const stderr = &stderr_writer.interface; + const locked_stderr = std.debug.lockStderr(&.{}, null); + defer std.debug.unlockStderr(); + const stderr = &locked_stderr.file_writer.interface; var reverse_live_values: std.AutoArrayHashMapUnmanaged(Value.Index, std.ArrayList(Air.Inst.Index)) = .empty; defer { diff --git a/src/crash_report.zig b/src/crash_report.zig index f23806b758..e56bc7cec5 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -95,9 +95,9 @@ fn dumpCrashContext() Io.Writer.Error!void { // TODO: this does mean that a different thread could grab the stderr mutex between the context // and the actual panic printing, which would be quite confusing. - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = std.debug.lockStderr(&.{}); + defer std.debug.unlockStderr(); + const w = &stderr.file_writer.interface; try w.writeAll("Compiler crash context:\n"); diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index a76fec9237..8cf1dfa303 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -314,14 +314,14 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (comp.verbose_cc) { var buffer: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; w.print("def file: {s}\n", .{def_file_path}) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + error.WriteFailed => return stderr.file_writer.err.?, }; w.print("include dir: {s}\n", .{include_dir}) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + error.WriteFailed => return stderr.file_writer.err.?, }; } @@ -339,12 +339,12 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); for (aro_comp.diagnostics.output.to_list.messages.items) |msg| { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { - msg.write(&stderr.interface, stderr.mode, true) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + msg.write(stderr.terminal(), true) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, }; return error.AroPreprocessorFailed; } @@ -365,9 +365,9 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { error.OutOfMemory => |e| return e, error.ParseError => { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try w.writeAll("error: "); try def_diagnostics.writeMsg(w, input); try w.writeByte('\n'); diff --git a/src/libs/mingw/def.zig b/src/libs/mingw/def.zig index 9a105b6182..f1c112d16e 100644 --- a/src/libs/mingw/def.zig +++ b/src/libs/mingw/def.zig @@ -1039,9 +1039,9 @@ fn testParse( const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) { error.OutOfMemory => |e| return e, error.ParseError => { - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try diagnostics.writeMsg(w, source); try w.writeByte('\n'); return err; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index d379669613..03b757f5b4 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -2382,9 +2382,9 @@ pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void { const comp = coff.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; coff.printNode(tid, w, .root, 0) catch |err| switch (err) { error.WriteFailed => return stderr.err.?, }; diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 3c511f1ee9..bbdb439385 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -3733,9 +3733,9 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { const comp = elf.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.lockStderr(); + const w = &stderr.file_writer.interface; elf.printNode(tid, w, .root, 0) catch |err| switch (err) { error.WriteFailed => return stderr.err.?, }; diff --git a/src/main.zig b/src/main.zig index c5ed278921..8e30febb81 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4429,9 +4429,9 @@ fn runOrTest( // the error message and invocation below. if (process.can_execv and arg_mode == .run) { // execv releases the locks; no need to destroy the Compilation here. - _ = try io.lockStderrWriter(&.{}); + _ = try io.lockStderr(&.{}, .no_color); const err = process.execve(gpa, argv.items, &env_map); - io.unlockStderrWriter(); + io.unlockStderr(); try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd }); @@ -4448,8 +4448,8 @@ fn runOrTest( comp_destroyed.* = true; const term_result = t: { - _ = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + _ = try io.lockStderr(&.{}, .no_color); + defer io.unlockStderr(); break :t child.spawnAndWait(io); }; const term = term_result catch |err| { @@ -5418,8 +5418,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) child.stderr_behavior = .Inherit; const term = t: { - _ = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + _ = try io.lockStderr(&.{}, .no_color); + defer io.unlockStderr(); break :t child.spawnAndWait(io) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); }; -- cgit v1.2.3 From a5b719e9eb0a196a43a88af8f62c897d1ecfa04f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Dec 2025 23:12:11 -0800 Subject: compiler: fix build failures from std.Io-fs --- lib/compiler/aro/aro/Diagnostics.zig | 10 +++++----- lib/std/Io/Dir.zig | 2 +- lib/std/Io/Threaded.zig | 2 +- lib/std/zig/llvm/Builder.zig | 4 ++-- src/Compilation.zig | 32 +++++++++++++------------------- src/InternPool.zig | 26 +++++++++++++------------- src/Package/Fetch.zig | 15 ++++++--------- src/codegen/aarch64/Select.zig | 2 +- src/codegen/llvm.zig | 18 +++++++++--------- src/libs/mingw.zig | 1 + src/link.zig | 3 +-- src/link/Elf.zig | 5 +++-- src/link/Lld.zig | 2 +- src/link/MachO.zig | 8 +++++--- src/link/MappedFile.zig | 4 ++-- src/link/Queue.zig | 1 + src/link/Wasm.zig | 3 ++- 17 files changed, 67 insertions(+), 71 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index b33efa3f85..993b5d93af 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -541,11 +541,11 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void { switch (d.output) { .ignore => {}, - .to_writer => |writer| { - var config = writer.color; - if (d.color == false) config = .no_color; - if (d.color == true and config == .no_color) config = .escape_codes; - msg.write(writer.writer, config, d.details) catch { + .to_writer => |t| { + var new_mode = t.mode; + if (d.color == false) new_mode = .no_color; + if (d.color == true and new_mode == .no_color) new_mode = .escape_codes; + msg.write(.{ .writer = t.writer, .mode = new_mode }, d.details) catch { return error.FatalError; }; }, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index f482f72afd..12fcea6576 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1739,7 +1739,7 @@ pub fn setFilePermissions( new_permissions: File.Permissions, options: SetFilePermissionsOptions, ) SetFilePermissionsError!void { - return io.vtable.dirSetFilePermissions(io.userdata, sub_path, dir, new_permissions, options); + return io.vtable.dirSetFilePermissions(io.userdata, dir, sub_path, new_permissions, options); } pub const SetOwnerError = File.SetOwnerError; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index b07a9bb9a8..ca10272b33 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -10139,7 +10139,7 @@ fn initLockedStderr( t.stderr_writer.interface.buffer = buffer; return .{ .file_writer = &t.stderr_writer, - .terminal_mode = t.stderr_mode, + .terminal_mode = terminal_mode orelse t.stderr_mode, }; } diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 251c87defc..66d20df348 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -9576,10 +9576,10 @@ pub fn asmValue( return (try self.asmConst(ty, info, assembly, constraints)).toValue(); } -pub fn dump(b: *Builder) void { +pub fn dump(b: *Builder, io: Io) void { var buffer: [4000]u8 = undefined; const stderr: Io.File = .stderr(); - b.printToFile(stderr, &buffer) catch {}; + b.printToFile(io, stderr, &buffer) catch {}; } pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void { diff --git a/src/Compilation.zig b/src/Compilation.zig index f3fcef40a0..a78bf19e66 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2101,6 +2101,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, error.Canceled => |e| return e, else => {}, }, + error.OutOfMemory => |e| return e, }; } } @@ -2708,7 +2709,7 @@ fn printVerboseLlvmCpuFeatures( root_name: []const u8, target: *const std.Target, cf: [*:0]const u8, -) Writer.Error!void { +) (Writer.Error || Allocator.Error)!void { try w.print("compilation: {s}\n", .{root_name}); try w.print(" target: {s}\n", .{try target.zigTriple(arena)}); try w.print(" cpu: {s}\n", .{target.cpu.model.name}); @@ -3113,7 +3114,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { std.debug.print("intern pool stats for '{s}':\n", .{comp.root_name}); - zcu.intern_pool.dump(io); + zcu.intern_pool.dump(); } if (build_options.enable_debug_extensions and comp.verbose_generic_instances) { @@ -3320,11 +3321,8 @@ pub fn resolveEmitPathFlush( }, } } -fn flush( - comp: *Compilation, - arena: Allocator, - tid: Zcu.PerThread.Id, -) Allocator.Error!void { + +fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancelable || Allocator.Error)!void { const io = comp.io; if (comp.zcu) |zcu| { if (zcu.llvm_object) |llvm_object| { @@ -3390,7 +3388,7 @@ fn flush( // This is needed before reading the error flags. lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) { error.LinkFailure => {}, // Already reported. - error.OutOfMemory => return error.OutOfMemory, + error.OutOfMemory, error.Canceled => |e| return e, }; } if (comp.zcu) |zcu| { @@ -3614,6 +3612,7 @@ fn emitFromCObject( new_ext: []const u8, unresolved_emit_path: []const u8, ) Allocator.Error!void { + const io = comp.io; // The dirname and stem (i.e. everything but the extension), of the sub path of the C object. // We'll append `new_ext` to it to get the path to the right thing (asm, LLVM IR, etc). const c_obj_dir_and_stem: []const u8 = p: { @@ -3623,23 +3622,18 @@ fn emitFromCObject( }; const src_path: Cache.Path = .{ .root_dir = c_obj_path.root_dir, - .sub_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ - c_obj_dir_and_stem, - new_ext, - }), + .sub_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ c_obj_dir_and_stem, new_ext }), }; const emit_path = comp.resolveEmitPath(unresolved_emit_path); - src_path.root_dir.handle.copyFile( + Io.Dir.copyFile( + src_path.root_dir.handle, src_path.sub_path, emit_path.root_dir.handle, emit_path.sub_path, + io, .{}, - ) catch |err| log.err("unable to copy '{f}' to '{f}': {s}", .{ - src_path, - emit_path, - @errorName(err), - }); + ) catch |err| log.err("unable to copy '{f}' to '{f}': {t}", .{ src_path, emit_path, err }); } /// Having the file open for writing is problematic as far as executing the @@ -7787,7 +7781,7 @@ pub fn lockAndSetMiscFailure( pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderr(&buffer); + const stderr = try io.lockStderr(&buffer, null); defer io.unlockStderr(); const w = &stderr.file_writer.interface; return dumpArgvWriter(w, argv) catch |err| switch (err) { diff --git a/src/InternPool.zig b/src/InternPool.zig index 98bde244c5..3076aa2cf3 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11167,16 +11167,16 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release); } -pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { +pub fn dump(ip: *const InternPool) void { var buffer: [4096]u8 = undefined; - const stderr = try io.lockStderr(&buffer, null); - defer io.unlockStderr(); + const stderr = std.debug.lockStderr(&buffer); + defer std.debug.unlockStderr(); const w = &stderr.file_writer.interface; - try dumpStatsFallible(ip, w, std.heap.page_allocator); - try dumpAllFallible(ip, w); + dumpStatsFallible(ip, w, std.heap.page_allocator) catch return; + dumpAllFallible(ip, w) catch return; } -fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) anyerror!void { +fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !void { var items_len: usize = 0; var extra_len: usize = 0; var limbs_len: usize = 0; @@ -11429,9 +11429,9 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) any }; counts.sort(SortContext{ .map = &counts }); const len = @min(50, counts.count()); - w.print(" top 50 tags:\n", .{}); + try w.print(" top 50 tags:\n", .{}); for (counts.keys()[0..len], counts.values()[0..len]) |tag, stats| { - w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); + try w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); } } @@ -11534,12 +11534,12 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { } } -pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { +pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderr(&buffer, null); - defer io.unlockStderr(); - const w = &stderr_writer.interface; - try ip.dumpGenericInstancesFallible(allocator, w); + const stderr = std.debug.lockStderr(&buffer); + defer std.debug.unlockStderr(); + const w = &stderr.file_writer.interface; + ip.dumpGenericInstancesFallible(allocator, w) catch return; } pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, w: *Io.Writer) !void { diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 823015574b..b17b39cd83 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -1682,18 +1682,18 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er hasher.update(&.{ 0, 0 }); var file_header: FileHeader = .{}; while (true) { - const bytes_read = try file.read(&buf); + const bytes_read = try file.readPositional(io, &.{&buf}, file_size); if (bytes_read == 0) break; file_size += bytes_read; hasher.update(buf[0..bytes_read]); file_header.update(buf[0..bytes_read]); } if (file_header.isExecutable()) { - try setExecutable(file); + try setExecutable(io, file); } }, .link => { - const link_name = try dir.readLink(io, hashed_file.fs_path, &buf); + const link_name = buf[0..try dir.readLink(io, hashed_file.fs_path, &buf)]; if (fs.path.sep != canonical_sep) { // Package hashes are intended to be consistent across // platforms which means we must normalize path separators @@ -1711,12 +1711,9 @@ fn deleteFileFallible(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) DeletedFi try dir.deleteFile(io, deleted_file.fs_path); } -fn setExecutable(file: Io.File) !void { +fn setExecutable(io: Io, file: Io.File) !void { if (!Io.File.Permissions.has_executable_bit) return; - - const S = std.posix.S; - const mode = Io.File.default_mode | S.IXUSR | S.IXGRP | S.IXOTH; - try file.chmod(mode); + try file.setPermissions(io, .executable_file); } const DeletedFile = struct { @@ -1738,7 +1735,7 @@ const HashedFile = struct { const Error = Io.File.OpenError || - Io.File.Reader.Error || + Io.File.ReadPositionalError || Io.File.StatError || Io.File.SetPermissionsError || Io.Dir.ReadLinkError; diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 93a6e0a768..49de055b47 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11280,7 +11280,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { errdefer |err| @panic(@errorName(err)); - const locked_stderr = std.debug.lockStderr(&.{}, null); + const locked_stderr = std.debug.lockStderr(&.{}); defer std.debug.unlockStderr(); const stderr = &locked_stderr.file_writer.interface; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4fc58c2c4b..fca89ea4fc 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -965,10 +965,10 @@ pub const Object = struct { const context, const module = emit: { if (options.pre_ir_path) |path| { if (std.mem.eql(u8, path, "-")) { - o.builder.dump(); + o.builder.dump(io); } else { - o.builder.printToFilePath(Io.Dir.cwd(), path) catch |err| { - log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); + o.builder.printToFilePath(io, Io.Dir.cwd(), path) catch |err| { + log.err("failed printing LLVM module to \"{s}\": {t}", .{ path, err }); }; } } @@ -982,12 +982,12 @@ pub const Object = struct { if (options.pre_bc_path) |path| { var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| - return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); + return diags.fail("failed to create '{s}': {t}", .{ path, err }); defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); - file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| - return diags.fail("failed to write to '{s}': {s}", .{ path, @errorName(err) }); + file.writeStreamingAll(io, ptr[0..(bitcode.len * 4)]) catch |err| + return diags.fail("failed to write to '{s}': {t}", .{ path, err }); } if (options.asm_path == null and options.bin_path == null and @@ -995,12 +995,12 @@ pub const Object = struct { if (options.post_bc_path) |path| { var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| - return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); + return diags.fail("failed to create '{s}': {t}", .{ path, err }); defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); - file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| - return diags.fail("failed to write to '{s}': {s}", .{ path, @errorName(err) }); + file.writeStreamingAll(io, ptr[0..(bitcode.len * 4)]) catch |err| + return diags.fail("failed to write to '{s}': {t}", .{ path, err }); } if (!build_options.have_llvm or !comp.config.use_lib_llvm) { diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 8cf1dfa303..c4b002f983 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -345,6 +345,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { msg.write(stderr.terminal(), true) catch |err| switch (err) { error.WriteFailed => return stderr.file_writer.err.?, + error.Unexpected => |e| return e, }; return error.AroPreprocessorFailed; } diff --git a/src/link.zig b/src/link.zig index 3b822b2e69..13306b90a4 100644 --- a/src/link.zig +++ b/src/link.zig @@ -900,10 +900,9 @@ pub const File = struct { } } - pub const FlushError = error{ + pub const FlushError = Io.Cancelable || Allocator.Error || error{ /// Indicates an error will be present in `Compilation.link_diags`. LinkFailure, - OutOfMemory, }; /// Commit pending changes and write headers. Takes into account final output mode. diff --git a/src/link/Elf.zig b/src/link/Elf.zig index a312138c04..85f37f88ce 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -748,9 +748,10 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std defer tracy.end(); const comp = self.base.comp; + const io = comp.io; const diags = &comp.link_diags; - if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items); + if (comp.verbose_link) try Compilation.dumpArgv(io, self.dump_argv_list.items); const sub_prog_node = prog_node.start("ELF Flush", 0); defer sub_prog_node.end(); @@ -758,7 +759,7 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std return flushInner(self, arena, tid) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.LinkFailure => return error.LinkFailure, - else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}), + else => |e| return diags.fail("ELF flush failed: {t}", .{e}), }; } diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 8ba91905a8..b2a0f6e396 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1588,7 +1588,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi if (comp.verbose_link) { // Skip over our own name so that the LLD linker name is the first argv item. - Compilation.dump_argv(argv[1..]); + try Compilation.dumpArgv(io, argv[1..]); } // If possible, we run LLD as a child process because it does not always diff --git a/src/link/MachO.zig b/src/link/MachO.zig index cd9674a390..b3c62db2df 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -618,14 +618,16 @@ pub fn flush( }; const emit = self.base.emit; invalidateKernelCache(emit.root_dir.handle, emit.sub_path) catch |err| switch (err) { - else => |e| return diags.fail("failed to invalidate kernel cache: {s}", .{@errorName(e)}), + else => |e| return diags.fail("failed to invalidate kernel cache: {t}", .{e}), }; } } /// --verbose-link output fn dumpArgv(self: *MachO, comp: *Compilation) !void { - const gpa = self.base.comp.gpa; + const gpa = comp.gpa; + const io = comp.io; + var arena_allocator = std.heap.ArenaAllocator.init(gpa); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -820,7 +822,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { if (comp.ubsan_rt_obj) |obj| try argv.append(try obj.full_object_path.toString(arena)); } - Compilation.dump_argv(argv.items); + try Compilation.dumpArgv(io, argv.items); } /// TODO delete this, libsystem must be resolved when setting up the compilation pipeline diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index dca3dca503..2986e27e24 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -476,8 +476,8 @@ pub const Node = extern struct { return n; }, .streaming, - .streaming_reading, - .positional_reading, + .streaming_simple, + .positional_simple, .failure, => { const dest = limit.slice(interface.unusedCapacitySlice()); diff --git a/src/link/Queue.zig b/src/link/Queue.zig index e8e7700695..caa2cc1898 100644 --- a/src/link/Queue.zig +++ b/src/link/Queue.zig @@ -175,6 +175,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void { lf.post_prelink = true; } else |err| switch (err) { error.OutOfMemory => comp.link_diags.setAllocFailure(), + error.Canceled => @panic("TODO"), error.LinkFailure => {}, } } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index a8140327e5..216a641db3 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3828,8 +3828,9 @@ pub fn flush( const comp = wasm.base.comp; const diags = &comp.link_diags; const gpa = comp.gpa; + const io = comp.io; - if (comp.verbose_link) Compilation.dump_argv(wasm.dump_argv_list.items); + if (comp.verbose_link) try Compilation.dumpArgv(io, wasm.dump_argv_list.items); if (wasm.base.zcu_object_basename) |raw| { const zcu_obj_path: Path = try comp.resolveEmitPathFlush(arena, .temp, raw); -- cgit v1.2.3 From 54865e0483bf02bc1ace9f06c00071fce32534cc Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Dec 2025 23:23:32 -0800 Subject: compiler: fix compilation when linking libc --- lib/compiler/test_runner.zig | 2 +- lib/std/Io/Threaded.zig | 4 ++-- lib/std/testing.zig | 15 ++++++++++----- src/Compilation.zig | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 3d97944a7f..d16fc3ae82 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -224,7 +224,7 @@ fn mainTerminal() void { var skip_count: usize = 0; var fail_count: usize = 0; var fuzz_count: usize = 0; - const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(.{ + const root_node = if (builtin.fuzz) std.Progress.Node.none else std.Progress.start(runner_threaded_io.io(), .{ .root_name = "Test", .estimated_total_items = test_fn_list.len, }); diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index ca10272b33..36118ca818 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -6804,7 +6804,7 @@ fn fileWritePositional( try current_thread.beginSyscall(); while (true) { - const rc = pwritev_sym(file.handle, &iovecs, iovlen, @bitCast(offset)); + const rc = pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset)); switch (posix.errno(rc)) { .SUCCESS => { current_thread.endSyscall(); @@ -6923,7 +6923,7 @@ fn fileWriteStreaming( try current_thread.beginSyscall(); while (true) { - const rc = posix.system.writev(file.handle, &iovecs, iovlen); + const rc = posix.system.writev(file.handle, &iovecs, @intCast(iovlen)); switch (posix.errno(rc)) { .SUCCESS => { current_thread.endSyscall(); diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 98fca2f2d5..f3dd114af3 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -370,7 +370,8 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const if (!backend_can_print) return error.TestExpectedEqual; if (io.lockStderr(&.{}, null)) |stderr| { defer io.unlockStderr(); - failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; + const w = &stderr.file_writer.interface; + failEqualSlices(T, expected, actual, diff_index, w, stderr.terminal_mode) catch {}; } else |_| {} return error.TestExpectedEqual; } @@ -475,13 +476,13 @@ fn SliceDiffer(comptime T: type) type { for (self.expected, 0..) |value, i| { const full_index = self.start_index + i; const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; - if (diff) try t.setColor(writer, .red); + if (diff) try t.setColor(.red); if (@typeInfo(T) == .pointer) { try writer.print("[{}]{*}: {any}\n", .{ full_index, value, value }); } else { try writer.print("[{}]: {any}\n", .{ full_index, value }); } - if (diff) try t.setColor(writer, .reset); + if (diff) try t.setColor(.reset); } } }; @@ -538,10 +539,14 @@ const BytesDiffer = struct { } } + fn terminal(self: *const BytesDiffer, writer: *Io.Writer) Io.Terminal { + return .{ .writer = writer, .mode = self.terminal_mode }; + } + fn writeDiff(self: BytesDiffer, writer: *Io.Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void { - if (diff) try self.file_writer_mode.setColor(writer, .red); + if (diff) try self.terminal(writer).setColor(.red); try writer.print(fmt, args); - if (diff) try self.file_writer_mode.setColor(writer, .reset); + if (diff) try self.terminal(writer).setColor(.reset); } }; diff --git a/src/Compilation.zig b/src/Compilation.zig index a78bf19e66..dc254a36c5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -6270,7 +6270,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dumpArgv(io, argv.items); + try dumpArgv(io, argv.items); } const err = std.process.execv(arena, argv.items); @@ -6316,7 +6316,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dumpArgv(io, argv.items); + try dumpArgv(io, argv.items); } // Just to save disk space, we delete the files that are never needed again. @@ -6358,7 +6358,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr var stderr_reader = child.stderr.?.readerStreaming(io, &.{}); const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32))); - const term = child.wait() catch |err| { + const term = child.wait(io) catch |err| { return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) }); }; -- cgit v1.2.3 From a8088306f6223b07ad9b7ae37486bcc9e0ac08c9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 19 Dec 2025 16:42:28 -0800 Subject: std: rename other Dir "make" functions to "create" --- lib/compiler/build_runner.zig | 6 +-- lib/compiler/translate-c/main.zig | 2 +- lib/std/Build.zig | 6 +-- lib/std/Build/Cache.zig | 8 ++-- lib/std/Build/Cache/Path.zig | 8 ++-- lib/std/Build/Step.zig | 6 +-- lib/std/Build/Step/Compile.zig | 4 +- lib/std/Build/Step/ConfigHeader.zig | 2 +- lib/std/Build/Step/ObjCopy.zig | 2 +- lib/std/Build/Step/Options.zig | 4 +- lib/std/Build/Step/Run.zig | 6 +-- lib/std/Build/Step/UpdateSourceFiles.zig | 2 +- lib/std/Build/Step/WriteFile.zig | 8 ++-- lib/std/Io.zig | 6 +-- lib/std/Io/Dir.zig | 40 +++++++++---------- lib/std/Io/Kqueue.zig | 12 +++--- lib/std/Io/Threaded.zig | 65 +++++++++++++++---------------- lib/std/fs/test.zig | 66 ++++++++++++++++---------------- lib/std/posix.zig | 2 +- lib/std/tar.zig | 6 +-- lib/std/testing.zig | 6 +-- lib/std/zip.zig | 4 +- src/Compilation.zig | 34 ++++++++-------- src/Package/Fetch.zig | 12 +++--- src/Package/Fetch/git.zig | 4 +- src/libs/freebsd.zig | 4 +- src/libs/glibc.zig | 4 +- src/libs/mingw.zig | 4 +- src/libs/netbsd.zig | 4 +- src/link/MachO.zig | 2 +- src/main.zig | 8 ++-- 31 files changed, 171 insertions(+), 176 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 1c30ecaadc..cfe0fee78f 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -66,12 +66,12 @@ pub fn main() !void { const local_cache_directory: std.Build.Cache.Directory = .{ .path = cache_root, - .handle = try cwd.makeOpenPath(io, cache_root, .{}), + .handle = try cwd.createDirPathOpen(io, cache_root, .{}), }; const global_cache_directory: std.Build.Cache.Directory = .{ .path = global_cache_root, - .handle = try cwd.makeOpenPath(io, global_cache_root, .{}), + .handle = try cwd.createDirPathOpen(io, global_cache_root, .{}), }; var graph: std.Build.Graph = .{ @@ -80,7 +80,7 @@ pub fn main() !void { .cache = .{ .io = io, .gpa = arena, - .manifest_dir = try local_cache_directory.handle.makeOpenPath(io, "h", .{}), + .manifest_dir = try local_cache_directory.handle.createDirPathOpen(io, "h", .{}), }, .zig_exe = zig_exe, .env_map = try process.getEnvMap(arena), diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index d02f21a2a8..80dc67fbfe 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -253,7 +253,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration if (d.output_name) |path| blk: { if (std.mem.eql(u8, path, "-")) break :blk; if (std.fs.path.dirname(path)) |dirname| { - Io.Dir.cwd().makePath(io, dirname) catch |err| + Io.Dir.cwd().createDirPath(io, dirname) catch |err| return d.fatal("failed to create path to '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); } out_file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| { diff --git a/lib/std/Build.zig b/lib/std/Build.zig index cf0b9e5b0d..4b8909e689 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1701,14 +1701,14 @@ pub fn addCheckFile( return Step.CheckFile.create(b, file_source, options); } -pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void { +pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.CreateDirError || Io.Dir.StatFileError)!void { const io = b.graph.io; if (b.verbose) log.info("truncate {s}", .{dest_path}); const cwd = Io.Dir.cwd(); var src_file = cwd.createFile(io, dest_path, .{}) catch |err| switch (err) { error.FileNotFound => blk: { if (fs.path.dirname(dest_path)) |dirname| { - try cwd.makePath(io, dirname); + try cwd.createDirPath(io, dirname); } break :blk try cwd.createFile(io, dest_path, .{}); }, @@ -2654,7 +2654,7 @@ pub fn makeTempPath(b: *Build) []const u8 { const rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); const result_path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch @panic("OOM"); - b.cache_root.handle.makePath(io, tmp_dir_sub_path) catch |err| { + b.cache_root.handle.createDirPath(io, tmp_dir_sub_path) catch |err| { std.debug.print("unable to make tmp path '{s}': {t}\n", .{ result_path, err }); }; return result_path; diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 43f8691000..396f204350 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1330,7 +1330,7 @@ test "cache file and then recall it" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.createDirPathOpen(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1396,7 +1396,7 @@ test "check that changing a file makes cache fail" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.createDirPathOpen(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1456,7 +1456,7 @@ test "no file inputs" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.createDirPathOpen(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); @@ -1515,7 +1515,7 @@ test "Manifest with files added after initial hash work" { var cache: Cache = .{ .io = io, .gpa = testing.allocator, - .manifest_dir = try tmp.dir.makeOpenPath(io, temp_manifest_dir, .{}), + .manifest_dir = try tmp.dir.createDirPathOpen(io, temp_manifest_dir, .{}), }; cache.addPrefix(.{ .path = null, .handle = tmp.dir }); defer cache.manifest_dir.close(io); diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig index 3ef4dec658..2b7814c544 100644 --- a/lib/std/Build/Cache/Path.zig +++ b/lib/std/Build/Cache/Path.zig @@ -84,14 +84,14 @@ pub fn openDir( return p.root_dir.handle.openDir(io, joined_path, args); } -pub fn makeOpenPath(p: Path, io: Io, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir { +pub fn createDirPathOpen(p: Path, io: Io, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io.Dir { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.makeOpenPath(io, joined_path, opts); + return p.root_dir.handle.createDirPathOpen(io, joined_path, opts); } pub fn statFile(p: Path, io: Io, sub_path: []const u8) !Io.Dir.Stat { @@ -129,14 +129,14 @@ pub fn access(p: Path, io: Io, sub_path: []const u8, flags: Io.Dir.AccessOptions return p.root_dir.handle.access(io, joined_path, flags); } -pub fn makePath(p: Path, io: Io, sub_path: []const u8) !void { +pub fn createDirPath(p: Path, io: Io, sub_path: []const u8) !void { var buf: [fs.max_path_bytes]u8 = undefined; const joined_path = if (p.sub_path.len == 0) sub_path else p: { break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ p.sub_path, sub_path, }) catch return error.NameTooLong; }; - return p.root_dir.handle.makePath(io, joined_path); + return p.root_dir.handle.createDirPath(io, joined_path); } pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 { diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 74b41634a7..243dee8604 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -516,12 +516,12 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u return s.fail("unable to update file from '{f}' to '{s}': {t}", .{ src_path, dest_path, err }); } -/// Wrapper around `Io.Dir.makePathStatus` that handles verbose and error output. -pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus { +/// Wrapper around `Io.Dir.createDirPathStatus` that handles verbose and error output. +pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.CreatePathStatus { const b = s.owner; const io = b.graph.io; try handleVerbose(b, null, &.{ "install", "-d", dest_path }); - return Io.Dir.cwd().makePathStatus(io, dest_path, .default_dir) catch |err| + return Io.Dir.cwd().createDirPathStatus(io, dest_path, .default_dir) catch |err| return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err }); } diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 4752046089..0454e5b79d 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -1669,7 +1669,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { args_length += arg.len + 1; // +1 to account for null terminator } if (args_length >= 30 * 1024) { - try b.cache_root.handle.makePath(io, "args"); + try b.cache_root.handle.createDirPath(io, "args"); const args_to_escape = zig_args.items[2..]; var escaped_args = try std.array_list.Managed([]const u8).initCapacity(arena, args_to_escape.len); @@ -1706,7 +1706,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { // The args file is already present from a previous run. } else |err| switch (err) { error.FileNotFound => { - try b.cache_root.handle.makePath(io, "tmp"); + try b.cache_root.handle.createDirPath(io, "tmp"); const rand_int = std.crypto.random.int(u64); const tmp_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); try b.cache_root.handle.writeFile(io, .{ .sub_path = tmp_path, .data = args }); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 250bae5009..b55efc0da4 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -258,7 +258,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path }); const sub_path_dirname = std.fs.path.dirname(sub_path).?; - b.cache_root.handle.makePath(io, sub_path_dirname) catch |err| { + b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, sub_path_dirname, @errorName(err), }); diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index b81f59b9a1..ea0714adf9 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -177,7 +177,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const cache_path = "o" ++ fs.path.sep_str ++ digest; const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, objcopy.basename }); const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{objcopy.basename}) }); - b.cache_root.handle.makePath(io, cache_path) catch |err| { + b.cache_root.handle.createDirPath(io, cache_path) catch |err| { return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) }); }; diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 676ea4d851..610d417aea 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -477,7 +477,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { } else |outer_err| switch (outer_err) { error.FileNotFound => { const sub_dirname = fs.path.dirname(sub_path).?; - b.cache_root.handle.makePath(io, sub_dirname) catch |e| + b.cache_root.handle.createDirPath(io, sub_dirname) catch |e| return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, sub_dirname, e }); const rand_int = std.crypto.random.int(u64); @@ -486,7 +486,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { basename; const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?; - b.cache_root.handle.makePath(io, tmp_sub_path_dirname) catch |err| { + b.cache_root.handle.createDirPath(io, tmp_sub_path_dirname) catch |err| { return step.fail("unable to make temporary directory '{f}{s}': {t}", .{ b.cache_root, tmp_sub_path_dirname, err, }); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 157a0292e7..c0ba7f0cee 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -975,7 +975,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .output_directory => output_sub_path, else => unreachable, }; - b.cache_root.handle.makePath(io, output_sub_dir_path) catch |err| { + b.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, output_sub_dir_path, @errorName(err), }); @@ -1007,7 +1007,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .output_directory => output_sub_path, else => unreachable, }; - b.cache_root.handle.makePath(io, output_sub_dir_path) catch |err| { + b.cache_root.handle.createDirPath(io, output_sub_dir_path) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, output_sub_dir_path, @errorName(err), }); @@ -1439,7 +1439,7 @@ fn runCommand( const sub_path = b.pathJoin(&output_components); const sub_path_dirname = Dir.path.dirname(sub_path).?; - b.cache_root.handle.makePath(io, sub_path_dirname) catch |err| { + b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {s}", .{ b.cache_root, sub_path_dirname, @errorName(err), }); diff --git a/lib/std/Build/Step/UpdateSourceFiles.zig b/lib/std/Build/Step/UpdateSourceFiles.zig index eb8a6a85dd..1c4c94f9cf 100644 --- a/lib/std/Build/Step/UpdateSourceFiles.zig +++ b/lib/std/Build/Step/UpdateSourceFiles.zig @@ -78,7 +78,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { var any_miss = false; for (usf.output_source_files.items) |output_source_file| { if (fs.path.dirname(output_source_file.sub_path)) |dirname| { - b.build_root.handle.makePath(io, dirname) catch |err| { + b.build_root.handle.createDirPath(io, dirname) catch |err| { return step.fail("unable to make path '{f}{s}': {t}", .{ b.build_root, dirname, err }); }; } diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 53222289e6..145c7f9bb3 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -259,13 +259,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void { write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest }); - var cache_dir = b.cache_root.handle.makeOpenPath(io, cache_path, .{}) catch |err| + var cache_dir = b.cache_root.handle.createDirPathOpen(io, cache_path, .{}) catch |err| return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, cache_path, err }); defer cache_dir.close(io); for (write_file.files.items) |file| { if (fs.path.dirname(file.sub_path)) |dirname| { - cache_dir.makePath(io, dirname) catch |err| { + cache_dir.createDirPath(io, dirname) catch |err| { return step.fail("unable to make path '{f}{s}{c}{s}': {t}", .{ b.cache_root, cache_path, fs.path.sep, dirname, err, }); @@ -300,7 +300,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const dest_dirname = dir.sub_path; if (dest_dirname.len != 0) { - cache_dir.makePath(io, dest_dirname) catch |err| { + cache_dir.createDirPath(io, dest_dirname) catch |err| { return step.fail("unable to make path '{f}{s}{c}{s}': {s}", .{ b.cache_root, cache_path, fs.path.sep, dest_dirname, @errorName(err), }); @@ -315,7 +315,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { const src_entry_path = try src_dir_path.join(arena, entry.path); const dest_path = b.pathJoin(&.{ dest_dirname, entry.path }); switch (entry.kind) { - .directory => try cache_dir.makePath(io, dest_path), + .directory => try cache_dir.createDirPath(io, dest_path), .file => { const prev_status = Io.Dir.updateFile( src_entry_path.root_dir.handle, diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 1d477d330e..ad26893651 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -659,9 +659,9 @@ pub const VTable = struct { futexWaitUncancelable: *const fn (?*anyopaque, ptr: *const u32, expected: u32) void, futexWake: *const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void, - dirMake: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakeError!void, - dirMakePath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.MakePathError!Dir.MakePathStatus, - dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.MakeOpenPathError!Dir, + dirCreateDir: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirError!void, + dirCreateDirPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirPathError!Dir.CreatePathStatus, + dirCreateDirPathOpen: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir, dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir, dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 78637015ba..54cce082da 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -590,7 +590,7 @@ pub fn updateFile( } if (path.dirname(dest_path)) |dirname| { - try dest_dir.makePath(io, dirname); + try dest_dir.createDirPath(io, dirname); } var buffer: [1000]u8 = undefined; // Used only when direct fd-to-fd is not available. @@ -637,7 +637,7 @@ pub fn readFile(dir: Dir, io: Io, file_path: []const u8, buffer: []u8) ReadFileE return buffer[0..n]; } -pub const MakeError = error{ +pub const CreateDirError = error{ /// In WASI, this error may occur when the file descriptor does /// not hold the required rights to create a new directory relative to it. AccessDenied, @@ -663,10 +663,10 @@ pub const MakeError = error{ /// * On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. /// /// Related: -/// * `makePath` +/// * `createDirPath` /// * `createDirAbsolute` -pub fn createDir(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) MakeError!void { - return io.vtable.dirMake(io.userdata, dir, sub_path, permissions); +pub fn createDir(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) CreateDirError!void { + return io.vtable.dirCreateDir(io.userdata, dir, sub_path, permissions); } /// Create a new directory, based on an absolute path. @@ -677,14 +677,14 @@ pub fn createDir(dir: Dir, io: Io, sub_path: []const u8, permissions: Permission /// On Windows, `absolute_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). /// On WASI, `absolute_path` should be encoded as valid UTF-8. /// On other platforms, `absolute_path` is an opaque sequence of bytes with no particular encoding. -pub fn createDirAbsolute(io: Io, absolute_path: []const u8, permissions: Permissions) MakeError!void { +pub fn createDirAbsolute(io: Io, absolute_path: []const u8, permissions: Permissions) CreateDirError!void { assert(path.isAbsolute(absolute_path)); return createDir(.cwd(), io, absolute_path, permissions); } test createDirAbsolute {} -pub const MakePathError = MakeError || StatFileError; +pub const CreateDirPathError = CreateDirError || StatFileError; /// Creates parent directories with default permissions as necessary to ensure /// `sub_path` exists as a directory. @@ -710,27 +710,27 @@ pub const MakePathError = MakeError || StatFileError; /// and a `./second` directory. /// /// See also: -/// * `makePathStatus` -pub fn makePath(dir: Dir, io: Io, sub_path: []const u8) MakePathError!void { - _ = try io.vtable.dirMakePath(io.userdata, dir, sub_path, .default_dir); +/// * `createDirPathStatus` +pub fn createDirPath(dir: Dir, io: Io, sub_path: []const u8) CreateDirPathError!void { + _ = try io.vtable.dirCreateDirPath(io.userdata, dir, sub_path, .default_dir); } -pub const MakePathStatus = enum { existed, created }; +pub const CreatePathStatus = enum { existed, created }; -/// Same as `makePath` except returns whether the path already existed or was +/// Same as `createDirPath` except returns whether the path already existed or was /// successfully created. -pub fn makePathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) MakePathError!MakePathStatus { - return io.vtable.dirMakePath(io.userdata, dir, sub_path, permissions); +pub fn createDirPathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) CreateDirPathError!CreatePathStatus { + return io.vtable.dirCreateDirPath(io.userdata, dir, sub_path, permissions); } -pub const MakeOpenPathError = MakeError || OpenError || StatFileError; +pub const CreateDirPathOpenError = CreateDirError || OpenError || StatFileError; -pub const MakeOpenPathOptions = struct { +pub const CreateDirPathOpenOptions = struct { open_options: OpenOptions = .{}, permissions: Permissions = .default_dir, }; -/// Performs the equivalent of `makePath` followed by `openDir`, atomically if possible. +/// Performs the equivalent of `createDirPath` followed by `openDir`, atomically if possible. /// /// When this operation is canceled, it may leave the file system in a /// partially modified state. @@ -738,8 +738,8 @@ pub const MakeOpenPathOptions = struct { /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). /// On WASI, `sub_path` should be encoded as valid UTF-8. /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. -pub fn makeOpenPath(dir: Dir, io: Io, sub_path: []const u8, options: MakeOpenPathOptions) MakeOpenPathError!Dir { - return io.vtable.dirMakeOpenPath(io.userdata, dir, sub_path, options.permissions, options.open_options); +pub fn createDirPathOpen(dir: Dir, io: Io, sub_path: []const u8, options: CreateDirPathOpenOptions) CreateDirPathOpenError!Dir { + return io.vtable.dirCreateDirPathOpen(io.userdata, dir, sub_path, options.permissions, options.open_options); } pub const Stat = File.Stat; @@ -1729,7 +1729,7 @@ pub const AtomicFileOptions = struct { pub fn atomicFile(parent: Dir, io: Io, dest_path: []const u8, options: AtomicFileOptions) !File.Atomic { if (path.dirname(dest_path)) |dirname| { const dir = if (options.make_path) - try parent.makeOpenPath(io, dirname, .{}) + try parent.createDirPathOpen(io, dirname, .{}) else try parent.openDir(io, dirname, .{}); diff --git a/lib/std/Io/Kqueue.zig b/lib/std/Io/Kqueue.zig index 9f9403d5ad..26b8298cab 100644 --- a/lib/std/Io/Kqueue.zig +++ b/lib/std/Io/Kqueue.zig @@ -869,9 +869,9 @@ pub fn io(k: *Kqueue) Io { .conditionWaitUncancelable = conditionWaitUncancelable, .conditionWake = conditionWake, - .dirMake = dirMake, - .dirMakePath = dirMakePath, - .dirMakeOpenPath = dirMakeOpenPath, + .dirCreateDir = dirCreateDir, + .dirCreateDirPath = dirCreateDirPath, + .dirCreateDirPathOpen = dirCreateDirPathOpen, .dirStat = dirStat, .dirStatFile = dirStatFile, @@ -1114,7 +1114,7 @@ fn conditionWake(userdata: ?*anyopaque, cond: *Io.Condition, wake: Io.Condition. k.yield(waiting_fiber, .reschedule); } -fn dirMake(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.MakeError!void { +fn dirCreateDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.CreateDirError!void { const k: *Kqueue = @ptrCast(@alignCast(userdata)); _ = k; _ = dir; @@ -1122,7 +1122,7 @@ fn dirMake(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode _ = mode; @panic("TODO"); } -fn dirMakePath(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.MakeError!void { +fn dirCreateDirPath(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.CreateDirError!void { const k: *Kqueue = @ptrCast(@alignCast(userdata)); _ = k; _ = dir; @@ -1130,7 +1130,7 @@ fn dirMakePath(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir. _ = mode; @panic("TODO"); } -fn dirMakeOpenPath(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.OpenOptions) Dir.MakeOpenPathError!Dir { +fn dirCreateDirPathOpen(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir { const k: *Kqueue = @ptrCast(@alignCast(userdata)); _ = k; _ = dir; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index f4d60b3934..4afd8d75d1 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -711,9 +711,9 @@ pub fn io(t: *Threaded) Io { .futexWaitUncancelable = futexWaitUncancelable, .futexWake = futexWake, - .dirMake = dirMake, - .dirMakePath = dirMakePath, - .dirMakeOpenPath = dirMakeOpenPath, + .dirCreateDir = dirCreateDir, + .dirCreateDirPath = dirCreateDirPath, + .dirCreateDirPathOpen = dirCreateDirPathOpen, .dirStat = dirStat, .dirStatFile = dirStatFile, .dirAccess = dirAccess, @@ -846,9 +846,9 @@ pub fn ioBasic(t: *Threaded) Io { .futexWaitUncancelable = futexWaitUncancelable, .futexWake = futexWake, - .dirMake = dirMake, - .dirMakePath = dirMakePath, - .dirMakeOpenPath = dirMakeOpenPath, + .dirCreateDir = dirCreateDir, + .dirCreateDirPath = dirCreateDirPath, + .dirCreateDirPathOpen = dirCreateDirPathOpen, .dirStat = dirStat, .dirStatFile = dirStatFile, .dirAccess = dirAccess, @@ -1507,13 +1507,13 @@ fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void { } } -const dirMake = switch (native_os) { - .windows => dirMakeWindows, - .wasi => dirMakeWasi, - else => dirMakePosix, +const dirCreateDir = switch (native_os) { + .windows => dirCreateDirWindows, + .wasi => dirCreateDirWasi, + else => dirCreateDirPosix, }; -fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { +fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); @@ -1559,8 +1559,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissio } } -fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { - if (builtin.link_libc) return dirMakePosix(userdata, dir, sub_path, permissions); +fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void { + if (builtin.link_libc) return dirCreateDirPosix(userdata, dir, sub_path, permissions); const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); try current_thread.beginSyscall(); @@ -1601,7 +1601,7 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permission } } -fn dirMakeWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { +fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); try current_thread.checkCancel(); @@ -1627,19 +1627,19 @@ fn dirMakeWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permiss windows.CloseHandle(sub_dir_handle); } -fn dirMakePath( +fn dirCreateDirPath( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions, -) Dir.MakePathError!Dir.MakePathStatus { +) Dir.CreateDirPathError!Dir.CreatePathStatus { const t: *Threaded = @ptrCast(@alignCast(userdata)); var it = std.fs.path.componentIterator(sub_path); - var status: Dir.MakePathStatus = .existed; + var status: Dir.CreatePathStatus = .existed; var component = it.last() orelse return error.BadPathName; while (true) { - if (dirMake(t, dir, component.path, permissions)) |_| { + if (dirCreateDir(t, dir, component.path, permissions)) |_| { status = .created; } else |err| switch (err) { error.PathAlreadyExists => { @@ -1659,37 +1659,37 @@ fn dirMakePath( } } -const dirMakeOpenPath = switch (native_os) { - .windows => dirMakeOpenPathWindows, - .wasi => dirMakeOpenPathWasi, - else => dirMakeOpenPathPosix, +const dirCreateDirPathOpen = switch (native_os) { + .windows => dirCreateDirPathOpenWindows, + .wasi => dirCreateDirPathOpenWasi, + else => dirCreateDirPathOpenPosix, }; -fn dirMakeOpenPathPosix( +fn dirCreateDirPathOpenPosix( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions, options: Dir.OpenOptions, -) Dir.MakeOpenPathError!Dir { +) Dir.CreateDirPathOpenError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const t_io = ioBasic(t); return dirOpenDirPosix(t, dir, sub_path, options) catch |err| switch (err) { error.FileNotFound => { - _ = try dir.makePathStatus(t_io, sub_path, permissions); + _ = try dir.createDirPathStatus(t_io, sub_path, permissions); return dirOpenDirPosix(t, dir, sub_path, options); }, else => |e| return e, }; } -fn dirMakeOpenPathWindows( +fn dirCreateDirPathOpenWindows( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions, options: Dir.OpenOptions, -) Dir.MakeOpenPathError!Dir { +) Dir.CreateDirPathOpenError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); const w = windows; @@ -1795,18 +1795,18 @@ fn dirMakeOpenPathWindows( } } -fn dirMakeOpenPathWasi( +fn dirCreateDirPathOpenWasi( userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions, options: Dir.OpenOptions, -) Dir.MakeOpenPathError!Dir { +) Dir.CreateDirPathOpenError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const t_io = ioBasic(t); return dirOpenDirWasi(t, dir, sub_path, options) catch |err| switch (err) { error.FileNotFound => { - _ = try dir.makePathStatus(t_io, sub_path, permissions); + _ = try dir.createDirPathStatus(t_io, sub_path, permissions); return dirOpenDirWasi(t, dir, sub_path, options); }, else => |e| return e, @@ -3352,11 +3352,6 @@ pub fn dirOpenDirWindows( } } -const MakeOpenDirAccessMaskWOptions = struct { - no_follow: bool, - create_disposition: u32, -}; - fn dirClose(userdata: ?*anyopaque, dirs: []const Dir) void { const t: *Threaded = @ptrCast(@alignCast(userdata)); _ = t; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 644a6fc52d..bcb9048e0e 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -226,7 +226,7 @@ test "Dir.readLink" { // test 3: relative path symlink const parent_file = ".." ++ Dir.path.sep_str ++ "target.txt"; const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); - var subdir = try ctx.dir.makeOpenPath(io, "subdir", .{}); + var subdir = try ctx.dir.createDirPathOpen(io, "subdir", .{}); defer subdir.close(io); try setupSymlink(io, subdir, canonical_parent_file, "relative-link.txt", .{}); try testReadLink(io, subdir, canonical_parent_file, "relative-link.txt"); @@ -411,7 +411,7 @@ test "openDir non-cwd parent '..'" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var subdir = try tmp.dir.makeOpenPath(io, "subdir", .{}); + var subdir = try tmp.dir.createDirPathOpen(io, "subdir", .{}); defer subdir.close(io); var dir = try subdir.openDir(io, "..", .{}); @@ -613,13 +613,13 @@ test "Dir.Iterator but dir is deleted during iteration" { defer tmp.cleanup(); // Create directory and setup an iterator for it - var subdir = try tmp.dir.makeOpenPath(io, "subdir", .{ .open_options = .{ .iterate = true } }); + var subdir = try tmp.dir.createDirPathOpen(io, "subdir", .{ .open_options = .{ .iterate = true } }); defer subdir.close(io); var iterator = subdir.iterate(); // Create something to iterate over within the subdir - try tmp.dir.makePath(io, "subdir" ++ Dir.path.sep_str ++ "b"); + try tmp.dir.createDirPath(io, "subdir" ++ Dir.path.sep_str ++ "b"); // Then, before iterating, delete the directory that we're iterating. // This is a contrived reproduction, but this could happen outside of the program, in another thread, etc. @@ -862,13 +862,13 @@ test "file operations on directories" { }.impl); } -test "makeOpenPath parent dirs do not exist" { +test "createDirPathOpen parent dirs do not exist" { const io = testing.io; var tmp_dir = tmpDir(.{}); defer tmp_dir.cleanup(); - var dir = try tmp_dir.dir.makeOpenPath(io, "root_dir/parent_dir/some_dir", .{}); + var dir = try tmp_dir.dir.createDirPathOpen(io, "root_dir/parent_dir/some_dir", .{}); dir.close(io); // double check that the full directory structure was created @@ -1016,7 +1016,7 @@ test "Dir.rename directory onto non-empty dir" { try ctx.dir.createDir(io, test_dir_path, .default_dir); - var target_dir = try ctx.dir.makeOpenPath(io, target_dir_path, .{}); + var target_dir = try ctx.dir.createDirPathOpen(io, target_dir_path, .{}); var file = try target_dir.createFile(io, "test_file", .{ .read = true }); file.close(io); target_dir.close(io); @@ -1155,9 +1155,9 @@ test "deleteTree does not follow symlinks" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath(io, "b"); + try tmp.dir.createDirPath(io, "b"); { - var a = try tmp.dir.makeOpenPath(io, "a", .{}); + var a = try tmp.dir.createDirPathOpen(io, "a", .{}); defer a.close(io); try setupSymlink(io, a, "../b", "b", .{ .is_directory = true }); @@ -1184,7 +1184,7 @@ test "deleteTree on a symlink" { try tmp.dir.access(io, "file", .{}); // Symlink to a directory - try tmp.dir.makePath(io, "dir"); + try tmp.dir.createDirPath(io, "dir"); try setupSymlink(io, tmp.dir, "dir", "dirlink", .{ .is_directory = true }); try tmp.dir.deleteTree(io, "dirlink"); @@ -1192,14 +1192,14 @@ test "deleteTree on a symlink" { try tmp.dir.access(io, "dir", .{}); } -test "makePath, put some files in it, deleteTree" { +test "createDirPath, put some files in it, deleteTree" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { const io = ctx.io; const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); - try ctx.dir.makePath(io, try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); + try ctx.dir.createDirPath(io, try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); try ctx.dir.writeFile(io, .{ .sub_path = try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", @@ -1215,14 +1215,14 @@ test "makePath, put some files in it, deleteTree" { }.impl); } -test "makePath, put some files in it, deleteTreeMinStackSize" { +test "createDirPath, put some files in it, deleteTreeMinStackSize" { try testWithAllSupportedPathTypes(struct { fn impl(ctx: *TestContext) !void { const io = ctx.io; const allocator = ctx.arena.allocator(); const dir_path = try ctx.transformPath("os_test_tmp"); - try ctx.dir.makePath(io, try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); + try ctx.dir.createDirPath(io, try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c" })); try ctx.dir.writeFile(io, .{ .sub_path = try Dir.path.join(allocator, &.{ "os_test_tmp", "b", "c", "file.txt" }), .data = "nonsense", @@ -1238,7 +1238,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" { }.impl); } -test "makePath in a directory that no longer exists" { +test "createDirPath in a directory that no longer exists" { if (native_os == .windows) return error.SkipZigTest; // Windows returns FileBusy if attempting to remove an open dir const io = testing.io; @@ -1247,10 +1247,10 @@ test "makePath in a directory that no longer exists" { defer tmp.cleanup(); try tmp.parent_dir.deleteTree(io, &tmp.sub_path); - try expectError(error.FileNotFound, tmp.dir.makePath(io, "sub-path")); + try expectError(error.FileNotFound, tmp.dir.createDirPath(io, "sub-path")); } -test "makePath but sub_path contains pre-existing file" { +test "createDirPath but sub_path contains pre-existing file" { const io = testing.io; var tmp = tmpDir(.{}); @@ -1259,7 +1259,7 @@ test "makePath but sub_path contains pre-existing file" { try tmp.dir.createDir(io, "foo", .default_dir); try tmp.dir.writeFile(io, .{ .sub_path = "foo/bar", .data = "" }); - try expectError(error.NotDir, tmp.dir.makePath(io, "foo/bar/baz")); + try expectError(error.NotDir, tmp.dir.createDirPath(io, "foo/bar/baz")); } fn expectDir(io: Io, dir: Dir, path: []const u8) !void { @@ -1279,7 +1279,7 @@ test "makepath existing directories" { try tmpA.createDir(io, "B", .default_dir); const testPath = "A" ++ Dir.path.sep_str ++ "B" ++ Dir.path.sep_str ++ "C"; - try tmp.dir.makePath(io, testPath); + try tmp.dir.createDirPath(io, testPath); try expectDir(io, tmp.dir, testPath); } @@ -1293,7 +1293,7 @@ test "makepath through existing valid symlink" { try tmp.dir.createDir(io, "realfolder", .default_dir); try setupSymlink(io, tmp.dir, "." ++ Dir.path.sep_str ++ "realfolder", "working-symlink", .{}); - try tmp.dir.makePath(io, "working-symlink" ++ Dir.path.sep_str ++ "in-realfolder"); + try tmp.dir.createDirPath(io, "working-symlink" ++ Dir.path.sep_str ++ "in-realfolder"); try expectDir(io, tmp.dir, "realfolder" ++ Dir.path.sep_str ++ "in-realfolder"); } @@ -1309,7 +1309,7 @@ test "makepath relative walks" { }); defer testing.allocator.free(relPath); - try tmp.dir.makePath(io, relPath); + try tmp.dir.createDirPath(io, relPath); // How .. is handled is different on Windows than non-Windows switch (native_os) { @@ -1348,7 +1348,7 @@ test "makepath ignores '.'" { }); defer testing.allocator.free(expectedPath); - try tmp.dir.makePath(io, dotPath); + try tmp.dir.createDirPath(io, dotPath); try expectDir(io, tmp.dir, expectedPath); } @@ -1358,7 +1358,7 @@ fn testFilenameLimits(io: Io, iterable_dir: Dir, maxed_filename: []const u8, max { try iterable_dir.writeFile(io, .{ .sub_path = maxed_filename, .data = "" }); - var maxed_dir = try iterable_dir.makeOpenPath(io, maxed_dirname, .{}); + var maxed_dir = try iterable_dir.createDirPathOpen(io, maxed_dirname, .{}); defer maxed_dir.close(io); try maxed_dir.writeFile(io, .{ .sub_path = maxed_filename, .data = "" }); @@ -1511,7 +1511,7 @@ test "access file" { const dir_path = try ctx.transformPath("os_test_tmp"); const file_path = try ctx.transformPath("os_test_tmp" ++ Dir.path.sep_str ++ "file.txt"); - try ctx.dir.makePath(io, dir_path); + try ctx.dir.createDirPath(io, dir_path); try expectError(error.FileNotFound, ctx.dir.access(io, file_path, .{})); try ctx.dir.writeFile(io, .{ .sub_path = file_path, .data = "" }); @@ -1527,7 +1527,7 @@ test "sendfile" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath(io, "os_test_tmp"); + try tmp.dir.createDirPath(io, "os_test_tmp"); var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); @@ -1574,7 +1574,7 @@ test "sendfile with buffered data" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try tmp.dir.makePath(io, "os_test_tmp"); + try tmp.dir.createDirPath(io, "os_test_tmp"); var dir = try tmp.dir.openDir(io, "os_test_tmp", .{}); defer dir.close(io); @@ -1851,7 +1851,7 @@ test "walker" { }); for (expected_paths.keys()) |key| { - try tmp.dir.makePath(io, key); + try tmp.dir.createDirPath(io, key); } var walker = try tmp.dir.walk(testing.allocator); @@ -1913,7 +1913,7 @@ test "selective walker, skip entries that start with ." { }); for (paths_to_create) |path| { - try tmp.dir.makePath(io, path); + try tmp.dir.createDirPath(io, path); } var walker = try tmp.dir.walkSelectively(testing.allocator); @@ -1959,8 +1959,8 @@ test "walker without fully iterating" { // Create 2 directories inside the tmp directory, but then only iterate once before breaking. // This ensures that walker doesn't try to close the initial directory when not fully iterating. - try tmp.dir.makePath(io, "a"); - try tmp.dir.makePath(io, "b"); + try tmp.dir.createDirPath(io, "a"); + try tmp.dir.createDirPath(io, "b"); var num_walked: usize = 0; while (try walker.next(io)) |_| { @@ -2109,8 +2109,8 @@ test "invalid UTF-8/WTF-8 paths" { try expectError(expected_err, ctx.dir.createDir(io, invalid_path, .default_dir)); - try expectError(expected_err, ctx.dir.makePath(io, invalid_path)); - try expectError(expected_err, ctx.dir.makeOpenPath(io, invalid_path, .{})); + try expectError(expected_err, ctx.dir.createDirPath(io, invalid_path)); + try expectError(expected_err, ctx.dir.createDirPathOpen(io, invalid_path, .{})); try expectError(expected_err, ctx.dir.openDir(io, invalid_path, .{})); @@ -2574,7 +2574,7 @@ test "hard link with different directories" { const target_name = "link-target"; const link_name = "newlink"; - const subdir = try tmp.dir.makeOpenPath(io, "subdir", .{}); + const subdir = try tmp.dir.createDirPathOpen(io, "subdir", .{}); defer tmp.dir.deleteFile(io, target_name) catch {}; try tmp.dir.writeFile(io, .{ .sub_path = target_name, .data = "example" }); diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 3997bc70cd..133dfc0293 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -1079,7 +1079,7 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDir } } -pub const MakeDirError = std.Io.Dir.MakeError; +pub const MakeDirError = std.Io.Dir.CreateDirError; /// Create a directory. /// `mode` is ignored on Windows and WASI. diff --git a/lib/std/tar.zig b/lib/std/tar.zig index d45aa99443..024a425919 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -606,7 +606,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp switch (file.kind) { .directory => { if (file_name.len > 0 and !options.exclude_empty_directories) { - try dir.makePath(io, file_name); + try dir.createDirPath(io, file_name); } }, .file => { @@ -642,7 +642,7 @@ fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, permissions: Io. const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { - try dir.makePath(io, dir_name); + try dir.createDirPath(io, dir_name); return try dir.createFile(io, file_name, .{ .exclusive = true, .permissions = permissions }); } } @@ -656,7 +656,7 @@ fn createDirAndSymlink(io: Io, dir: Io.Dir, link_name: []const u8, file_name: [] dir.symLink(io, link_name, file_name, .{}) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { - try dir.makePath(io, dir_name); + try dir.createDirPath(io, dir_name); return try dir.symLink(io, link_name, file_name, .{}); } } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index f3dd114af3..5b5ec852e9 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -635,12 +635,12 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir { _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes); const cwd = Io.Dir.cwd(); - var cache_dir = cwd.makeOpenPath(io, ".zig-cache", .{}) catch + var cache_dir = cwd.createDirPathOpen(io, ".zig-cache", .{}) catch @panic("unable to make tmp dir for testing: unable to make and open .zig-cache dir"); defer cache_dir.close(io); - const parent_dir = cache_dir.makeOpenPath(io, "tmp", .{}) catch + const parent_dir = cache_dir.createDirPathOpen(io, "tmp", .{}) catch @panic("unable to make tmp dir for testing: unable to make and open .zig-cache/tmp dir"); - const dir = parent_dir.makeOpenPath(io, &sub_path, .{ .open_options = opts }) catch + const dir = parent_dir.createDirPathOpen(io, &sub_path, .{ .open_options = opts }) catch @panic("unable to make tmp dir for testing: unable to make and open the tmp dir"); return .{ diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 770bfd8ae7..ff95587e7a 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -554,13 +554,13 @@ pub const Iterator = struct { if (filename[filename.len - 1] == '/') { if (self.uncompressed_size != 0) return error.ZipBadDirectorySize; - try dest.makePath(io, filename[0 .. filename.len - 1]); + try dest.createDirPath(io, filename[0 .. filename.len - 1]); return; } const out_file = blk: { if (std.fs.path.dirname(filename)) |dirname| { - var parent_dir = try dest.makeOpenPath(io, dirname, .{}); + var parent_dir = try dest.createDirPathOpen(io, dirname, .{}); defer parent_dir.close(io); const basename = std.fs.path.basename(filename); diff --git a/src/Compilation.zig b/src/Compilation.zig index dc254a36c5..8b840b8d45 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -832,7 +832,7 @@ pub const Directories = struct { const nonempty_path = if (path.len == 0) "." else path; const handle_or_err = switch (thing) { .@"zig lib" => Io.Dir.cwd().openDir(io, nonempty_path, .{}), - .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(io, nonempty_path, .{}), + .@"global cache", .@"local cache" => Io.Dir.cwd().createDirPathOpen(io, nonempty_path, .{}), }; return .{ .path = if (path.len == 0) null else path, @@ -1879,7 +1879,7 @@ pub const CreateDiagnostic = union(enum) { pub const CreateCachePath = struct { which: enum { local, global }, sub: []const u8, - err: (Io.Dir.MakeError || Io.Dir.OpenError || Io.Dir.StatFileError), + err: (Io.Dir.CreateDirError || Io.Dir.OpenError || Io.Dir.StatFileError), }; pub fn format(diag: CreateDiagnostic, w: *Writer) Writer.Error!void { switch (diag) { @@ -2120,7 +2120,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, cache.* = .{ .gpa = gpa, .io = io, - .manifest_dir = options.dirs.local_cache.handle.makeOpenPath(io, "h", .{}) catch |err| { + .manifest_dir = options.dirs.local_cache.handle.createDirPathOpen(io, "h", .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = "h", .err = err } }); }, }; @@ -2170,7 +2170,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, // to redundantly happen for each AstGen operation. const zir_sub_dir = "z"; - var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(io, zir_sub_dir, .{}) catch |err| { + var local_zir_dir = options.dirs.local_cache.handle.createDirPathOpen(io, zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } }); }; errdefer local_zir_dir.close(io); @@ -2178,7 +2178,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, .handle = local_zir_dir, .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), }; - var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(io, zir_sub_dir, .{}) catch |err| { + var global_zir_dir = options.dirs.global_cache.handle.createDirPathOpen(io, zir_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } }); }; errdefer global_zir_dir.close(io); @@ -2449,7 +2449,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, const digest = hash.final(); const artifact_sub_dir = "o" ++ fs.path.sep_str ++ digest; - var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(io, artifact_sub_dir, .{}) catch |err| { + var artifact_dir = options.dirs.local_cache.handle.createDirPathOpen(io, artifact_sub_dir, .{}) catch |err| { return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } }); }; errdefer artifact_dir.close(io); @@ -2917,7 +2917,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE tmp_dir_rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path}); - const handle = comp.dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}) catch |err| { + const handle = comp.dirs.local_cache.handle.createDirPathOpen(io, tmp_dir_sub_path, .{}) catch |err| { return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err }); }; break :d .{ .path = path, .handle = handle }; @@ -2998,7 +2998,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE tmp_dir_rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path}); - const handle = comp.dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}) catch |err| { + const handle = comp.dirs.local_cache.handle.createDirPathOpen(io, tmp_dir_sub_path, .{}) catch |err| { return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err }); }; break :d .{ .path = path, .handle = handle }; @@ -3437,7 +3437,7 @@ fn renameTmpIntoCache( continue; }, error.FileNotFound => { - try cache_directory.handle.makePath(io, "o"); + try cache_directory.handle.createDirPath(io, "o"); continue; }, else => |e| return e, @@ -5276,7 +5276,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { const io = comp.io; const docs_path = comp.resolveEmitPath(comp.emit_docs.?); - var out_dir = docs_path.root_dir.handle.makeOpenPath(io, docs_path.sub_path, .{}) catch |err| { + var out_dir = docs_path.root_dir.handle.createDirPathOpen(io, docs_path.sub_path, .{}) catch |err| { return comp.lockAndSetMiscFailure( .docs_copy, "unable to create output directory '{f}': {s}", @@ -5513,7 +5513,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU assert(docs_bin_file.sub_path.len > 0); // emitted binary is not a directory const docs_path = comp.resolveEmitPath(comp.emit_docs.?); - var out_dir = docs_path.root_dir.handle.makeOpenPath(io, docs_path.sub_path, .{}) catch |err| { + var out_dir = docs_path.root_dir.handle.createDirPathOpen(io, docs_path.sub_path, .{}) catch |err| { comp.lockAndSetMiscFailure( .docs_copy, "unable to create output directory '{f}': {t}", @@ -5705,7 +5705,7 @@ pub fn translateC( const tmp_basename = std.fmt.hex(std.crypto.random.int(u64)); const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename; const cache_dir = comp.dirs.local_cache.handle; - var cache_tmp_dir = try cache_dir.makeOpenPath(io, tmp_sub_path, .{}); + var cache_tmp_dir = try cache_dir.createDirPathOpen(io, tmp_sub_path, .{}); defer cache_tmp_dir.close(io); const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename }); @@ -6280,7 +6280,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr // We can't know the digest until we do the C compiler invocation, // so we need a temporary filename. const out_obj_path = try comp.tmpFilePath(arena, o_basename); - var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, "tmp", .{}); + var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, "tmp", .{}); defer zig_cache_tmp_dir.close(io); const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) @@ -6445,7 +6445,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr // Rename into place. const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_obj_path); try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io); @@ -6534,7 +6534,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const digest = man.final(); const o_sub_path = try fs.path.join(arena, &.{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{}); defer o_dir.close(io); const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ @@ -6622,7 +6622,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 const rc_basename_noext = src_basename[0 .. src_basename.len - fs.path.extension(src_basename).len]; const digest = if (try man.hit()) man.final() else blk: { - var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, "tmp", .{}); + var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, "tmp", .{}); defer zig_cache_tmp_dir.close(io); const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); @@ -6693,7 +6693,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 // Rename into place. const digest = man.final(); const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(io, o_sub_path, .{}); + var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{}); defer o_dir.close(io); const tmp_basename = fs.path.basename(out_res_path); try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename, io); diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 45fcd66b8c..8a11736e42 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -500,7 +500,7 @@ fn runResource( var tmp_directory: Cache.Directory = .{ .path = tmp_directory_path, .handle = handle: { - const dir = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ + const dir = cache_root.handle.createDirPathOpen(io, tmp_dir_sub_path, .{ .open_options = .{ .iterate = true }, }) catch |err| { try eb.addRootErrorMessage(.{ @@ -524,7 +524,7 @@ fn runResource( if (native_os == .linux and f.job_queue.work_around_btrfs_bug) { // https://github.com/ziglang/zig/issues/17095 pkg_path.root_dir.handle.close(io); - pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(io, tmp_dir_sub_path, .{ + pkg_path.root_dir.handle = cache_root.handle.createDirPathOpen(io, tmp_dir_sub_path, .{ .open_options = .{ .iterate = true }, }) catch @panic("btrfs workaround failed"); } @@ -1366,7 +1366,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U // we do not attempt to replicate the exact structure of a real .git // directory, since that isn't relevant for fetching a package. { - var pack_dir = try out_dir.makeOpenPath(io, ".git", .{}); + var pack_dir = try out_dir.createDirPathOpen(io, ".git", .{}); defer pack_dir.close(io); var pack_file = try pack_dir.createFile(io, "pkg.pack", .{ .read = true }); defer pack_file.close(io); @@ -1427,7 +1427,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void .file => { dir.copyFile(entry.path, tmp_dir, entry.path, io, .{}) catch |err| switch (err) { error.FileNotFound => { - if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); + if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.createDirPath(io, dirname); try dir.copyFile(entry.path, tmp_dir, entry.path, io, .{}); }, else => |e| return e, @@ -1440,7 +1440,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void // the destination directory, fail with an error instead. tmp_dir.symLink(io, link_name, entry.path, .{}) catch |err| switch (err) { error.FileNotFound => { - if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); + if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.createDirPath(io, dirname); try tmp_dir.symLink(io, link_name, entry.path, .{}); }, else => |e| return e, @@ -2250,7 +2250,7 @@ const TestFetchBuilder = struct { cache_parent_dir: std.Io.Dir, path_or_url: []const u8, ) !*Fetch { - const cache_dir = try cache_parent_dir.makeOpenPath(io, "zig-global-cache", .{}); + const cache_dir = try cache_parent_dir.createDirPathOpen(io, "zig-global-cache", .{}); self.http_client = .{ .allocator = allocator, .io = io }; self.global_cache_directory = .{ .handle = cache_dir, .path = null }; diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index eb3d2a447e..f241f768f6 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -1720,10 +1720,10 @@ pub fn main() !void { var pack_file_reader = pack_file.reader(io, &pack_file_buffer); const commit = try Oid.parse(format, args[3]); - var worktree = try Io.Dir.cwd().makeOpenPath(io, args[4], .{}); + var worktree = try Io.Dir.cwd().createDirPathOpen(io, args[4], .{}); defer worktree.close(io); - var git_dir = try worktree.makeOpenPath(io, ".git", .{}); + var git_dir = try worktree.createDirPathOpen(io, ".git", .{}); defer git_dir.close(io); std.debug.print("Starting index...\n", .{}); diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index 44676007e2..ba85f45830 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -444,7 +444,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -477,7 +477,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index 8371b3288d..e9b6ce1882 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -679,7 +679,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -712,7 +712,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index c4b002f983..03ed917c4f 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -258,7 +258,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -297,7 +297,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const digest = man.final(); const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); - var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}); + var o_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}); defer o_dir.close(io); const aro = @import("aro"); diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index 9c09c35b0a..9e4213d237 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -385,7 +385,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye var cache: Cache = .{ .gpa = gpa, .io = io, - .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath(io, "h", .{}), + .manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}), }; cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); @@ -418,7 +418,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); var o_directory: Cache.Directory = .{ - .handle = try comp.dirs.global_cache.handle.makeOpenPath(io, o_sub_path, .{}), + .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}), .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), }; defer o_directory.handle.close(io); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 513c857dbf..97493ada32 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3319,7 +3319,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { ); defer gpa.free(d_sym_path); - var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(io, d_sym_path, .{}); + var d_sym_bundle = try self.base.emit.root_dir.handle.createDirPathOpen(io, d_sym_path, .{}); defer d_sym_bundle.close(io); self.d_sym.?.file = try d_sym_bundle.createFile(io, fs.path.basename(self.base.emit.sub_path), .{ diff --git a/src/main.zig b/src/main.zig index fb2a8cfe0f..507b01ab0e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3381,7 +3381,7 @@ fn buildOutputType( const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ std.crypto.random.int(u64), ext.canonicalName(target), }); - try dirs.local_cache.handle.makePath(io, "tmp"); + try dirs.local_cache.handle.createDirPath(io, "tmp"); // Note that in one of the happy paths, execve() is used to switch to // clang in which case any cleanup logic that exists for this temporary @@ -6955,7 +6955,7 @@ fn cmdFetch( var global_cache_directory: Directory = l: { const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); break :l .{ - .handle = try Io.Dir.cwd().makeOpenPath(io, p, .{}), + .handle = try Io.Dir.cwd().createDirPathOpen(io, p, .{}), .path = p, }; }; @@ -7201,7 +7201,7 @@ fn createDependenciesModule( const rand_int = std.crypto.random.int(u64); const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); { - var tmp_dir = try dirs.local_cache.handle.makeOpenPath(io, tmp_dir_sub_path, .{}); + var tmp_dir = try dirs.local_cache.handle.createDirPathOpen(io, tmp_dir_sub_path, .{}); defer tmp_dir.close(io); try tmp_dir.writeFile(io, .{ .sub_path = basename, .data = source }); } @@ -7396,7 +7396,7 @@ const Templates = struct { fingerprint: Package.Fingerprint, ) !void { if (fs.path.dirname(template_path)) |dirname| { - out_dir.makePath(io, dirname) catch |err| { + out_dir.createDirPath(io, dirname) catch |err| { fatal("unable to make path '{s}': {t}", .{ dirname, err }); }; } -- cgit v1.2.3 From 187d0a692de2f00e64a446548873f7a12d9ddb4f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 22 Dec 2025 17:29:28 -0800 Subject: compiler: handle cancelation from finishPrelinkQueue --- src/Compilation.zig | 4 +++- src/InternPool.zig | 1 - src/link/Queue.zig | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 8b840b8d45..8e005992ec 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5056,7 +5056,9 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node } prelink_group.wait(io); - comp.link_queue.finishPrelinkQueue(comp); + comp.link_queue.finishPrelinkQueue(comp) catch |err| switch (err) { + error.Canceled => return, + }; } const JobError = Allocator.Error || Io.Cancelable; diff --git a/src/InternPool.zig b/src/InternPool.zig index 3076aa2cf3..69a64cbc45 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11,7 +11,6 @@ const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; const Cache = std.Build.Cache; -const Io = std.Io; const Limb = std.math.big.Limb; const Hash = std.hash.Wyhash; const Zir = std.zig.Zir; diff --git a/src/link/Queue.zig b/src/link/Queue.zig index caa2cc1898..b716800bae 100644 --- a/src/link/Queue.zig +++ b/src/link/Queue.zig @@ -121,7 +121,7 @@ pub fn enqueueZcu( link.doZcuTask(comp, tid, task); } -pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) void { +pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) Io.Cancelable!void { if (q.future != null) { q.prelink_queue.close(comp.io); return; @@ -136,6 +136,7 @@ pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) void { } else |err| switch (err) { error.OutOfMemory => comp.link_diags.setAllocFailure(), error.LinkFailure => {}, + error.Canceled => |e| return e, } } } -- cgit v1.2.3