update all openDir() sites to accept io instance

This commit is contained in:
Andrew Kelley 2025-12-08 13:46:29 -08:00
parent a21bc31006
commit dda7560d7a
21 changed files with 107 additions and 92 deletions

View file

@ -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 } },
};
}

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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),
});

View file

@ -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 {

View file

@ -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),
});

View file

@ -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),
});

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);

View file

@ -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,

View file

@ -337,7 +337,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);
}
}
@ -416,7 +416,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
}
@ -439,7 +439,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, ".");
@ -806,7 +806,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)) {
@ -869,7 +869,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);
@ -885,7 +885,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);
}
@ -972,8 +972,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 });
@ -984,8 +984,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);
@ -1009,8 +1009,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);
@ -1037,7 +1037,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);
@ -1131,8 +1131,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);
}
@ -1200,6 +1200,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");
@ -1214,7 +1215,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);
}
@ -1222,6 +1223,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");
@ -1236,7 +1238,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);
}
@ -1262,7 +1264,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);
}
@ -1273,7 +1275,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");
@ -1535,7 +1537,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";
@ -1582,7 +1584,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 });
@ -1879,7 +1881,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;
}
@ -1947,7 +1949,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;
}
@ -1992,7 +1994,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, .{});
@ -2068,7 +2070,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);
@ -2090,7 +2092,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);
}

View file

@ -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" {

View file

@ -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,

View file

@ -746,6 +746,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) {
@ -769,7 +770,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) });
@ -777,22 +778,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,
};
@ -819,13 +820,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 .{
@ -5348,7 +5355,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 });
};

View file

@ -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.

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -710,7 +710,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);
@ -3301,7 +3301,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`.
@ -5117,7 +5117,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,
});
@ -5229,7 +5229,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),
});
@ -7048,7 +7048,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();
@ -7260,7 +7260,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)
@ -7269,7 +7269,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 .{
@ -7290,7 +7290,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 .{
@ -7473,7 +7473,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),
@ -7590,17 +7590,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;