| author | |
| committer | |
| log | aafddc2ea13e40a8262d9378aeca2e097a37ac03 |
| tree | 46770e51147a635a43c2e7356e62064466b51c34 |
| parent | eab354b2f5d7242c036523394023e9824be7eca9 |
75 files changed, 1014 insertions(+), 707 deletions(-)
build.zig+2-2| ... | @@ -1604,12 +1604,12 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath { | ... | @@ -1604,12 +1604,12 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath { |
| 1604 | b.build_root, @errorName(err), | 1604 | b.build_root, @errorName(err), |
| 1605 | }); | 1605 | }); |
| 1606 | }; | 1606 | }; |
| 1607 | defer dir.close(); | 1607 | defer dir.close(io); |
| 1608 | 1608 | ||
| 1609 | var wf = b.addWriteFiles(); | 1609 | var wf = b.addWriteFiles(); |
| 1610 | 1610 | ||
| 1611 | var it = dir.iterateAssumeFirstIteration(); | 1611 | var it = dir.iterateAssumeFirstIteration(); |
| 1612 | while (it.next() catch @panic("failed to read dir")) |entry| { | 1612 | while (it.next(io) catch @panic("failed to read dir")) |entry| { |
| 1613 | if (std.mem.startsWith(u8, entry.name, ".") or entry.kind != .file) | 1613 | if (std.mem.startsWith(u8, entry.name, ".") or entry.kind != .file) |
| 1614 | continue; | 1614 | continue; |
| 1615 | 1615 |
lib/compiler/aro/aro/Compilation.zig+6-2| ... | @@ -1639,8 +1639,10 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin | ... | @@ -1639,8 +1639,10 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin |
| 1639 | return error.FileNotFound; | 1639 | return error.FileNotFound; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | const io = comp.io; | ||
| 1643 | |||
| 1642 | const file = try comp.cwd.openFile(path, .{}); | 1644 | const file = try comp.cwd.openFile(path, .{}); |
| 1643 | defer file.close(); | 1645 | defer file.close(io); |
| 1644 | return comp.addSourceFromFile(file, path, kind); | 1646 | return comp.addSourceFromFile(file, path, kind); |
| 1645 | } | 1647 | } |
| 1646 | 1648 | ||
| ... | @@ -1971,8 +1973,10 @@ fn getPathContents(comp: *Compilation, path: []const u8, limit: Io.Limit) ![]u8 | ... | @@ -1971,8 +1973,10 @@ fn getPathContents(comp: *Compilation, path: []const u8, limit: Io.Limit) ![]u8 |
| 1971 | return error.FileNotFound; | 1973 | return error.FileNotFound; |
| 1972 | } | 1974 | } |
| 1973 | 1975 | ||
| 1976 | const io = comp.io; | ||
| 1977 | |||
| 1974 | const file = try comp.cwd.openFile(path, .{}); | 1978 | const file = try comp.cwd.openFile(path, .{}); |
| 1975 | defer file.close(); | 1979 | defer file.close(io); |
| 1976 | return comp.getFileContents(file, limit); | 1980 | return comp.getFileContents(file, limit); |
| 1977 | } | 1981 | } |
| 1978 | 1982 |
lib/compiler/aro/aro/Driver.zig+7-5| ... | @@ -1286,6 +1286,8 @@ fn processSource( | ... | @@ -1286,6 +1286,8 @@ fn processSource( |
| 1286 | d.comp.generated_buf.items.len = 0; | 1286 | d.comp.generated_buf.items.len = 0; |
| 1287 | const prev_total = d.diagnostics.errors; | 1287 | const prev_total = d.diagnostics.errors; |
| 1288 | 1288 | ||
| 1289 | const io = d.comp.io; | ||
| 1290 | |||
| 1289 | var pp = try Preprocessor.initDefault(d.comp); | 1291 | var pp = try Preprocessor.initDefault(d.comp); |
| 1290 | defer pp.deinit(); | 1292 | defer pp.deinit(); |
| 1291 | 1293 | ||
| ... | @@ -1328,7 +1330,7 @@ fn processSource( | ... | @@ -1328,7 +1330,7 @@ fn processSource( |
| 1328 | return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) }) | 1330 | return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) }) |
| 1329 | else | 1331 | else |
| 1330 | std.fs.File.stdout(); | 1332 | std.fs.File.stdout(); |
| 1331 | defer if (dep_file_name != null) file.close(); | 1333 | defer if (dep_file_name != null) file.close(io); |
| 1332 | 1334 | ||
| 1333 | var file_writer = file.writer(&writer_buf); | 1335 | var file_writer = file.writer(&writer_buf); |
| 1334 | dep_file.write(&file_writer.interface) catch | 1336 | dep_file.write(&file_writer.interface) catch |
| ... | @@ -1353,7 +1355,7 @@ fn processSource( | ... | @@ -1353,7 +1355,7 @@ fn processSource( |
| 1353 | return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) | 1355 | return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) |
| 1354 | else | 1356 | else |
| 1355 | std.fs.File.stdout(); | 1357 | std.fs.File.stdout(); |
| 1356 | defer if (d.output_name != null) file.close(); | 1358 | defer if (d.output_name != null) file.close(io); |
| 1357 | 1359 | ||
| 1358 | var file_writer = file.writer(&writer_buf); | 1360 | var file_writer = file.writer(&writer_buf); |
| 1359 | pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch | 1361 | pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch |
| ... | @@ -1404,7 +1406,7 @@ fn processSource( | ... | @@ -1404,7 +1406,7 @@ fn processSource( |
| 1404 | if (d.only_preprocess_and_compile) { | 1406 | if (d.only_preprocess_and_compile) { |
| 1405 | const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| | 1407 | const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| |
| 1406 | return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); | 1408 | return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); |
| 1407 | defer out_file.close(); | 1409 | defer out_file.close(io); |
| 1408 | 1410 | ||
| 1409 | assembly.writeToFile(out_file) catch |er| | 1411 | assembly.writeToFile(out_file) catch |er| |
| 1410 | return d.fatal("unable to write to output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); | 1412 | return d.fatal("unable to write to output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); |
| ... | @@ -1418,7 +1420,7 @@ fn processSource( | ... | @@ -1418,7 +1420,7 @@ fn processSource( |
| 1418 | const assembly_out_file_name = try d.getRandomFilename(&assembly_name_buf, ".s"); | 1420 | const assembly_out_file_name = try d.getRandomFilename(&assembly_name_buf, ".s"); |
| 1419 | const out_file = d.comp.cwd.createFile(assembly_out_file_name, .{}) catch |er| | 1421 | const out_file = d.comp.cwd.createFile(assembly_out_file_name, .{}) catch |er| |
| 1420 | return d.fatal("unable to create output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); | 1422 | return d.fatal("unable to create output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); |
| 1421 | defer out_file.close(); | 1423 | defer out_file.close(io); |
| 1422 | assembly.writeToFile(out_file) catch |er| | 1424 | assembly.writeToFile(out_file) catch |er| |
| 1423 | return d.fatal("unable to write to output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); | 1425 | return d.fatal("unable to write to output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); |
| 1424 | try d.invokeAssembler(tc, assembly_out_file_name, out_file_name); | 1426 | try d.invokeAssembler(tc, assembly_out_file_name, out_file_name); |
| ... | @@ -1454,7 +1456,7 @@ fn processSource( | ... | @@ -1454,7 +1456,7 @@ fn processSource( |
| 1454 | 1456 | ||
| 1455 | const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| | 1457 | const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| |
| 1456 | return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); | 1458 | return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); |
| 1457 | defer out_file.close(); | 1459 | defer out_file.close(io); |
| 1458 | 1460 | ||
| 1459 | var file_writer = out_file.writer(&writer_buf); | 1461 | var file_writer = out_file.writer(&writer_buf); |
| 1460 | obj.finish(&file_writer.interface) catch | 1462 | obj.finish(&file_writer.interface) catch |
lib/compiler/aro/aro/Driver/Filesystem.zig+15-13| ... | @@ -1,8 +1,10 @@ | ... | @@ -1,8 +1,10 @@ |
| 1 | const std = @import("std"); | ||
| 2 | const mem = std.mem; | ||
| 3 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 4 | const is_windows = builtin.os.tag == .windows; | 2 | const is_windows = builtin.os.tag == .windows; |
| 5 | 3 | ||
| 4 | const std = @import("std"); | ||
| 5 | const Io = std.Io; | ||
| 6 | const mem = std.std.mem; | ||
| 7 | |||
| 6 | fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 { | 8 | fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 { |
| 7 | @branchHint(.cold); | 9 | @branchHint(.cold); |
| 8 | for (entries) |entry| { | 10 | for (entries) |entry| { |
| ... | @@ -96,7 +98,7 @@ fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]con | ... | @@ -96,7 +98,7 @@ fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]con |
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | pub const Filesystem = union(enum) { | 100 | pub const Filesystem = union(enum) { |
| 99 | real: std.fs.Dir, | 101 | real: std.Io.Dir, |
| 100 | fake: []const Entry, | 102 | fake: []const Entry, |
| 101 | 103 | ||
| 102 | const Entry = struct { | 104 | const Entry = struct { |
| ... | @@ -121,7 +123,7 @@ pub const Filesystem = union(enum) { | ... | @@ -121,7 +123,7 @@ pub const Filesystem = union(enum) { |
| 121 | base: []const u8, | 123 | base: []const u8, |
| 122 | i: usize = 0, | 124 | i: usize = 0, |
| 123 | 125 | ||
| 124 | fn next(self: *@This()) !?std.fs.Dir.Entry { | 126 | fn next(self: *@This()) !?std.Io.Dir.Entry { |
| 125 | while (self.i < self.entries.len) { | 127 | while (self.i < self.entries.len) { |
| 126 | const entry = self.entries[self.i]; | 128 | const entry = self.entries[self.i]; |
| 127 | self.i += 1; | 129 | self.i += 1; |
| ... | @@ -130,7 +132,7 @@ pub const Filesystem = union(enum) { | ... | @@ -130,7 +132,7 @@ pub const Filesystem = union(enum) { |
| 130 | const remaining = entry.path[self.base.len + 1 ..]; | 132 | const remaining = entry.path[self.base.len + 1 ..]; |
| 131 | if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue; | 133 | if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue; |
| 132 | const extension = std.fs.path.extension(remaining); | 134 | const extension = std.fs.path.extension(remaining); |
| 133 | const kind: std.fs.Dir.Entry.Kind = if (extension.len == 0) .directory else .file; | 135 | const kind: std.Io.Dir.Entry.Kind = if (extension.len == 0) .directory else .file; |
| 134 | return .{ .name = remaining, .kind = kind }; | 136 | return .{ .name = remaining, .kind = kind }; |
| 135 | } | 137 | } |
| 136 | } | 138 | } |
| ... | @@ -140,7 +142,7 @@ pub const Filesystem = union(enum) { | ... | @@ -140,7 +142,7 @@ pub const Filesystem = union(enum) { |
| 140 | }; | 142 | }; |
| 141 | 143 | ||
| 142 | const Dir = union(enum) { | 144 | const Dir = union(enum) { |
| 143 | dir: std.fs.Dir, | 145 | dir: std.Io.Dir, |
| 144 | fake: FakeDir, | 146 | fake: FakeDir, |
| 145 | 147 | ||
| 146 | pub fn iterate(self: Dir) Iterator { | 148 | pub fn iterate(self: Dir) Iterator { |
| ... | @@ -150,19 +152,19 @@ pub const Filesystem = union(enum) { | ... | @@ -150,19 +152,19 @@ pub const Filesystem = union(enum) { |
| 150 | }; | 152 | }; |
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | pub fn close(self: *Dir) void { | 155 | pub fn close(self: *Dir, io: Io) void { |
| 154 | switch (self.*) { | 156 | switch (self.*) { |
| 155 | .dir => |*d| d.close(), | 157 | .dir => |*d| d.close(io), |
| 156 | .fake => {}, | 158 | .fake => {}, |
| 157 | } | 159 | } |
| 158 | } | 160 | } |
| 159 | }; | 161 | }; |
| 160 | 162 | ||
| 161 | const Iterator = union(enum) { | 163 | const Iterator = union(enum) { |
| 162 | iterator: std.fs.Dir.Iterator, | 164 | iterator: std.Io.Dir.Iterator, |
| 163 | fake: FakeDir.Iterator, | 165 | fake: FakeDir.Iterator, |
| 164 | 166 | ||
| 165 | pub fn next(self: *Iterator) std.fs.Dir.Iterator.Error!?std.fs.Dir.Entry { | 167 | pub fn next(self: *Iterator) std.Io.Dir.Iterator.Error!?std.Io.Dir.Entry { |
| 166 | return switch (self.*) { | 168 | return switch (self.*) { |
| 167 | .iterator => |*it| it.next(), | 169 | .iterator => |*it| it.next(), |
| 168 | .fake => |*it| it.next(), | 170 | .fake => |*it| it.next(), |
| ... | @@ -208,11 +210,11 @@ pub const Filesystem = union(enum) { | ... | @@ -208,11 +210,11 @@ pub const Filesystem = union(enum) { |
| 208 | /// Read the file at `path` into `buf`. | 210 | /// Read the file at `path` into `buf`. |
| 209 | /// Returns null if any errors are encountered | 211 | /// Returns null if any errors are encountered |
| 210 | /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned | 212 | /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned |
| 211 | pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 { | 213 | pub fn readFile(fs: Filesystem, io: Io, path: []const u8, buf: []u8) ?[]const u8 { |
| 212 | return switch (fs) { | 214 | return switch (fs) { |
| 213 | .real => |cwd| { | 215 | .real => |cwd| { |
| 214 | const file = cwd.openFile(path, .{}) catch return null; | 216 | const file = cwd.openFile(path, .{}) catch return null; |
| 215 | defer file.close(); | 217 | defer file.close(io); |
| 216 | 218 | ||
| 217 | const bytes_read = file.readAll(buf) catch return null; | 219 | const bytes_read = file.readAll(buf) catch return null; |
| 218 | return buf[0..bytes_read]; | 220 | return buf[0..bytes_read]; |
| ... | @@ -221,7 +223,7 @@ pub const Filesystem = union(enum) { | ... | @@ -221,7 +223,7 @@ pub const Filesystem = union(enum) { |
| 221 | }; | 223 | }; |
| 222 | } | 224 | } |
| 223 | 225 | ||
| 224 | pub fn openDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!Dir { | 226 | pub fn openDir(fs: Filesystem, dir_name: []const u8) std.Io.Dir.OpenError!Dir { |
| 225 | return switch (fs) { | 227 | return switch (fs) { |
| 226 | .real => |cwd| .{ .dir = try cwd.openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) }, | 228 | .real => |cwd| .{ .dir = try cwd.openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) }, |
| 227 | .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } }, | 229 | .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } }, |
lib/compiler/aro/aro/Toolchain.zig+2-1| ... | @@ -497,6 +497,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { | ... | @@ -497,6 +497,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { |
| 497 | const comp = d.comp; | 497 | const comp = d.comp; |
| 498 | const gpa = comp.gpa; | 498 | const gpa = comp.gpa; |
| 499 | const arena = comp.arena; | 499 | const arena = comp.arena; |
| 500 | const io = comp.io; | ||
| 500 | try d.includes.ensureUnusedCapacity(gpa, 1); | 501 | try d.includes.ensureUnusedCapacity(gpa, 1); |
| 501 | if (d.resource_dir) |resource_dir| { | 502 | if (d.resource_dir) |resource_dir| { |
| 502 | const path = try std.fs.path.join(arena, &.{ resource_dir, "include" }); | 503 | const path = try std.fs.path.join(arena, &.{ resource_dir, "include" }); |
| ... | @@ -509,7 +510,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { | ... | @@ -509,7 +510,7 @@ pub fn addBuiltinIncludeDir(tc: *const Toolchain) !void { |
| 509 | var search_path = d.aro_name; | 510 | var search_path = d.aro_name; |
| 510 | while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) { | 511 | while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) { |
| 511 | var base_dir = d.comp.cwd.openDir(dirname, .{}) catch continue; | 512 | var base_dir = d.comp.cwd.openDir(dirname, .{}) catch continue; |
| 512 | defer base_dir.close(); | 513 | defer base_dir.close(io); |
| 513 | 514 | ||
| 514 | base_dir.access("include/stddef.h", .{}) catch continue; | 515 | base_dir.access("include/stddef.h", .{}) catch continue; |
| 515 | const path = try std.fs.path.join(arena, &.{ dirname, "include" }); | 516 | const path = try std.fs.path.join(arena, &.{ dirname, "include" }); |
lib/compiler/objcopy.zig+2-2| ... | @@ -152,7 +152,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void | ... | @@ -152,7 +152,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 152 | const io = threaded.io(); | 152 | const io = threaded.io(); |
| 153 | 153 | ||
| 154 | const input_file = fs.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); | 154 | const input_file = fs.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); |
| 155 | defer input_file.close(); | 155 | defer input_file.close(io); |
| 156 | 156 | ||
| 157 | const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); | 157 | const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); |
| 158 | 158 | ||
| ... | @@ -180,7 +180,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void | ... | @@ -180,7 +180,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 180 | const mode = if (out_fmt != .elf or only_keep_debug) fs.File.default_mode else stat.mode; | 180 | const mode = if (out_fmt != .elf or only_keep_debug) fs.File.default_mode else stat.mode; |
| 181 | 181 | ||
| 182 | var output_file = try fs.cwd().createFile(output, .{ .mode = mode }); | 182 | var output_file = try fs.cwd().createFile(output, .{ .mode = mode }); |
| 183 | defer output_file.close(); | 183 | defer output_file.close(io); |
| 184 | 184 | ||
| 185 | var out = output_file.writer(&output_buffer); | 185 | var out = output_file.writer(&output_buffer); |
| 186 | 186 |
lib/compiler/resinator/cli.zig+3-1| ... | @@ -1991,6 +1991,8 @@ test "parse: input and output formats" { | ... | @@ -1991,6 +1991,8 @@ test "parse: input and output formats" { |
| 1991 | } | 1991 | } |
| 1992 | 1992 | ||
| 1993 | test "maybeAppendRC" { | 1993 | test "maybeAppendRC" { |
| 1994 | const io = std.testing.io; | ||
| 1995 | |||
| 1994 | var tmp = std.testing.tmpDir(.{}); | 1996 | var tmp = std.testing.tmpDir(.{}); |
| 1995 | defer tmp.cleanup(); | 1997 | defer tmp.cleanup(); |
| 1996 | 1998 | ||
| ... | @@ -2001,7 +2003,7 @@ test "maybeAppendRC" { | ... | @@ -2001,7 +2003,7 @@ test "maybeAppendRC" { |
| 2001 | // Create the file so that it's found. In this scenario, .rc should not get | 2003 | // Create the file so that it's found. In this scenario, .rc should not get |
| 2002 | // appended. | 2004 | // appended. |
| 2003 | var file = try tmp.dir.createFile("foo", .{}); | 2005 | var file = try tmp.dir.createFile("foo", .{}); |
| 2004 | file.close(); | 2006 | file.close(io); |
| 2005 | try options.maybeAppendRC(tmp.dir); | 2007 | try options.maybeAppendRC(tmp.dir); |
| 2006 | try std.testing.expectEqualStrings("foo", options.input_source.filename); | 2008 | try std.testing.expectEqualStrings("foo", options.input_source.filename); |
| 2007 | 2009 |
lib/compiler/resinator/compile.zig+18-16| ... | @@ -34,7 +34,7 @@ const code_pages = @import("code_pages.zig"); | ... | @@ -34,7 +34,7 @@ const code_pages = @import("code_pages.zig"); |
| 34 | const errors = @import("errors.zig"); | 34 | const errors = @import("errors.zig"); |
| 35 | 35 | ||
| 36 | pub const CompileOptions = struct { | 36 | pub const CompileOptions = struct { |
| 37 | cwd: std.fs.Dir, | 37 | cwd: std.Io.Dir, |
| 38 | diagnostics: *Diagnostics, | 38 | diagnostics: *Diagnostics, |
| 39 | source_mappings: ?*SourceMappings = null, | 39 | source_mappings: ?*SourceMappings = null, |
| 40 | /// List of paths (absolute or relative to `cwd`) for every file that the resources within the .rc file depend on. | 40 | /// List of paths (absolute or relative to `cwd`) for every file that the resources within the .rc file depend on. |
| ... | @@ -107,7 +107,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io | ... | @@ -107,7 +107,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io |
| 107 | // the cwd so we don't need to add it as a distinct search path. | 107 | // the cwd so we don't need to add it as a distinct search path. |
| 108 | if (std.fs.path.dirname(root_path)) |root_dir_path| { | 108 | if (std.fs.path.dirname(root_path)) |root_dir_path| { |
| 109 | var root_dir = try options.cwd.openDir(root_dir_path, .{}); | 109 | var root_dir = try options.cwd.openDir(root_dir_path, .{}); |
| 110 | errdefer root_dir.close(); | 110 | errdefer root_dir.close(io); |
| 111 | try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) }); | 111 | try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) }); |
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| ... | @@ -136,7 +136,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io | ... | @@ -136,7 +136,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io |
| 136 | // TODO: maybe a warning that the search path is skipped? | 136 | // TODO: maybe a warning that the search path is skipped? |
| 137 | continue; | 137 | continue; |
| 138 | }; | 138 | }; |
| 139 | errdefer dir.close(); | 139 | errdefer dir.close(io); |
| 140 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) }); | 140 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) }); |
| 141 | } | 141 | } |
| 142 | for (options.system_include_paths) |system_include_path| { | 142 | for (options.system_include_paths) |system_include_path| { |
| ... | @@ -144,7 +144,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io | ... | @@ -144,7 +144,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io |
| 144 | // TODO: maybe a warning that the search path is skipped? | 144 | // TODO: maybe a warning that the search path is skipped? |
| 145 | continue; | 145 | continue; |
| 146 | }; | 146 | }; |
| 147 | errdefer dir.close(); | 147 | errdefer dir.close(io); |
| 148 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) }); | 148 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) }); |
| 149 | } | 149 | } |
| 150 | if (!options.ignore_include_env_var) { | 150 | if (!options.ignore_include_env_var) { |
| ... | @@ -160,7 +160,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io | ... | @@ -160,7 +160,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io |
| 160 | var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter); | 160 | var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter); |
| 161 | while (it.next()) |search_path| { | 161 | while (it.next()) |search_path| { |
| 162 | var dir = openSearchPathDir(options.cwd, search_path) catch continue; | 162 | var dir = openSearchPathDir(options.cwd, search_path) catch continue; |
| 163 | errdefer dir.close(); | 163 | errdefer dir.close(io); |
| 164 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) }); | 164 | try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) }); |
| 165 | } | 165 | } |
| 166 | } | 166 | } |
| ... | @@ -196,7 +196,7 @@ pub const Compiler = struct { | ... | @@ -196,7 +196,7 @@ pub const Compiler = struct { |
| 196 | arena: Allocator, | 196 | arena: Allocator, |
| 197 | allocator: Allocator, | 197 | allocator: Allocator, |
| 198 | io: Io, | 198 | io: Io, |
| 199 | cwd: std.fs.Dir, | 199 | cwd: std.Io.Dir, |
| 200 | state: State = .{}, | 200 | state: State = .{}, |
| 201 | diagnostics: *Diagnostics, | 201 | diagnostics: *Diagnostics, |
| 202 | dependencies: ?*Dependencies, | 202 | dependencies: ?*Dependencies, |
| ... | @@ -388,7 +388,9 @@ pub const Compiler = struct { | ... | @@ -388,7 +388,9 @@ pub const Compiler = struct { |
| 388 | /// matching file is invalid. That is, it does not do the `cmd` PATH searching | 388 | /// matching file is invalid. That is, it does not do the `cmd` PATH searching |
| 389 | /// thing of continuing to look for matching files until it finds a valid | 389 | /// thing of continuing to look for matching files until it finds a valid |
| 390 | /// one if a matching file is invalid. | 390 | /// one if a matching file is invalid. |
| 391 | fn searchForFile(self: *Compiler, path: []const u8) !std.fs.File { | 391 | fn searchForFile(self: *Compiler, path: []const u8) !std.Io.File { |
| 392 | const io = self.io; | ||
| 393 | |||
| 392 | // If the path is absolute, then it is not resolved relative to any search | 394 | // If the path is absolute, then it is not resolved relative to any search |
| 393 | // paths, so there's no point in checking them. | 395 | // paths, so there's no point in checking them. |
| 394 | // | 396 | // |
| ... | @@ -405,7 +407,7 @@ pub const Compiler = struct { | ... | @@ -405,7 +407,7 @@ pub const Compiler = struct { |
| 405 | // an absolute path. | 407 | // an absolute path. |
| 406 | if (std.fs.path.isAbsolute(path)) { | 408 | if (std.fs.path.isAbsolute(path)) { |
| 407 | const file = try utils.openFileNotDir(std.fs.cwd(), path, .{}); | 409 | const file = try utils.openFileNotDir(std.fs.cwd(), path, .{}); |
| 408 | errdefer file.close(); | 410 | errdefer file.close(io); |
| 409 | 411 | ||
| 410 | if (self.dependencies) |dependencies| { | 412 | if (self.dependencies) |dependencies| { |
| 411 | const duped_path = try dependencies.allocator.dupe(u8, path); | 413 | const duped_path = try dependencies.allocator.dupe(u8, path); |
| ... | @@ -414,10 +416,10 @@ pub const Compiler = struct { | ... | @@ -414,10 +416,10 @@ pub const Compiler = struct { |
| 414 | } | 416 | } |
| 415 | } | 417 | } |
| 416 | 418 | ||
| 417 | var first_error: ?(std.fs.File.OpenError || std.fs.File.StatError) = null; | 419 | var first_error: ?(std.Io.File.OpenError || std.Io.File.StatError) = null; |
| 418 | for (self.search_dirs) |search_dir| { | 420 | for (self.search_dirs) |search_dir| { |
| 419 | if (utils.openFileNotDir(search_dir.dir, path, .{})) |file| { | 421 | if (utils.openFileNotDir(search_dir.dir, path, .{})) |file| { |
| 420 | errdefer file.close(); | 422 | errdefer file.close(io); |
| 421 | 423 | ||
| 422 | if (self.dependencies) |dependencies| { | 424 | if (self.dependencies) |dependencies| { |
| 423 | const searched_file_path = try std.fs.path.join(dependencies.allocator, &.{ | 425 | const searched_file_path = try std.fs.path.join(dependencies.allocator, &.{ |
| ... | @@ -587,7 +589,7 @@ pub const Compiler = struct { | ... | @@ -587,7 +589,7 @@ pub const Compiler = struct { |
| 587 | }); | 589 | }); |
| 588 | }, | 590 | }, |
| 589 | }; | 591 | }; |
| 590 | defer file_handle.close(); | 592 | defer file_handle.close(io); |
| 591 | var file_buffer: [2048]u8 = undefined; | 593 | var file_buffer: [2048]u8 = undefined; |
| 592 | var file_reader = file_handle.reader(io, &file_buffer); | 594 | var file_reader = file_handle.reader(io, &file_buffer); |
| 593 | 595 | ||
| ... | @@ -2892,9 +2894,9 @@ pub const Compiler = struct { | ... | @@ -2892,9 +2894,9 @@ pub const Compiler = struct { |
| 2892 | } | 2894 | } |
| 2893 | }; | 2895 | }; |
| 2894 | 2896 | ||
| 2895 | pub const OpenSearchPathError = std.fs.Dir.OpenError; | 2897 | pub const OpenSearchPathError = std.Io.Dir.OpenError; |
| 2896 | 2898 | ||
| 2897 | fn openSearchPathDir(dir: std.fs.Dir, path: []const u8) OpenSearchPathError!std.fs.Dir { | 2899 | fn openSearchPathDir(dir: std.Io.Dir, path: []const u8) OpenSearchPathError!std.Io.Dir { |
| 2898 | // Validate the search path to avoid possible unreachable on invalid paths, | 2900 | // Validate the search path to avoid possible unreachable on invalid paths, |
| 2899 | // see https://github.com/ziglang/zig/issues/15607 for why this is currently necessary. | 2901 | // see https://github.com/ziglang/zig/issues/15607 for why this is currently necessary. |
| 2900 | try validateSearchPath(path); | 2902 | try validateSearchPath(path); |
| ... | @@ -2927,11 +2929,11 @@ fn validateSearchPath(path: []const u8) error{BadPathName}!void { | ... | @@ -2927,11 +2929,11 @@ fn validateSearchPath(path: []const u8) error{BadPathName}!void { |
| 2927 | } | 2929 | } |
| 2928 | 2930 | ||
| 2929 | pub const SearchDir = struct { | 2931 | pub const SearchDir = struct { |
| 2930 | dir: std.fs.Dir, | 2932 | dir: std.Io.Dir, |
| 2931 | path: ?[]const u8, | 2933 | path: ?[]const u8, |
| 2932 | 2934 | ||
| 2933 | pub fn deinit(self: *SearchDir, allocator: Allocator) void { | 2935 | pub fn deinit(self: *SearchDir, allocator: Allocator, io: Io) void { |
| 2934 | self.dir.close(); | 2936 | self.dir.close(io); |
| 2935 | if (self.path) |path| { | 2937 | if (self.path) |path| { |
| 2936 | allocator.free(path); | 2938 | allocator.free(path); |
| 2937 | } | 2939 | } |
lib/compiler/resinator/errors.zig+2-2| ... | @@ -1221,8 +1221,8 @@ const CorrespondingLines = struct { | ... | @@ -1221,8 +1221,8 @@ const CorrespondingLines = struct { |
| 1221 | }; | 1221 | }; |
| 1222 | } | 1222 | } |
| 1223 | 1223 | ||
| 1224 | pub fn deinit(self: *CorrespondingLines) void { | 1224 | pub fn deinit(self: *CorrespondingLines, io: Io) void { |
| 1225 | self.file.close(); | 1225 | self.file.close(io); |
| 1226 | } | 1226 | } |
| 1227 | }; | 1227 | }; |
| 1228 | 1228 |
lib/compiler/resinator/main.zig+7-7| ... | @@ -296,7 +296,7 @@ pub fn main() !void { | ... | @@ -296,7 +296,7 @@ pub fn main() !void { |
| 296 | error.ParseError, error.CompileError => { | 296 | error.ParseError, error.CompileError => { |
| 297 | try error_handler.emitDiagnostics(gpa, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings); | 297 | try error_handler.emitDiagnostics(gpa, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings); |
| 298 | // Delete the output file on error | 298 | // Delete the output file on error |
| 299 | res_stream.cleanupAfterError(); | 299 | res_stream.cleanupAfterError(io); |
| 300 | std.process.exit(1); | 300 | std.process.exit(1); |
| 301 | }, | 301 | }, |
| 302 | else => |e| return e, | 302 | else => |e| return e, |
| ... | @@ -315,7 +315,7 @@ pub fn main() !void { | ... | @@ -315,7 +315,7 @@ pub fn main() !void { |
| 315 | try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); | 315 | try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); |
| 316 | std.process.exit(1); | 316 | std.process.exit(1); |
| 317 | }; | 317 | }; |
| 318 | defer depfile.close(); | 318 | defer depfile.close(io); |
| 319 | 319 | ||
| 320 | var depfile_buffer: [1024]u8 = undefined; | 320 | var depfile_buffer: [1024]u8 = undefined; |
| 321 | var depfile_writer = depfile.writer(&depfile_buffer); | 321 | var depfile_writer = depfile.writer(&depfile_buffer); |
| ... | @@ -402,7 +402,7 @@ pub fn main() !void { | ... | @@ -402,7 +402,7 @@ pub fn main() !void { |
| 402 | }, | 402 | }, |
| 403 | } | 403 | } |
| 404 | // Delete the output file on error | 404 | // Delete the output file on error |
| 405 | coff_stream.cleanupAfterError(); | 405 | coff_stream.cleanupAfterError(io); |
| 406 | std.process.exit(1); | 406 | std.process.exit(1); |
| 407 | }; | 407 | }; |
| 408 | 408 | ||
| ... | @@ -434,11 +434,11 @@ const IoStream = struct { | ... | @@ -434,11 +434,11 @@ const IoStream = struct { |
| 434 | self.source.deinit(allocator); | 434 | self.source.deinit(allocator); |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | pub fn cleanupAfterError(self: *IoStream) void { | 437 | pub fn cleanupAfterError(self: *IoStream, io: Io) void { |
| 438 | switch (self.source) { | 438 | switch (self.source) { |
| 439 | .file => |file| { | 439 | .file => |file| { |
| 440 | // Delete the output file on error | 440 | // Delete the output file on error |
| 441 | file.close(); | 441 | file.close(io); |
| 442 | // Failing to delete is not really a big deal, so swallow any errors | 442 | // Failing to delete is not really a big deal, so swallow any errors |
| 443 | std.fs.cwd().deleteFile(self.name) catch {}; | 443 | std.fs.cwd().deleteFile(self.name) catch {}; |
| 444 | }, | 444 | }, |
| ... | @@ -465,9 +465,9 @@ const IoStream = struct { | ... | @@ -465,9 +465,9 @@ const IoStream = struct { |
| 465 | } | 465 | } |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | pub fn deinit(self: *Source, allocator: Allocator) void { | 468 | pub fn deinit(self: *Source, allocator: Allocator, io: Io) void { |
| 469 | switch (self.*) { | 469 | switch (self.*) { |
| 470 | .file => |file| file.close(), | 470 | .file => |file| file.close(io), |
| 471 | .stdio => {}, | 471 | .stdio => {}, |
| 472 | .memory => |*list| list.deinit(allocator), | 472 | .memory => |*list| list.deinit(allocator), |
| 473 | .closed => {}, | 473 | .closed => {}, |
lib/compiler/resinator/utils.zig+6-3| ... | @@ -1,6 +1,8 @@ | ... | @@ -1,6 +1,8 @@ |
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 3 | 2 | ||
| 3 | const std = @import("std"); | ||
| 4 | const Io = std.Io; | ||
| 5 | |||
| 4 | pub const UncheckedSliceWriter = struct { | 6 | pub const UncheckedSliceWriter = struct { |
| 5 | const Self = @This(); | 7 | const Self = @This(); |
| 6 | 8 | ||
| ... | @@ -28,11 +30,12 @@ pub const UncheckedSliceWriter = struct { | ... | @@ -28,11 +30,12 @@ pub const UncheckedSliceWriter = struct { |
| 28 | /// TODO: Remove once https://github.com/ziglang/zig/issues/5732 is addressed. | 30 | /// TODO: Remove once https://github.com/ziglang/zig/issues/5732 is addressed. |
| 29 | pub fn openFileNotDir( | 31 | pub fn openFileNotDir( |
| 30 | cwd: std.fs.Dir, | 32 | cwd: std.fs.Dir, |
| 33 | io: Io, | ||
| 31 | path: []const u8, | 34 | path: []const u8, |
| 32 | flags: std.fs.File.OpenFlags, | 35 | flags: std.fs.File.OpenFlags, |
| 33 | ) (std.fs.File.OpenError || std.fs.File.StatError)!std.fs.File { | 36 | ) (std.fs.File.OpenError || std.fs.File.StatError)!std.fs.File { |
| 34 | const file = try cwd.openFile(path, flags); | 37 | const file = try cwd.openFile(io, path, flags); |
| 35 | errdefer file.close(); | 38 | errdefer file.close(io); |
| 36 | // https://github.com/ziglang/zig/issues/5732 | 39 | // https://github.com/ziglang/zig/issues/5732 |
| 37 | if (builtin.os.tag != .windows) { | 40 | if (builtin.os.tag != .windows) { |
| 38 | const stat = try file.stat(); | 41 | const stat = try file.stat(); |
lib/compiler/std-docs.zig+22-11| ... | @@ -1,12 +1,14 @@ | ... | @@ -1,12 +1,14 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | |||
| 2 | const std = @import("std"); | 3 | const std = @import("std"); |
| 4 | const Io = std.Io; | ||
| 3 | const mem = std.mem; | 5 | const mem = std.mem; |
| 4 | const Allocator = std.mem.Allocator; | 6 | const Allocator = std.mem.Allocator; |
| 5 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 6 | const Cache = std.Build.Cache; | 8 | const Cache = std.Build.Cache; |
| 7 | 9 | ||
| 8 | fn usage() noreturn { | 10 | fn usage() noreturn { |
| 9 | std.fs.File.stdout().writeAll( | 11 | std.Io.File.stdout().writeAll( |
| 10 | \\Usage: zig std [options] | 12 | \\Usage: zig std [options] |
| 11 | \\ | 13 | \\ |
| 12 | \\Options: | 14 | \\Options: |
| ... | @@ -27,6 +29,10 @@ pub fn main() !void { | ... | @@ -27,6 +29,10 @@ pub fn main() !void { |
| 27 | var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; | 29 | var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; |
| 28 | const gpa = general_purpose_allocator.allocator(); | 30 | const gpa = general_purpose_allocator.allocator(); |
| 29 | 31 | ||
| 32 | var threaded: std.Io.Threaded = .init(gpa); | ||
| 33 | defer threaded.deinit(); | ||
| 34 | const io = threaded.io(); | ||
| 35 | |||
| 30 | var argv = try std.process.argsWithAllocator(arena); | 36 | var argv = try std.process.argsWithAllocator(arena); |
| 31 | defer argv.deinit(); | 37 | defer argv.deinit(); |
| 32 | assert(argv.skip()); | 38 | assert(argv.skip()); |
| ... | @@ -35,7 +41,7 @@ pub fn main() !void { | ... | @@ -35,7 +41,7 @@ pub fn main() !void { |
| 35 | const global_cache_path = argv.next().?; | 41 | const global_cache_path = argv.next().?; |
| 36 | 42 | ||
| 37 | var lib_dir = try std.fs.cwd().openDir(zig_lib_directory, .{}); | 43 | var lib_dir = try std.fs.cwd().openDir(zig_lib_directory, .{}); |
| 38 | defer lib_dir.close(); | 44 | defer lib_dir.close(io); |
| 39 | 45 | ||
| 40 | var listen_port: u16 = 0; | 46 | var listen_port: u16 = 0; |
| 41 | var force_open_browser: ?bool = null; | 47 | var force_open_browser: ?bool = null; |
| ... | @@ -64,7 +70,7 @@ pub fn main() !void { | ... | @@ -64,7 +70,7 @@ pub fn main() !void { |
| 64 | }); | 70 | }); |
| 65 | const port = http_server.listen_address.in.getPort(); | 71 | const port = http_server.listen_address.in.getPort(); |
| 66 | const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port}); | 72 | const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port}); |
| 67 | std.fs.File.stdout().writeAll(url_with_newline) catch {}; | 73 | std.Io.File.stdout().writeAll(url_with_newline) catch {}; |
| 68 | if (should_open_browser) { | 74 | if (should_open_browser) { |
| 69 | openBrowserTab(gpa, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { | 75 | openBrowserTab(gpa, url_with_newline[0 .. url_with_newline.len - 1 :'\n']) catch |err| { |
| 70 | std.log.err("unable to open browser: {s}", .{@errorName(err)}); | 76 | std.log.err("unable to open browser: {s}", .{@errorName(err)}); |
| ... | @@ -73,6 +79,7 @@ pub fn main() !void { | ... | @@ -73,6 +79,7 @@ pub fn main() !void { |
| 73 | 79 | ||
| 74 | var context: Context = .{ | 80 | var context: Context = .{ |
| 75 | .gpa = gpa, | 81 | .gpa = gpa, |
| 82 | .io = io, | ||
| 76 | .zig_exe_path = zig_exe_path, | 83 | .zig_exe_path = zig_exe_path, |
| 77 | .global_cache_path = global_cache_path, | 84 | .global_cache_path = global_cache_path, |
| 78 | .lib_dir = lib_dir, | 85 | .lib_dir = lib_dir, |
| ... | @@ -83,14 +90,15 @@ pub fn main() !void { | ... | @@ -83,14 +90,15 @@ pub fn main() !void { |
| 83 | const connection = try http_server.accept(); | 90 | const connection = try http_server.accept(); |
| 84 | _ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| { | 91 | _ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| { |
| 85 | std.log.err("unable to accept connection: {s}", .{@errorName(err)}); | 92 | std.log.err("unable to accept connection: {s}", .{@errorName(err)}); |
| 86 | connection.stream.close(); | 93 | connection.stream.close(io); |
| 87 | continue; | 94 | continue; |
| 88 | }; | 95 | }; |
| 89 | } | 96 | } |
| 90 | } | 97 | } |
| 91 | 98 | ||
| 92 | fn accept(context: *Context, connection: std.net.Server.Connection) void { | 99 | fn accept(context: *Context, connection: std.net.Server.Connection) void { |
| 93 | defer connection.stream.close(); | 100 | const io = context.io; |
| 101 | defer connection.stream.close(io); | ||
| 94 | 102 | ||
| 95 | var recv_buffer: [4000]u8 = undefined; | 103 | var recv_buffer: [4000]u8 = undefined; |
| 96 | var send_buffer: [4000]u8 = undefined; | 104 | var send_buffer: [4000]u8 = undefined; |
| ... | @@ -124,6 +132,7 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void { | ... | @@ -124,6 +132,7 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void { |
| 124 | 132 | ||
| 125 | const Context = struct { | 133 | const Context = struct { |
| 126 | gpa: Allocator, | 134 | gpa: Allocator, |
| 135 | io: Io, | ||
| 127 | lib_dir: std.fs.Dir, | 136 | lib_dir: std.fs.Dir, |
| 128 | zig_lib_directory: []const u8, | 137 | zig_lib_directory: []const u8, |
| 129 | zig_exe_path: []const u8, | 138 | zig_exe_path: []const u8, |
| ... | @@ -185,6 +194,7 @@ fn serveDocsFile( | ... | @@ -185,6 +194,7 @@ fn serveDocsFile( |
| 185 | 194 | ||
| 186 | fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { | 195 | fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { |
| 187 | const gpa = context.gpa; | 196 | const gpa = context.gpa; |
| 197 | const io = context.io; | ||
| 188 | 198 | ||
| 189 | var send_buffer: [0x4000]u8 = undefined; | 199 | var send_buffer: [0x4000]u8 = undefined; |
| 190 | var response = try request.respondStreaming(&send_buffer, .{ | 200 | var response = try request.respondStreaming(&send_buffer, .{ |
| ... | @@ -197,7 +207,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { | ... | @@ -197,7 +207,7 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { |
| 197 | }); | 207 | }); |
| 198 | 208 | ||
| 199 | var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true }); | 209 | var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true }); |
| 200 | defer std_dir.close(); | 210 | defer std_dir.close(io); |
| 201 | 211 | ||
| 202 | var walker = try std_dir.walk(gpa); | 212 | var walker = try std_dir.walk(gpa); |
| 203 | defer walker.deinit(); | 213 | defer walker.deinit(); |
| ... | @@ -216,11 +226,11 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { | ... | @@ -216,11 +226,11 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void { |
| 216 | else => continue, | 226 | else => continue, |
| 217 | } | 227 | } |
| 218 | var file = try entry.dir.openFile(entry.basename, .{}); | 228 | var file = try entry.dir.openFile(entry.basename, .{}); |
| 219 | defer file.close(); | 229 | defer file.close(io); |
| 220 | const stat = try file.stat(); | 230 | const stat = try file.stat(); |
| 221 | var file_reader: std.fs.File.Reader = .{ | 231 | var file_reader: std.Io.File.Reader = .{ |
| 222 | .file = file, | 232 | .file = file, |
| 223 | .interface = std.fs.File.Reader.initInterface(&.{}), | 233 | .interface = std.Io.File.Reader.initInterface(&.{}), |
| 224 | .size = stat.size, | 234 | .size = stat.size, |
| 225 | }; | 235 | }; |
| 226 | try archiver.writeFile(entry.path, &file_reader, stat.mtime); | 236 | try archiver.writeFile(entry.path, &file_reader, stat.mtime); |
| ... | @@ -283,6 +293,7 @@ fn buildWasmBinary( | ... | @@ -283,6 +293,7 @@ fn buildWasmBinary( |
| 283 | optimize_mode: std.builtin.OptimizeMode, | 293 | optimize_mode: std.builtin.OptimizeMode, |
| 284 | ) !Cache.Path { | 294 | ) !Cache.Path { |
| 285 | const gpa = context.gpa; | 295 | const gpa = context.gpa; |
| 296 | const io = context.io; | ||
| 286 | 297 | ||
| 287 | var argv: std.ArrayList([]const u8) = .empty; | 298 | var argv: std.ArrayList([]const u8) = .empty; |
| 288 | 299 | ||
| ... | @@ -371,7 +382,7 @@ fn buildWasmBinary( | ... | @@ -371,7 +382,7 @@ fn buildWasmBinary( |
| 371 | } | 382 | } |
| 372 | 383 | ||
| 373 | // Send EOF to stdin. | 384 | // Send EOF to stdin. |
| 374 | child.stdin.?.close(); | 385 | child.stdin.?.close(io); |
| 375 | child.stdin = null; | 386 | child.stdin = null; |
| 376 | 387 | ||
| 377 | switch (try child.wait()) { | 388 | switch (try child.wait()) { |
| ... | @@ -410,7 +421,7 @@ fn buildWasmBinary( | ... | @@ -410,7 +421,7 @@ fn buildWasmBinary( |
| 410 | }; | 421 | }; |
| 411 | } | 422 | } |
| 412 | 423 | ||
| 413 | fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { | 424 | fn sendMessage(file: std.Io.File, tag: std.zig.Client.Message.Tag) !void { |
| 414 | const header: std.zig.Client.Message.Header = .{ | 425 | const header: std.zig.Client.Message.Header = .{ |
| 415 | .tag = tag, | 426 | .tag = tag, |
| 416 | .bytes_len = 0, | 427 | .bytes_len = 0, |
lib/compiler/translate-c/main.zig+3-2| ... | @@ -121,6 +121,7 @@ pub const usage = | ... | @@ -121,6 +121,7 @@ pub const usage = |
| 121 | 121 | ||
| 122 | fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration: bool) !void { | 122 | fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration: bool) !void { |
| 123 | const gpa = d.comp.gpa; | 123 | const gpa = d.comp.gpa; |
| 124 | const io = d.comp.io; | ||
| 124 | 125 | ||
| 125 | const aro_args = args: { | 126 | const aro_args = args: { |
| 126 | var i: usize = 0; | 127 | var i: usize = 0; |
| ... | @@ -228,7 +229,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration | ... | @@ -228,7 +229,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration |
| 228 | return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) }) | 229 | return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) }) |
| 229 | else | 230 | else |
| 230 | std.fs.File.stdout(); | 231 | std.fs.File.stdout(); |
| 231 | defer if (dep_file_name != null) file.close(); | 232 | defer if (dep_file_name != null) file.close(io); |
| 232 | 233 | ||
| 233 | var file_writer = file.writer(&out_buf); | 234 | var file_writer = file.writer(&out_buf); |
| 234 | dep_file.write(&file_writer.interface) catch | 235 | dep_file.write(&file_writer.interface) catch |
| ... | @@ -246,7 +247,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration | ... | @@ -246,7 +247,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration |
| 246 | var close_out_file = false; | 247 | var close_out_file = false; |
| 247 | var out_file_path: []const u8 = "<stdout>"; | 248 | var out_file_path: []const u8 = "<stdout>"; |
| 248 | var out_file: std.fs.File = .stdout(); | 249 | var out_file: std.fs.File = .stdout(); |
| 249 | defer if (close_out_file) out_file.close(); | 250 | defer if (close_out_file) out_file.close(io); |
| 250 | 251 | ||
| 251 | if (d.output_name) |path| blk: { | 252 | if (d.output_name) |path| blk: { |
| 252 | if (std.mem.eql(u8, path, "-")) break :blk; | 253 | if (std.mem.eql(u8, path, "-")) break :blk; |
lib/std/Build/Cache/Directory.zig+2-2| ... | @@ -52,8 +52,8 @@ pub fn joinZ(self: Directory, allocator: Allocator, paths: []const []const u8) ! | ... | @@ -52,8 +52,8 @@ pub fn joinZ(self: Directory, allocator: Allocator, paths: []const []const u8) ! |
| 52 | /// Whether or not the handle should be closed, or the path should be freed | 52 | /// Whether or not the handle should be closed, or the path should be freed |
| 53 | /// is determined by usage, however this function is provided for convenience | 53 | /// is determined by usage, however this function is provided for convenience |
| 54 | /// if it happens to be what the caller needs. | 54 | /// if it happens to be what the caller needs. |
| 55 | pub fn closeAndFree(self: *Directory, gpa: Allocator) void { | 55 | pub fn closeAndFree(self: *Directory, gpa: Allocator, io: Io) void { |
| 56 | self.handle.close(); | 56 | self.handle.close(io); |
| 57 | if (self.path) |p| gpa.free(p); | 57 | if (self.path) |p| gpa.free(p); |
| 58 | self.* = undefined; | 58 | self.* = undefined; |
| 59 | } | 59 | } |
lib/std/Build/Fuzz.zig+2-2| ... | @@ -411,7 +411,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -411,7 +411,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 411 | }); | 411 | }); |
| 412 | return error.AlreadyReported; | 412 | return error.AlreadyReported; |
| 413 | }; | 413 | }; |
| 414 | defer coverage_file.close(); | 414 | defer coverage_file.close(io); |
| 415 | 415 | ||
| 416 | const file_size = coverage_file.getEndPos() catch |err| { | 416 | const file_size = coverage_file.getEndPos() catch |err| { |
| 417 | log.err("unable to check len of coverage file '{f}': {t}", .{ coverage_file_path, err }); | 417 | log.err("unable to check len of coverage file '{f}': {t}", .{ coverage_file_path, err }); |
| ... | @@ -533,7 +533,7 @@ pub fn waitAndPrintReport(fuzz: *Fuzz) void { | ... | @@ -533,7 +533,7 @@ pub fn waitAndPrintReport(fuzz: *Fuzz) void { |
| 533 | cov.run.step.name, coverage_file_path, err, | 533 | cov.run.step.name, coverage_file_path, err, |
| 534 | }); | 534 | }); |
| 535 | }; | 535 | }; |
| 536 | defer coverage_file.close(); | 536 | defer coverage_file.close(io); |
| 537 | 537 | ||
| 538 | const fuzz_abi = std.Build.abi.fuzz; | 538 | const fuzz_abi = std.Build.abi.fuzz; |
| 539 | var rbuf: [0x1000]u8 = undefined; | 539 | var rbuf: [0x1000]u8 = undefined; |
lib/std/Build/Step.zig+2-1| ... | @@ -441,6 +441,7 @@ pub fn evalZigProcess( | ... | @@ -441,6 +441,7 @@ pub fn evalZigProcess( |
| 441 | assert(argv.len != 0); | 441 | assert(argv.len != 0); |
| 442 | const b = s.owner; | 442 | const b = s.owner; |
| 443 | const arena = b.allocator; | 443 | const arena = b.allocator; |
| 444 | const io = b.graph.io; | ||
| 444 | 445 | ||
| 445 | try handleChildProcUnsupported(s); | 446 | try handleChildProcUnsupported(s); |
| 446 | try handleVerbose(s.owner, null, argv); | 447 | try handleVerbose(s.owner, null, argv); |
| ... | @@ -474,7 +475,7 @@ pub fn evalZigProcess( | ... | @@ -474,7 +475,7 @@ pub fn evalZigProcess( |
| 474 | 475 | ||
| 475 | if (!watch) { | 476 | if (!watch) { |
| 476 | // Send EOF to stdin. | 477 | // Send EOF to stdin. |
| 477 | zp.child.stdin.?.close(); | 478 | zp.child.stdin.?.close(io); |
| 478 | zp.child.stdin = null; | 479 | zp.child.stdin = null; |
| 479 | 480 | ||
| 480 | const term = zp.child.wait() catch |err| { | 481 | const term = zp.child.wait() catch |err| { |
lib/std/Build/Step/InstallArtifact.zig+2-1| ... | @@ -119,6 +119,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -119,6 +119,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 119 | _ = options; | 119 | _ = options; |
| 120 | const install_artifact: *InstallArtifact = @fieldParentPtr("step", step); | 120 | const install_artifact: *InstallArtifact = @fieldParentPtr("step", step); |
| 121 | const b = step.owner; | 121 | const b = step.owner; |
| 122 | const io = b.graph.io; | ||
| 122 | 123 | ||
| 123 | var all_cached = true; | 124 | var all_cached = true; |
| 124 | 125 | ||
| ... | @@ -168,7 +169,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -168,7 +169,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 168 | src_dir_path, @errorName(err), | 169 | src_dir_path, @errorName(err), |
| 169 | }); | 170 | }); |
| 170 | }; | 171 | }; |
| 171 | defer src_dir.close(); | 172 | defer src_dir.close(io); |
| 172 | 173 | ||
| 173 | var it = try src_dir.walk(b.allocator); | 174 | var it = try src_dir.walk(b.allocator); |
| 174 | next_entry: while (try it.next()) |entry| { | 175 | next_entry: while (try it.next()) |entry| { |
lib/std/Build/Step/InstallDir.zig+1-1| ... | @@ -68,7 +68,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -68,7 +68,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 68 | var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { | 68 | var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { |
| 69 | return step.fail("unable to open source directory '{f}': {t}", .{ src_dir_path, err }); | 69 | return step.fail("unable to open source directory '{f}': {t}", .{ src_dir_path, err }); |
| 70 | }; | 70 | }; |
| 71 | defer src_dir.close(); | 71 | defer src_dir.close(io); |
| 72 | var it = try src_dir.walk(arena); | 72 | var it = try src_dir.walk(arena); |
| 73 | var all_cached = true; | 73 | var all_cached = true; |
| 74 | next_entry: while (try it.next()) |entry| { | 74 | next_entry: while (try it.next()) |entry| { |
lib/std/Build/Step/Run.zig+11-9| ... | @@ -851,7 +851,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -851,7 +851,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 851 | .{ file_path, err }, | 851 | .{ file_path, err }, |
| 852 | ); | 852 | ); |
| 853 | }; | 853 | }; |
| 854 | defer file.close(); | 854 | defer file.close(io); |
| 855 | 855 | ||
| 856 | var buf: [1024]u8 = undefined; | 856 | var buf: [1024]u8 = undefined; |
| 857 | var file_reader = file.reader(io, &buf); | 857 | var file_reader = file.reader(io, &buf); |
| ... | @@ -1111,7 +1111,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1111,7 +1111,7 @@ pub fn rerunInFuzzMode( |
| 1111 | result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory; | 1111 | result.writer.writeAll(file_plp.prefix) catch return error.OutOfMemory; |
| 1112 | 1112 | ||
| 1113 | const file = try file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{}); | 1113 | const file = try file_path.root_dir.handle.openFile(file_path.subPathOrDot(), .{}); |
| 1114 | defer file.close(); | 1114 | defer file.close(io); |
| 1115 | 1115 | ||
| 1116 | var buf: [1024]u8 = undefined; | 1116 | var buf: [1024]u8 = undefined; |
| 1117 | var file_reader = file.reader(io, &buf); | 1117 | var file_reader = file.reader(io, &buf); |
| ... | @@ -1671,8 +1671,10 @@ fn evalZigTest( | ... | @@ -1671,8 +1671,10 @@ fn evalZigTest( |
| 1671 | options: Step.MakeOptions, | 1671 | options: Step.MakeOptions, |
| 1672 | fuzz_context: ?FuzzContext, | 1672 | fuzz_context: ?FuzzContext, |
| 1673 | ) !EvalZigTestResult { | 1673 | ) !EvalZigTestResult { |
| 1674 | const gpa = run.step.owner.allocator; | 1674 | const step_owner = run.step.owner; |
| 1675 | const arena = run.step.owner.allocator; | 1675 | const gpa = step_owner.allocator; |
| 1676 | const arena = step_owner.allocator; | ||
| 1677 | const io = step_owner.graph.io; | ||
| 1676 | 1678 | ||
| 1677 | // We will update this every time a child runs. | 1679 | // We will update this every time a child runs. |
| 1678 | run.step.result_peak_rss = 0; | 1680 | run.step.result_peak_rss = 0; |
| ... | @@ -1724,7 +1726,7 @@ fn evalZigTest( | ... | @@ -1724,7 +1726,7 @@ fn evalZigTest( |
| 1724 | run.step.result_stderr = try arena.dupe(u8, poller.reader(.stderr).buffered()); | 1726 | run.step.result_stderr = try arena.dupe(u8, poller.reader(.stderr).buffered()); |
| 1725 | 1727 | ||
| 1726 | // Clean up everything and wait for the child to exit. | 1728 | // Clean up everything and wait for the child to exit. |
| 1727 | child.stdin.?.close(); | 1729 | child.stdin.?.close(io); |
| 1728 | child.stdin = null; | 1730 | child.stdin = null; |
| 1729 | poller.deinit(); | 1731 | poller.deinit(); |
| 1730 | child_killed = true; | 1732 | child_killed = true; |
| ... | @@ -1744,7 +1746,7 @@ fn evalZigTest( | ... | @@ -1744,7 +1746,7 @@ fn evalZigTest( |
| 1744 | poller.reader(.stderr).tossBuffered(); | 1746 | poller.reader(.stderr).tossBuffered(); |
| 1745 | 1747 | ||
| 1746 | // Clean up everything and wait for the child to exit. | 1748 | // Clean up everything and wait for the child to exit. |
| 1747 | child.stdin.?.close(); | 1749 | child.stdin.?.close(io); |
| 1748 | child.stdin = null; | 1750 | child.stdin = null; |
| 1749 | poller.deinit(); | 1751 | poller.deinit(); |
| 1750 | child_killed = true; | 1752 | child_killed = true; |
| ... | @@ -2177,7 +2179,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { | ... | @@ -2177,7 +2179,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { |
| 2177 | child.stdin.?.writeAll(bytes) catch |err| { | 2179 | child.stdin.?.writeAll(bytes) catch |err| { |
| 2178 | return run.step.fail("unable to write stdin: {s}", .{@errorName(err)}); | 2180 | return run.step.fail("unable to write stdin: {s}", .{@errorName(err)}); |
| 2179 | }; | 2181 | }; |
| 2180 | child.stdin.?.close(); | 2182 | child.stdin.?.close(io); |
| 2181 | child.stdin = null; | 2183 | child.stdin = null; |
| 2182 | }, | 2184 | }, |
| 2183 | .lazy_path => |lazy_path| { | 2185 | .lazy_path => |lazy_path| { |
| ... | @@ -2185,7 +2187,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { | ... | @@ -2185,7 +2187,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { |
| 2185 | const file = path.root_dir.handle.openFile(path.subPathOrDot(), .{}) catch |err| { | 2187 | const file = path.root_dir.handle.openFile(path.subPathOrDot(), .{}) catch |err| { |
| 2186 | return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)}); | 2188 | return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)}); |
| 2187 | }; | 2189 | }; |
| 2188 | defer file.close(); | 2190 | defer file.close(io); |
| 2189 | // TODO https://github.com/ziglang/zig/issues/23955 | 2191 | // TODO https://github.com/ziglang/zig/issues/23955 |
| 2190 | var read_buffer: [1024]u8 = undefined; | 2192 | var read_buffer: [1024]u8 = undefined; |
| 2191 | var file_reader = file.reader(io, &read_buffer); | 2193 | var file_reader = file.reader(io, &read_buffer); |
| ... | @@ -2204,7 +2206,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { | ... | @@ -2204,7 +2206,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !EvalGenericResult { |
| 2204 | stdin_writer.err.?, | 2206 | stdin_writer.err.?, |
| 2205 | }), | 2207 | }), |
| 2206 | }; | 2208 | }; |
| 2207 | child.stdin.?.close(); | 2209 | child.stdin.?.close(io); |
| 2208 | child.stdin = null; | 2210 | child.stdin = null; |
| 2209 | }, | 2211 | }, |
| 2210 | .none => {}, | 2212 | .none => {}, |
lib/std/Build/Step/WriteFile.zig+6-4| ... | @@ -206,7 +206,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -206,7 +206,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 206 | } | 206 | } |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | const open_dir_cache = try arena.alloc(fs.Dir, write_file.directories.items.len); | 209 | const open_dir_cache = try arena.alloc(Io.Dir, write_file.directories.items.len); |
| 210 | var open_dirs_count: usize = 0; | 210 | var open_dirs_count: usize = 0; |
| 211 | defer closeDirs(open_dir_cache[0..open_dirs_count]); | 211 | defer closeDirs(open_dir_cache[0..open_dirs_count]); |
| 212 | 212 | ||
| ... | @@ -264,7 +264,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -264,7 +264,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 264 | b.cache_root, cache_path, @errorName(err), | 264 | b.cache_root, cache_path, @errorName(err), |
| 265 | }); | 265 | }); |
| 266 | }; | 266 | }; |
| 267 | defer cache_dir.close(); | 267 | defer cache_dir.close(io); |
| 268 | 268 | ||
| 269 | for (write_file.files.items) |file| { | 269 | for (write_file.files.items) |file| { |
| 270 | if (fs.path.dirname(file.sub_path)) |dirname| { | 270 | if (fs.path.dirname(file.sub_path)) |dirname| { |
| ... | @@ -342,6 +342,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -342,6 +342,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 342 | try step.writeManifest(&man); | 342 | try step.writeManifest(&man); |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | fn closeDirs(dirs: []fs.Dir) void { | 345 | fn closeDirs(io: Io, dirs: []Io.Dir) void { |
| 346 | for (dirs) |*d| d.close(); | 346 | var group: Io.Group = .init; |
| 347 | defer group.wait(); | ||
| 348 | for (dirs) |d| group.async(Io.Dir.close, .{ d, io }); | ||
| 347 | } | 349 | } |
lib/std/Build/Watch/FsEvents.zig+5-4| ... | @@ -78,10 +78,10 @@ const ResolvedSymbols = struct { | ... | @@ -78,10 +78,10 @@ const ResolvedSymbols = struct { |
| 78 | kCFAllocatorUseContext: *const CFAllocatorRef, | 78 | kCFAllocatorUseContext: *const CFAllocatorRef, |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | pub fn init() error{ OpenFrameworkFailed, MissingCoreServicesSymbol }!FsEvents { | 81 | pub fn init(io: Io) error{ OpenFrameworkFailed, MissingCoreServicesSymbol }!FsEvents { |
| 82 | var core_services = std.DynLib.open("/System/Library/Frameworks/CoreServices.framework/CoreServices") catch | 82 | var core_services = std.DynLib.open("/System/Library/Frameworks/CoreServices.framework/CoreServices") catch |
| 83 | return error.OpenFrameworkFailed; | 83 | return error.OpenFrameworkFailed; |
| 84 | errdefer core_services.close(); | 84 | errdefer core_services.close(io); |
| 85 | 85 | ||
| 86 | var resolved_symbols: ResolvedSymbols = undefined; | 86 | var resolved_symbols: ResolvedSymbols = undefined; |
| 87 | inline for (@typeInfo(ResolvedSymbols).@"struct".fields) |f| { | 87 | inline for (@typeInfo(ResolvedSymbols).@"struct".fields) |f| { |
| ... | @@ -102,10 +102,10 @@ pub fn init() error{ OpenFrameworkFailed, MissingCoreServicesSymbol }!FsEvents { | ... | @@ -102,10 +102,10 @@ pub fn init() error{ OpenFrameworkFailed, MissingCoreServicesSymbol }!FsEvents { |
| 102 | }; | 102 | }; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | pub fn deinit(fse: *FsEvents, gpa: Allocator) void { | 105 | pub fn deinit(fse: *FsEvents, gpa: Allocator, io: Io) void { |
| 106 | dispatch_release(fse.waiting_semaphore); | 106 | dispatch_release(fse.waiting_semaphore); |
| 107 | dispatch_release(fse.dispatch_queue); | 107 | dispatch_release(fse.dispatch_queue); |
| 108 | fse.core_services.close(); | 108 | fse.core_services.close(io); |
| 109 | 109 | ||
| 110 | gpa.free(fse.watch_roots); | 110 | gpa.free(fse.watch_roots); |
| 111 | fse.watch_paths.deinit(gpa); | 111 | fse.watch_paths.deinit(gpa); |
| ... | @@ -487,6 +487,7 @@ const FSEventStreamEventFlags = packed struct(u32) { | ... | @@ -487,6 +487,7 @@ const FSEventStreamEventFlags = packed struct(u32) { |
| 487 | }; | 487 | }; |
| 488 | 488 | ||
| 489 | const std = @import("std"); | 489 | const std = @import("std"); |
| 490 | const Io = std.Io; | ||
| 490 | const assert = std.debug.assert; | 491 | const assert = std.debug.assert; |
| 491 | const Allocator = std.mem.Allocator; | 492 | const Allocator = std.mem.Allocator; |
| 492 | const watch_log = std.log.scoped(.watch); | 493 | const watch_log = std.log.scoped(.watch); |
lib/std/Build/WebServer.zig+4-3| ... | @@ -129,6 +129,7 @@ pub fn init(opts: Options) WebServer { | ... | @@ -129,6 +129,7 @@ pub fn init(opts: Options) WebServer { |
| 129 | } | 129 | } |
| 130 | pub fn deinit(ws: *WebServer) void { | 130 | pub fn deinit(ws: *WebServer) void { |
| 131 | const gpa = ws.gpa; | 131 | const gpa = ws.gpa; |
| 132 | const io = ws.graph.io; | ||
| 132 | 133 | ||
| 133 | gpa.free(ws.step_names_trailing); | 134 | gpa.free(ws.step_names_trailing); |
| 134 | gpa.free(ws.step_status_bits); | 135 | gpa.free(ws.step_status_bits); |
| ... | @@ -139,7 +140,7 @@ pub fn deinit(ws: *WebServer) void { | ... | @@ -139,7 +140,7 @@ pub fn deinit(ws: *WebServer) void { |
| 139 | gpa.free(ws.time_report_update_times); | 140 | gpa.free(ws.time_report_update_times); |
| 140 | 141 | ||
| 141 | if (ws.serve_thread) |t| { | 142 | if (ws.serve_thread) |t| { |
| 142 | if (ws.tcp_server) |*s| s.stream.close(); | 143 | if (ws.tcp_server) |*s| s.stream.close(io); |
| 143 | t.join(); | 144 | t.join(); |
| 144 | } | 145 | } |
| 145 | if (ws.tcp_server) |*s| s.deinit(); | 146 | if (ws.tcp_server) |*s| s.deinit(); |
| ... | @@ -507,7 +508,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons | ... | @@ -507,7 +508,7 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons |
| 507 | log.err("failed to open '{f}': {s}", .{ path, @errorName(err) }); | 508 | log.err("failed to open '{f}': {s}", .{ path, @errorName(err) }); |
| 508 | continue; | 509 | continue; |
| 509 | }; | 510 | }; |
| 510 | defer file.close(); | 511 | defer file.close(io); |
| 511 | const stat = try file.stat(); | 512 | const stat = try file.stat(); |
| 512 | var read_buffer: [1024]u8 = undefined; | 513 | var read_buffer: [1024]u8 = undefined; |
| 513 | var file_reader: Io.File.Reader = .initSize(file.adaptToNewApi(), io, &read_buffer, stat.size); | 514 | var file_reader: Io.File.Reader = .initSize(file.adaptToNewApi(), io, &read_buffer, stat.size); |
| ... | @@ -634,7 +635,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim | ... | @@ -634,7 +635,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim |
| 634 | } | 635 | } |
| 635 | 636 | ||
| 636 | // Send EOF to stdin. | 637 | // Send EOF to stdin. |
| 637 | child.stdin.?.close(); | 638 | child.stdin.?.close(io); |
| 638 | child.stdin = null; | 639 | child.stdin = null; |
| 639 | 640 | ||
| 640 | switch (try child.wait()) { | 641 | switch (try child.wait()) { |
lib/std/Io/Dir.zig+25-16| ... | @@ -131,7 +131,7 @@ pub const SelectiveWalker = struct { | ... | @@ -131,7 +131,7 @@ pub const SelectiveWalker = struct { |
| 131 | /// After each call to this function, and on deinit(), the memory returned | 131 | /// After each call to this function, and on deinit(), the memory returned |
| 132 | /// from this function becomes invalid. A copy must be made in order to keep | 132 | /// from this function becomes invalid. A copy must be made in order to keep |
| 133 | /// a reference to the path. | 133 | /// a reference to the path. |
| 134 | pub fn next(self: *SelectiveWalker) Error!?Walker.Entry { | 134 | pub fn next(self: *SelectiveWalker, io: Io) Error!?Walker.Entry { |
| 135 | while (self.stack.items.len > 0) { | 135 | while (self.stack.items.len > 0) { |
| 136 | const top = &self.stack.items[self.stack.items.len - 1]; | 136 | const top = &self.stack.items[self.stack.items.len - 1]; |
| 137 | var dirname_len = top.dirname_len; | 137 | var dirname_len = top.dirname_len; |
| ... | @@ -142,7 +142,7 @@ pub const SelectiveWalker = struct { | ... | @@ -142,7 +142,7 @@ pub const SelectiveWalker = struct { |
| 142 | // likely just fail with the same error. | 142 | // likely just fail with the same error. |
| 143 | var item = self.stack.pop().?; | 143 | var item = self.stack.pop().?; |
| 144 | if (self.stack.items.len != 0) { | 144 | if (self.stack.items.len != 0) { |
| 145 | item.iter.dir.close(); | 145 | item.iter.dir.close(io); |
| 146 | } | 146 | } |
| 147 | return err; | 147 | return err; |
| 148 | }) |entry| { | 148 | }) |entry| { |
| ... | @@ -164,7 +164,7 @@ pub const SelectiveWalker = struct { | ... | @@ -164,7 +164,7 @@ pub const SelectiveWalker = struct { |
| 164 | } else { | 164 | } else { |
| 165 | var item = self.stack.pop().?; | 165 | var item = self.stack.pop().?; |
| 166 | if (self.stack.items.len != 0) { | 166 | if (self.stack.items.len != 0) { |
| 167 | item.iter.dir.close(); | 167 | item.iter.dir.close(io); |
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | } | 170 | } |
| ... | @@ -172,7 +172,7 @@ pub const SelectiveWalker = struct { | ... | @@ -172,7 +172,7 @@ pub const SelectiveWalker = struct { |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | /// Traverses into the directory, continuing walking one level down. | 174 | /// Traverses into the directory, continuing walking one level down. |
| 175 | pub fn enter(self: *SelectiveWalker, entry: Walker.Entry) !void { | 175 | pub fn enter(self: *SelectiveWalker, io: Io, entry: Walker.Entry) !void { |
| 176 | if (entry.kind != .directory) { | 176 | if (entry.kind != .directory) { |
| 177 | @branchHint(.cold); | 177 | @branchHint(.cold); |
| 178 | return; | 178 | return; |
| ... | @@ -184,7 +184,7 @@ pub const SelectiveWalker = struct { | ... | @@ -184,7 +184,7 @@ pub const SelectiveWalker = struct { |
| 184 | else => |e| return e, | 184 | else => |e| return e, |
| 185 | } | 185 | } |
| 186 | }; | 186 | }; |
| 187 | errdefer new_dir.close(); | 187 | errdefer new_dir.close(io); |
| 188 | 188 | ||
| 189 | try self.stack.append(self.allocator, .{ | 189 | try self.stack.append(self.allocator, .{ |
| 190 | .iter = new_dir.iterateAssumeFirstIteration(), | 190 | .iter = new_dir.iterateAssumeFirstIteration(), |
| ... | @@ -200,11 +200,11 @@ pub const SelectiveWalker = struct { | ... | @@ -200,11 +200,11 @@ pub const SelectiveWalker = struct { |
| 200 | /// Leaves the current directory, continuing walking one level up. | 200 | /// Leaves the current directory, continuing walking one level up. |
| 201 | /// If the current entry is a directory entry, then the "current directory" | 201 | /// If the current entry is a directory entry, then the "current directory" |
| 202 | /// will pertain to that entry if `enter` is called before `leave`. | 202 | /// will pertain to that entry if `enter` is called before `leave`. |
| 203 | pub fn leave(self: *SelectiveWalker) void { | 203 | pub fn leave(self: *SelectiveWalker, io: Io) void { |
| 204 | var item = self.stack.pop().?; | 204 | var item = self.stack.pop().?; |
| 205 | if (self.stack.items.len != 0) { | 205 | if (self.stack.items.len != 0) { |
| 206 | @branchHint(.likely); | 206 | @branchHint(.likely); |
| 207 | item.iter.dir.close(); | 207 | item.iter.dir.close(io); |
| 208 | } | 208 | } |
| 209 | } | 209 | } |
| 210 | }; | 210 | }; |
| ... | @@ -558,7 +558,8 @@ pub fn makeDir(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) | ... | @@ -558,7 +558,8 @@ pub fn makeDir(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) |
| 558 | 558 | ||
| 559 | pub const MakePathError = MakeError || StatPathError; | 559 | pub const MakePathError = MakeError || StatPathError; |
| 560 | 560 | ||
| 561 | /// Creates parent directories as necessary to ensure `sub_path` exists as a directory. | 561 | /// Creates parent directories with default permissions as necessary to ensure |
| 562 | /// `sub_path` exists as a directory. | ||
| 562 | /// | 563 | /// |
| 563 | /// Returns success if the path already exists and is a directory. | 564 | /// Returns success if the path already exists and is a directory. |
| 564 | /// | 565 | /// |
| ... | @@ -579,8 +580,11 @@ pub const MakePathError = MakeError || StatPathError; | ... | @@ -579,8 +580,11 @@ pub const MakePathError = MakeError || StatPathError; |
| 579 | /// - On other platforms, `..` are not resolved before the path is passed to `mkdirat`, | 580 | /// - On other platforms, `..` are not resolved before the path is passed to `mkdirat`, |
| 580 | /// meaning a `sub_path` like "first/../second" will create both a `./first` | 581 | /// meaning a `sub_path` like "first/../second" will create both a `./first` |
| 581 | /// and a `./second` directory. | 582 | /// and a `./second` directory. |
| 582 | pub fn makePath(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions) MakePathError!void { | 583 | /// |
| 583 | _ = try io.vtable.dirMakePath(io.userdata, dir, sub_path, permissions); | 584 | /// See also: |
| 585 | /// * `makePathStatus` | ||
| 586 | pub fn makePath(dir: Dir, io: Io, sub_path: []const u8) MakePathError!void { | ||
| 587 | _ = try io.vtable.dirMakePath(io.userdata, dir, sub_path, .default_dir); | ||
| 584 | } | 588 | } |
| 585 | 589 | ||
| 586 | pub const MakePathStatus = enum { existed, created }; | 590 | pub const MakePathStatus = enum { existed, created }; |
| ... | @@ -593,6 +597,11 @@ pub fn makePathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permi | ... | @@ -593,6 +597,11 @@ pub fn makePathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permi |
| 593 | 597 | ||
| 594 | pub const MakeOpenPathError = MakeError || OpenError || StatPathError; | 598 | pub const MakeOpenPathError = MakeError || OpenError || StatPathError; |
| 595 | 599 | ||
| 600 | pub const MakeOpenPathOptions = struct { | ||
| 601 | open_options: OpenOptions = .{}, | ||
| 602 | permissions: Permissions = .default_dir, | ||
| 603 | }; | ||
| 604 | |||
| 596 | /// Performs the equivalent of `makePath` followed by `openDir`, atomically if possible. | 605 | /// Performs the equivalent of `makePath` followed by `openDir`, atomically if possible. |
| 597 | /// | 606 | /// |
| 598 | /// When this operation is canceled, it may leave the file system in a | 607 | /// When this operation is canceled, it may leave the file system in a |
| ... | @@ -601,8 +610,8 @@ pub const MakeOpenPathError = MakeError || OpenError || StatPathError; | ... | @@ -601,8 +610,8 @@ pub const MakeOpenPathError = MakeError || OpenError || StatPathError; |
| 601 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | 610 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 602 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | 611 | /// On WASI, `sub_path` should be encoded as valid UTF-8. |
| 603 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | 612 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 604 | pub fn makeOpenPath(dir: Dir, io: Io, sub_path: []const u8, permissions: Permissions, options: OpenOptions) MakeOpenPathError!Dir { | 613 | pub fn makeOpenPath(dir: Dir, io: Io, sub_path: []const u8, options: MakeOpenPathOptions) MakeOpenPathError!Dir { |
| 605 | return io.vtable.dirMakeOpenPath(io.userdata, dir, sub_path, permissions, options); | 614 | return io.vtable.dirMakeOpenPath(io.userdata, dir, sub_path, options.permissions, options.open_options); |
| 606 | } | 615 | } |
| 607 | 616 | ||
| 608 | pub const Stat = File.Stat; | 617 | pub const Stat = File.Stat; |
| ... | @@ -1266,10 +1275,10 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, | ... | @@ -1266,10 +1275,10 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, |
| 1266 | start_over: while (true) { | 1275 | start_over: while (true) { |
| 1267 | var dir = (try parent.deleteTreeOpenInitialSubpath(io, sub_path, kind_hint)) orelse return; | 1276 | var dir = (try parent.deleteTreeOpenInitialSubpath(io, sub_path, kind_hint)) orelse return; |
| 1268 | var cleanup_dir_parent: ?Dir = null; | 1277 | var cleanup_dir_parent: ?Dir = null; |
| 1269 | defer if (cleanup_dir_parent) |*d| d.close(); | 1278 | defer if (cleanup_dir_parent) |*d| d.close(io); |
| 1270 | 1279 | ||
| 1271 | var cleanup_dir = true; | 1280 | var cleanup_dir = true; |
| 1272 | defer if (cleanup_dir) dir.close(); | 1281 | defer if (cleanup_dir) dir.close(io); |
| 1273 | 1282 | ||
| 1274 | // Valid use of max_path_bytes because dir_name_buf will only | 1283 | // Valid use of max_path_bytes because dir_name_buf will only |
| 1275 | // ever store a single path component that was returned from the | 1284 | // ever store a single path component that was returned from the |
| ... | @@ -1315,7 +1324,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, | ... | @@ -1315,7 +1324,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, |
| 1315 | error.Canceled, | 1324 | error.Canceled, |
| 1316 | => |e| return e, | 1325 | => |e| return e, |
| 1317 | }; | 1326 | }; |
| 1318 | if (cleanup_dir_parent) |*d| d.close(); | 1327 | if (cleanup_dir_parent) |*d| d.close(io); |
| 1319 | cleanup_dir_parent = dir; | 1328 | cleanup_dir_parent = dir; |
| 1320 | dir = new_dir; | 1329 | dir = new_dir; |
| 1321 | const result = dir_name_buf[0..entry.name.len]; | 1330 | const result = dir_name_buf[0..entry.name.len]; |
| ... | @@ -1354,7 +1363,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, | ... | @@ -1354,7 +1363,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, |
| 1354 | } | 1363 | } |
| 1355 | // Reached the end of the directory entries, which means we successfully deleted all of them. | 1364 | // Reached the end of the directory entries, which means we successfully deleted all of them. |
| 1356 | // Now to remove the directory itself. | 1365 | // Now to remove the directory itself. |
| 1357 | dir.close(); | 1366 | dir.close(io); |
| 1358 | cleanup_dir = false; | 1367 | cleanup_dir = false; |
| 1359 | 1368 | ||
| 1360 | if (cleanup_dir_parent) |d| { | 1369 | if (cleanup_dir_parent) |d| { |
lib/std/Io/Writer.zig+3-3| ... | @@ -2835,7 +2835,7 @@ test "discarding sendFile" { | ... | @@ -2835,7 +2835,7 @@ test "discarding sendFile" { |
| 2835 | defer tmp_dir.cleanup(); | 2835 | defer tmp_dir.cleanup(); |
| 2836 | 2836 | ||
| 2837 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | 2837 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2838 | defer file.close(); | 2838 | defer file.close(io); |
| 2839 | var r_buffer: [256]u8 = undefined; | 2839 | var r_buffer: [256]u8 = undefined; |
| 2840 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); | 2840 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); |
| 2841 | try file_writer.interface.writeByte('h'); | 2841 | try file_writer.interface.writeByte('h'); |
| ... | @@ -2857,7 +2857,7 @@ test "allocating sendFile" { | ... | @@ -2857,7 +2857,7 @@ test "allocating sendFile" { |
| 2857 | defer tmp_dir.cleanup(); | 2857 | defer tmp_dir.cleanup(); |
| 2858 | 2858 | ||
| 2859 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | 2859 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2860 | defer file.close(); | 2860 | defer file.close(io); |
| 2861 | var r_buffer: [2]u8 = undefined; | 2861 | var r_buffer: [2]u8 = undefined; |
| 2862 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); | 2862 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); |
| 2863 | try file_writer.interface.writeAll("abcd"); | 2863 | try file_writer.interface.writeAll("abcd"); |
| ... | @@ -2881,7 +2881,7 @@ test sendFileReading { | ... | @@ -2881,7 +2881,7 @@ test sendFileReading { |
| 2881 | defer tmp_dir.cleanup(); | 2881 | defer tmp_dir.cleanup(); |
| 2882 | 2882 | ||
| 2883 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | 2883 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2884 | defer file.close(); | 2884 | defer file.close(io); |
| 2885 | var r_buffer: [2]u8 = undefined; | 2885 | var r_buffer: [2]u8 = undefined; |
| 2886 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); | 2886 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); |
| 2887 | try file_writer.interface.writeAll("abcd"); | 2887 | try file_writer.interface.writeAll("abcd"); |
lib/std/Io/net/test.zig+7-3| ... | @@ -232,8 +232,10 @@ test "listen on an in use port" { | ... | @@ -232,8 +232,10 @@ test "listen on an in use port" { |
| 232 | fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void { | 232 | fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void { |
| 233 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 233 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 234 | 234 | ||
| 235 | const io = testing.io; | ||
| 236 | |||
| 235 | const connection = try net.tcpConnectToHost(allocator, name, port); | 237 | const connection = try net.tcpConnectToHost(allocator, name, port); |
| 236 | defer connection.close(); | 238 | defer connection.close(io); |
| 237 | 239 | ||
| 238 | var buf: [100]u8 = undefined; | 240 | var buf: [100]u8 = undefined; |
| 239 | const len = try connection.read(&buf); | 241 | const len = try connection.read(&buf); |
| ... | @@ -244,8 +246,10 @@ fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyer | ... | @@ -244,8 +246,10 @@ fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyer |
| 244 | fn testClient(addr: net.IpAddress) anyerror!void { | 246 | fn testClient(addr: net.IpAddress) anyerror!void { |
| 245 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 247 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 246 | 248 | ||
| 249 | const io = testing.io; | ||
| 250 | |||
| 247 | const socket_file = try net.tcpConnectToAddress(addr); | 251 | const socket_file = try net.tcpConnectToAddress(addr); |
| 248 | defer socket_file.close(); | 252 | defer socket_file.close(io); |
| 249 | 253 | ||
| 250 | var buf: [100]u8 = undefined; | 254 | var buf: [100]u8 = undefined; |
| 251 | const len = try socket_file.read(&buf); | 255 | const len = try socket_file.read(&buf); |
| ... | @@ -330,7 +334,7 @@ test "non-blocking tcp server" { | ... | @@ -330,7 +334,7 @@ test "non-blocking tcp server" { |
| 330 | try testing.expectError(error.WouldBlock, accept_err); | 334 | try testing.expectError(error.WouldBlock, accept_err); |
| 331 | 335 | ||
| 332 | const socket_file = try net.tcpConnectToAddress(server.socket.address); | 336 | const socket_file = try net.tcpConnectToAddress(server.socket.address); |
| 333 | defer socket_file.close(); | 337 | defer socket_file.close(io); |
| 334 | 338 | ||
| 335 | var stream = try server.accept(io); | 339 | var stream = try server.accept(io); |
| 336 | defer stream.close(io); | 340 | defer stream.close(io); |
lib/std/Io/test.zig+11-5| ... | @@ -28,7 +28,7 @@ test "write a file, read it, then delete it" { | ... | @@ -28,7 +28,7 @@ test "write a file, read it, then delete it" { |
| 28 | const tmp_file_name = "temp_test_file.txt"; | 28 | const tmp_file_name = "temp_test_file.txt"; |
| 29 | { | 29 | { |
| 30 | var file = try tmp.dir.createFile(tmp_file_name, .{}); | 30 | var file = try tmp.dir.createFile(tmp_file_name, .{}); |
| 31 | defer file.close(); | 31 | defer file.close(io); |
| 32 | 32 | ||
| 33 | var file_writer = file.writer(&.{}); | 33 | var file_writer = file.writer(&.{}); |
| 34 | const st = &file_writer.interface; | 34 | const st = &file_writer.interface; |
| ... | @@ -45,7 +45,7 @@ test "write a file, read it, then delete it" { | ... | @@ -45,7 +45,7 @@ test "write a file, read it, then delete it" { |
| 45 | 45 | ||
| 46 | { | 46 | { |
| 47 | var file = try tmp.dir.openFile(tmp_file_name, .{}); | 47 | var file = try tmp.dir.openFile(tmp_file_name, .{}); |
| 48 | defer file.close(); | 48 | defer file.close(io); |
| 49 | 49 | ||
| 50 | const file_size = try file.getEndPos(); | 50 | const file_size = try file.getEndPos(); |
| 51 | const expected_file_size: u64 = "begin".len + data.len + "end".len; | 51 | const expected_file_size: u64 = "begin".len + data.len + "end".len; |
| ... | @@ -67,9 +67,11 @@ test "File seek ops" { | ... | @@ -67,9 +67,11 @@ test "File seek ops" { |
| 67 | var tmp = tmpDir(.{}); | 67 | var tmp = tmpDir(.{}); |
| 68 | defer tmp.cleanup(); | 68 | defer tmp.cleanup(); |
| 69 | 69 | ||
| 70 | const io = testing.io; | ||
| 71 | |||
| 70 | const tmp_file_name = "temp_test_file.txt"; | 72 | const tmp_file_name = "temp_test_file.txt"; |
| 71 | var file = try tmp.dir.createFile(tmp_file_name, .{}); | 73 | var file = try tmp.dir.createFile(tmp_file_name, .{}); |
| 72 | defer file.close(); | 74 | defer file.close(io); |
| 73 | 75 | ||
| 74 | try file.writeAll(&([_]u8{0x55} ** 8192)); | 76 | try file.writeAll(&([_]u8{0x55} ** 8192)); |
| 75 | 77 | ||
| ... | @@ -88,12 +90,14 @@ test "File seek ops" { | ... | @@ -88,12 +90,14 @@ test "File seek ops" { |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | test "setEndPos" { | 92 | test "setEndPos" { |
| 93 | const io = testing.io; | ||
| 94 | |||
| 91 | var tmp = tmpDir(.{}); | 95 | var tmp = tmpDir(.{}); |
| 92 | defer tmp.cleanup(); | 96 | defer tmp.cleanup(); |
| 93 | 97 | ||
| 94 | const tmp_file_name = "temp_test_file.txt"; | 98 | const tmp_file_name = "temp_test_file.txt"; |
| 95 | var file = try tmp.dir.createFile(tmp_file_name, .{}); | 99 | var file = try tmp.dir.createFile(tmp_file_name, .{}); |
| 96 | defer file.close(); | 100 | defer file.close(io); |
| 97 | 101 | ||
| 98 | // Verify that the file size changes and the file offset is not moved | 102 | // Verify that the file size changes and the file offset is not moved |
| 99 | try expect((try file.getEndPos()) == 0); | 103 | try expect((try file.getEndPos()) == 0); |
| ... | @@ -111,12 +115,14 @@ test "setEndPos" { | ... | @@ -111,12 +115,14 @@ test "setEndPos" { |
| 111 | } | 115 | } |
| 112 | 116 | ||
| 113 | test "updateTimes" { | 117 | test "updateTimes" { |
| 118 | const io = testing.io; | ||
| 119 | |||
| 114 | var tmp = tmpDir(.{}); | 120 | var tmp = tmpDir(.{}); |
| 115 | defer tmp.cleanup(); | 121 | defer tmp.cleanup(); |
| 116 | 122 | ||
| 117 | const tmp_file_name = "just_a_temporary_file.txt"; | 123 | const tmp_file_name = "just_a_temporary_file.txt"; |
| 118 | var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); | 124 | var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); |
| 119 | defer file.close(); | 125 | defer file.close(io); |
| 120 | 126 | ||
| 121 | const stat_old = try file.stat(); | 127 | const stat_old = try file.stat(); |
| 122 | // Set atime and mtime to 5s before | 128 | // Set atime and mtime to 5s before |
lib/std/Thread.zig+4-3| ... | @@ -7,6 +7,7 @@ const target = builtin.target; | ... | @@ -7,6 +7,7 @@ const target = builtin.target; |
| 7 | const native_os = builtin.os.tag; | 7 | const native_os = builtin.os.tag; |
| 8 | 8 | ||
| 9 | const std = @import("std.zig"); | 9 | const std = @import("std.zig"); |
| 10 | const Io = std.Io; | ||
| 10 | const math = std.math; | 11 | const math = std.math; |
| 11 | const assert = std.debug.assert; | 12 | const assert = std.debug.assert; |
| 12 | const posix = std.posix; | 13 | const posix = std.posix; |
| ... | @@ -176,7 +177,7 @@ pub const SetNameError = error{ | ... | @@ -176,7 +177,7 @@ pub const SetNameError = error{ |
| 176 | InvalidWtf8, | 177 | InvalidWtf8, |
| 177 | } || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError; | 178 | } || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError; |
| 178 | 179 | ||
| 179 | pub fn setName(self: Thread, name: []const u8) SetNameError!void { | 180 | pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { |
| 180 | if (name.len > max_name_len) return error.NameTooLong; | 181 | if (name.len > max_name_len) return error.NameTooLong; |
| 181 | 182 | ||
| 182 | const name_with_terminator = blk: { | 183 | const name_with_terminator = blk: { |
| ... | @@ -208,7 +209,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void { | ... | @@ -208,7 +209,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void { |
| 208 | const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); | 209 | const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); |
| 209 | 210 | ||
| 210 | const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only }); | 211 | const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only }); |
| 211 | defer file.close(); | 212 | defer file.close(io); |
| 212 | 213 | ||
| 213 | try file.writeAll(name); | 214 | try file.writeAll(name); |
| 214 | return; | 215 | return; |
| ... | @@ -325,7 +326,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co | ... | @@ -325,7 +326,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co |
| 325 | const io = threaded.ioBasic(); | 326 | const io = threaded.ioBasic(); |
| 326 | 327 | ||
| 327 | const file = try std.fs.cwd().openFile(path, .{}); | 328 | const file = try std.fs.cwd().openFile(path, .{}); |
| 328 | defer file.close(); | 329 | defer file.close(io); |
| 329 | 330 | ||
| 330 | var file_reader = file.readerStreaming(io, &.{}); | 331 | var file_reader = file.readerStreaming(io, &.{}); |
| 331 | const data_len = file_reader.interface.readSliceShort(buffer_ptr[0 .. max_name_len + 1]) catch |err| switch (err) { | 332 | const data_len = file_reader.interface.readSliceShort(buffer_ptr[0 .. max_name_len + 1]) catch |err| switch (err) { |
lib/std/crypto/Certificate/Bundle.zig+3-3| ... | @@ -181,7 +181,7 @@ pub fn addCertsFromDirPath( | ... | @@ -181,7 +181,7 @@ pub fn addCertsFromDirPath( |
| 181 | sub_dir_path: []const u8, | 181 | sub_dir_path: []const u8, |
| 182 | ) AddCertsFromDirPathError!void { | 182 | ) AddCertsFromDirPathError!void { |
| 183 | var iterable_dir = try dir.openDir(sub_dir_path, .{ .iterate = true }); | 183 | var iterable_dir = try dir.openDir(sub_dir_path, .{ .iterate = true }); |
| 184 | defer iterable_dir.close(); | 184 | defer iterable_dir.close(io); |
| 185 | return addCertsFromDir(cb, gpa, io, iterable_dir); | 185 | return addCertsFromDir(cb, gpa, io, iterable_dir); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| ... | @@ -194,7 +194,7 @@ pub fn addCertsFromDirPathAbsolute( | ... | @@ -194,7 +194,7 @@ pub fn addCertsFromDirPathAbsolute( |
| 194 | ) AddCertsFromDirPathError!void { | 194 | ) AddCertsFromDirPathError!void { |
| 195 | assert(fs.path.isAbsolute(abs_dir_path)); | 195 | assert(fs.path.isAbsolute(abs_dir_path)); |
| 196 | var iterable_dir = try fs.openDirAbsolute(abs_dir_path, .{ .iterate = true }); | 196 | var iterable_dir = try fs.openDirAbsolute(abs_dir_path, .{ .iterate = true }); |
| 197 | defer iterable_dir.close(); | 197 | defer iterable_dir.close(io); |
| 198 | return addCertsFromDir(cb, gpa, io, now, iterable_dir); | 198 | return addCertsFromDir(cb, gpa, io, now, iterable_dir); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| ... | @@ -222,7 +222,7 @@ pub fn addCertsFromFilePathAbsolute( | ... | @@ -222,7 +222,7 @@ pub fn addCertsFromFilePathAbsolute( |
| 222 | abs_file_path: []const u8, | 222 | abs_file_path: []const u8, |
| 223 | ) AddCertsFromFilePathError!void { | 223 | ) AddCertsFromFilePathError!void { |
| 224 | var file = try fs.openFileAbsolute(abs_file_path, .{}); | 224 | var file = try fs.openFileAbsolute(abs_file_path, .{}); |
| 225 | defer file.close(); | 225 | defer file.close(io); |
| 226 | var file_reader = file.reader(io, &.{}); | 226 | var file_reader = file.reader(io, &.{}); |
| 227 | return addCertsFromFile(cb, gpa, &file_reader, now.toSeconds()); | 227 | return addCertsFromFile(cb, gpa, &file_reader, now.toSeconds()); |
| 228 | } | 228 | } |
lib/std/crypto/codecs/asn1/test.zig+1-1| ... | @@ -75,6 +75,6 @@ test AllTypes { | ... | @@ -75,6 +75,6 @@ test AllTypes { |
| 75 | // Use this to update test file. | 75 | // Use this to update test file. |
| 76 | // const dir = try std.fs.cwd().openDir("lib/std/crypto/asn1", .{}); | 76 | // const dir = try std.fs.cwd().openDir("lib/std/crypto/asn1", .{}); |
| 77 | // var file = try dir.createFile(path, .{}); | 77 | // var file = try dir.createFile(path, .{}); |
| 78 | // defer file.close(); | 78 | // defer file.close(io); |
| 79 | // try file.writeAll(buf); | 79 | // try file.writeAll(buf); |
| 80 | } | 80 | } |
lib/std/debug.zig+4-4| ... | @@ -1298,7 +1298,7 @@ test printLineFromFile { | ... | @@ -1298,7 +1298,7 @@ test printLineFromFile { |
| 1298 | } | 1298 | } |
| 1299 | { | 1299 | { |
| 1300 | const file = try test_dir.dir.createFile("line_overlaps_page_boundary.zig", .{}); | 1300 | const file = try test_dir.dir.createFile("line_overlaps_page_boundary.zig", .{}); |
| 1301 | defer file.close(); | 1301 | defer file.close(io); |
| 1302 | const path = try fs.path.join(gpa, &.{ test_dir_path, "line_overlaps_page_boundary.zig" }); | 1302 | const path = try fs.path.join(gpa, &.{ test_dir_path, "line_overlaps_page_boundary.zig" }); |
| 1303 | defer gpa.free(path); | 1303 | defer gpa.free(path); |
| 1304 | 1304 | ||
| ... | @@ -1317,7 +1317,7 @@ test printLineFromFile { | ... | @@ -1317,7 +1317,7 @@ test printLineFromFile { |
| 1317 | } | 1317 | } |
| 1318 | { | 1318 | { |
| 1319 | const file = try test_dir.dir.createFile("file_ends_on_page_boundary.zig", .{}); | 1319 | const file = try test_dir.dir.createFile("file_ends_on_page_boundary.zig", .{}); |
| 1320 | defer file.close(); | 1320 | defer file.close(io); |
| 1321 | const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" }); | 1321 | const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" }); |
| 1322 | defer gpa.free(path); | 1322 | defer gpa.free(path); |
| 1323 | 1323 | ||
| ... | @@ -1331,7 +1331,7 @@ test printLineFromFile { | ... | @@ -1331,7 +1331,7 @@ test printLineFromFile { |
| 1331 | } | 1331 | } |
| 1332 | { | 1332 | { |
| 1333 | const file = try test_dir.dir.createFile("very_long_first_line_spanning_multiple_pages.zig", .{}); | 1333 | const file = try test_dir.dir.createFile("very_long_first_line_spanning_multiple_pages.zig", .{}); |
| 1334 | defer file.close(); | 1334 | defer file.close(io); |
| 1335 | const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" }); | 1335 | const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" }); |
| 1336 | defer gpa.free(path); | 1336 | defer gpa.free(path); |
| 1337 | 1337 | ||
| ... | @@ -1357,7 +1357,7 @@ test printLineFromFile { | ... | @@ -1357,7 +1357,7 @@ test printLineFromFile { |
| 1357 | } | 1357 | } |
| 1358 | { | 1358 | { |
| 1359 | const file = try test_dir.dir.createFile("file_of_newlines.zig", .{}); | 1359 | const file = try test_dir.dir.createFile("file_of_newlines.zig", .{}); |
| 1360 | defer file.close(); | 1360 | defer file.close(io); |
| 1361 | const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" }); | 1361 | const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" }); |
| 1362 | defer gpa.free(path); | 1362 | defer gpa.free(path); |
| 1363 | 1363 |
lib/std/debug/ElfFile.zig+17-9| ... | @@ -1,5 +1,13 @@ | ... | @@ -1,5 +1,13 @@ |
| 1 | //! A helper type for loading an ELF file and collecting its DWARF debug information, unwind | 1 | //! A helper type for loading an ELF file and collecting its DWARF debug information, unwind |
| 2 | //! information, and symbol table. | 2 | //! information, and symbol table. |
| 3 | const ElfFile = @This(); | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const Io = std.Io; | ||
| 7 | const Endian = std.builtin.Endian; | ||
| 8 | const Dwarf = std.debug.Dwarf; | ||
| 9 | const Allocator = std.mem.Allocator; | ||
| 10 | const elf = std.elf; | ||
| 3 | 11 | ||
| 4 | is_64: bool, | 12 | is_64: bool, |
| 5 | endian: Endian, | 13 | endian: Endian, |
| ... | @@ -358,10 +366,17 @@ const Section = struct { | ... | @@ -358,10 +366,17 @@ const Section = struct { |
| 358 | const Array = std.enums.EnumArray(Section.Id, ?Section); | 366 | const Array = std.enums.EnumArray(Section.Id, ?Section); |
| 359 | }; | 367 | }; |
| 360 | 368 | ||
| 361 | fn loadSeparateDebugFile(arena: Allocator, main_loaded: *LoadInnerResult, opt_crc: ?u32, comptime fmt: []const u8, args: anytype) Allocator.Error!?[]align(std.heap.page_size_min) const u8 { | 369 | fn loadSeparateDebugFile( |
| 370 | arena: Allocator, | ||
| 371 | io: Io, | ||
| 372 | main_loaded: *LoadInnerResult, | ||
| 373 | opt_crc: ?u32, | ||
| 374 | comptime fmt: []const u8, | ||
| 375 | args: anytype, | ||
| 376 | ) Allocator.Error!?[]align(std.heap.page_size_min) const u8 { | ||
| 362 | const path = try std.fmt.allocPrint(arena, fmt, args); | 377 | const path = try std.fmt.allocPrint(arena, fmt, args); |
| 363 | const elf_file = std.fs.cwd().openFile(path, .{}) catch return null; | 378 | const elf_file = std.fs.cwd().openFile(path, .{}) catch return null; |
| 364 | defer elf_file.close(); | 379 | defer elf_file.close(io); |
| 365 | 380 | ||
| 366 | const result = loadInner(arena, elf_file, opt_crc) catch |err| switch (err) { | 381 | const result = loadInner(arena, elf_file, opt_crc) catch |err| switch (err) { |
| 367 | error.OutOfMemory => |e| return e, | 382 | error.OutOfMemory => |e| return e, |
| ... | @@ -529,10 +544,3 @@ fn loadInner( | ... | @@ -529,10 +544,3 @@ fn loadInner( |
| 529 | .mapped_mem = mapped_mem, | 544 | .mapped_mem = mapped_mem, |
| 530 | }; | 545 | }; |
| 531 | } | 546 | } |
| 532 | |||
| 533 | const std = @import("std"); | ||
| 534 | const Endian = std.builtin.Endian; | ||
| 535 | const Dwarf = std.debug.Dwarf; | ||
| 536 | const ElfFile = @This(); | ||
| 537 | const Allocator = std.mem.Allocator; | ||
| 538 | const elf = std.elf; |
lib/std/debug/Info.zig+15-6| ... | @@ -5,19 +5,18 @@ | ... | @@ -5,19 +5,18 @@ |
| 5 | //! Unlike `std.debug.SelfInfo`, this API does not assume the debug information | 5 | //! Unlike `std.debug.SelfInfo`, this API does not assume the debug information |
| 6 | //! in question happens to match the host CPU architecture, OS, or other target | 6 | //! in question happens to match the host CPU architecture, OS, or other target |
| 7 | //! properties. | 7 | //! properties. |
| 8 | const Info = @This(); | ||
| 8 | 9 | ||
| 9 | const std = @import("../std.zig"); | 10 | const std = @import("../std.zig"); |
| 11 | const Io = std.Io; | ||
| 10 | const Allocator = std.mem.Allocator; | 12 | const Allocator = std.mem.Allocator; |
| 11 | const Path = std.Build.Cache.Path; | 13 | const Path = std.Build.Cache.Path; |
| 12 | const assert = std.debug.assert; | 14 | const assert = std.debug.assert; |
| 13 | const Coverage = std.debug.Coverage; | 15 | const Coverage = std.debug.Coverage; |
| 14 | const SourceLocation = std.debug.Coverage.SourceLocation; | 16 | const SourceLocation = std.debug.Coverage.SourceLocation; |
| 15 | |||
| 16 | const ElfFile = std.debug.ElfFile; | 17 | const ElfFile = std.debug.ElfFile; |
| 17 | const MachOFile = std.debug.MachOFile; | 18 | const MachOFile = std.debug.MachOFile; |
| 18 | 19 | ||
| 19 | const Info = @This(); | ||
| 20 | |||
| 21 | impl: union(enum) { | 20 | impl: union(enum) { |
| 22 | elf: ElfFile, | 21 | elf: ElfFile, |
| 23 | macho: MachOFile, | 22 | macho: MachOFile, |
| ... | @@ -25,13 +24,23 @@ impl: union(enum) { | ... | @@ -25,13 +24,23 @@ impl: union(enum) { |
| 25 | /// Externally managed, outlives this `Info` instance. | 24 | /// Externally managed, outlives this `Info` instance. |
| 26 | coverage: *Coverage, | 25 | coverage: *Coverage, |
| 27 | 26 | ||
| 28 | pub const LoadError = std.fs.File.OpenError || ElfFile.LoadError || MachOFile.Error || std.debug.Dwarf.ScanError || error{ MissingDebugInfo, UnsupportedDebugInfo }; | 27 | pub const LoadError = error{ |
| 28 | MissingDebugInfo, | ||
| 29 | UnsupportedDebugInfo, | ||
| 30 | } || std.fs.File.OpenError || ElfFile.LoadError || MachOFile.Error || std.debug.Dwarf.ScanError; | ||
| 29 | 31 | ||
| 30 | pub fn load(gpa: Allocator, path: Path, coverage: *Coverage, format: std.Target.ObjectFormat, arch: std.Target.Cpu.Arch) LoadError!Info { | 32 | pub fn load( |
| 33 | gpa: Allocator, | ||
| 34 | io: Io, | ||
| 35 | path: Path, | ||
| 36 | coverage: *Coverage, | ||
| 37 | format: std.Target.ObjectFormat, | ||
| 38 | arch: std.Target.Cpu.Arch, | ||
| 39 | ) LoadError!Info { | ||
| 31 | switch (format) { | 40 | switch (format) { |
| 32 | .elf => { | 41 | .elf => { |
| 33 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); | 42 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); |
| 34 | defer file.close(); | 43 | defer file.close(io); |
| 35 | 44 | ||
| 36 | var elf_file: ElfFile = try .load(gpa, file, null, &.none); | 45 | var elf_file: ElfFile = try .load(gpa, file, null, &.none); |
| 37 | errdefer elf_file.deinit(gpa); | 46 | errdefer elf_file.deinit(gpa); |
lib/std/debug/MachOFile.zig+9-9| ... | @@ -27,13 +27,13 @@ pub fn deinit(mf: *MachOFile, gpa: Allocator) void { | ... | @@ -27,13 +27,13 @@ pub fn deinit(mf: *MachOFile, gpa: Allocator) void { |
| 27 | posix.munmap(mf.mapped_memory); | 27 | posix.munmap(mf.mapped_memory); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | pub fn load(gpa: Allocator, path: []const u8, arch: std.Target.Cpu.Arch) Error!MachOFile { | 30 | pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) Error!MachOFile { |
| 31 | switch (arch) { | 31 | switch (arch) { |
| 32 | .x86_64, .aarch64 => {}, | 32 | .x86_64, .aarch64 => {}, |
| 33 | else => unreachable, | 33 | else => unreachable, |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | const all_mapped_memory = try mapDebugInfoFile(path); | 36 | const all_mapped_memory = try mapDebugInfoFile(io, path); |
| 37 | errdefer posix.munmap(all_mapped_memory); | 37 | errdefer posix.munmap(all_mapped_memory); |
| 38 | 38 | ||
| 39 | // In most cases, the file we just mapped is a Mach-O binary. However, it could be a "universal | 39 | // In most cases, the file we just mapped is a Mach-O binary. However, it could be a "universal |
| ... | @@ -239,7 +239,7 @@ pub fn load(gpa: Allocator, path: []const u8, arch: std.Target.Cpu.Arch) Error!M | ... | @@ -239,7 +239,7 @@ pub fn load(gpa: Allocator, path: []const u8, arch: std.Target.Cpu.Arch) Error!M |
| 239 | .text_vmaddr = text_vmaddr, | 239 | .text_vmaddr = text_vmaddr, |
| 240 | }; | 240 | }; |
| 241 | } | 241 | } |
| 242 | pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, vaddr: u64) !struct { *Dwarf, u64 } { | 242 | pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, io: Io, vaddr: u64) !struct { *Dwarf, u64 } { |
| 243 | const symbol = Symbol.find(mf.symbols, vaddr) orelse return error.MissingDebugInfo; | 243 | const symbol = Symbol.find(mf.symbols, vaddr) orelse return error.MissingDebugInfo; |
| 244 | 244 | ||
| 245 | if (symbol.ofile == Symbol.unknown_ofile) return error.MissingDebugInfo; | 245 | if (symbol.ofile == Symbol.unknown_ofile) return error.MissingDebugInfo; |
| ... | @@ -254,7 +254,7 @@ pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, vaddr: u64) !struct { | ... | @@ -254,7 +254,7 @@ pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, vaddr: u64) !struct { |
| 254 | const gop = try mf.ofiles.getOrPut(gpa, symbol.ofile); | 254 | const gop = try mf.ofiles.getOrPut(gpa, symbol.ofile); |
| 255 | if (!gop.found_existing) { | 255 | if (!gop.found_existing) { |
| 256 | const name = mem.sliceTo(mf.strings[symbol.ofile..], 0); | 256 | const name = mem.sliceTo(mf.strings[symbol.ofile..], 0); |
| 257 | gop.value_ptr.* = loadOFile(gpa, name); | 257 | gop.value_ptr.* = loadOFile(gpa, io, name); |
| 258 | } | 258 | } |
| 259 | const of = &(gop.value_ptr.* catch |err| return err); | 259 | const of = &(gop.value_ptr.* catch |err| return err); |
| 260 | 260 | ||
| ... | @@ -356,7 +356,7 @@ test { | ... | @@ -356,7 +356,7 @@ test { |
| 356 | _ = Symbol; | 356 | _ = Symbol; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { | 359 | fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { |
| 360 | const all_mapped_memory, const mapped_ofile = map: { | 360 | const all_mapped_memory, const mapped_ofile = map: { |
| 361 | const open_paren = paren: { | 361 | const open_paren = paren: { |
| 362 | if (std.mem.endsWith(u8, o_file_name, ")")) { | 362 | if (std.mem.endsWith(u8, o_file_name, ")")) { |
| ... | @@ -365,7 +365,7 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { | ... | @@ -365,7 +365,7 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { |
| 365 | } | 365 | } |
| 366 | } | 366 | } |
| 367 | // Not an archive, just a normal path to a .o file | 367 | // Not an archive, just a normal path to a .o file |
| 368 | const m = try mapDebugInfoFile(o_file_name); | 368 | const m = try mapDebugInfoFile(io, o_file_name); |
| 369 | break :map .{ m, m }; | 369 | break :map .{ m, m }; |
| 370 | }; | 370 | }; |
| 371 | 371 | ||
| ... | @@ -373,7 +373,7 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { | ... | @@ -373,7 +373,7 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { |
| 373 | 373 | ||
| 374 | const archive_path = o_file_name[0..open_paren]; | 374 | const archive_path = o_file_name[0..open_paren]; |
| 375 | const target_name_in_archive = o_file_name[open_paren + 1 .. o_file_name.len - 1]; | 375 | const target_name_in_archive = o_file_name[open_paren + 1 .. o_file_name.len - 1]; |
| 376 | const mapped_archive = try mapDebugInfoFile(archive_path); | 376 | const mapped_archive = try mapDebugInfoFile(io, archive_path); |
| 377 | errdefer posix.munmap(mapped_archive); | 377 | errdefer posix.munmap(mapped_archive); |
| 378 | 378 | ||
| 379 | var ar_reader: Io.Reader = .fixed(mapped_archive); | 379 | var ar_reader: Io.Reader = .fixed(mapped_archive); |
| ... | @@ -511,12 +511,12 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { | ... | @@ -511,12 +511,12 @@ fn loadOFile(gpa: Allocator, o_file_name: []const u8) !OFile { |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | /// Uses `mmap` to map the file at `path` into memory. | 513 | /// Uses `mmap` to map the file at `path` into memory. |
| 514 | fn mapDebugInfoFile(path: []const u8) ![]align(std.heap.page_size_min) const u8 { | 514 | fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { |
| 515 | const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { | 515 | const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 516 | error.FileNotFound => return error.MissingDebugInfo, | 516 | error.FileNotFound => return error.MissingDebugInfo, |
| 517 | else => return error.ReadFailed, | 517 | else => return error.ReadFailed, |
| 518 | }; | 518 | }; |
| 519 | defer file.close(); | 519 | defer file.close(io); |
| 520 | 520 | ||
| 521 | const file_len = std.math.cast( | 521 | const file_len = std.math.cast( |
| 522 | usize, | 522 | usize, |
lib/std/debug/SelfInfo/Elf.zig+5-5| ... | @@ -319,14 +319,14 @@ const Module = struct { | ... | @@ -319,14 +319,14 @@ const Module = struct { |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | /// Assumes we already hold an exclusive lock. | 321 | /// Assumes we already hold an exclusive lock. |
| 322 | fn getLoadedElf(mod: *Module, gpa: Allocator) Error!*LoadedElf { | 322 | fn getLoadedElf(mod: *Module, gpa: Allocator, io: Io) Error!*LoadedElf { |
| 323 | if (mod.loaded_elf == null) mod.loaded_elf = loadElf(mod, gpa); | 323 | if (mod.loaded_elf == null) mod.loaded_elf = loadElf(mod, gpa, io); |
| 324 | return if (mod.loaded_elf.?) |*elf| elf else |err| err; | 324 | return if (mod.loaded_elf.?) |*elf| elf else |err| err; |
| 325 | } | 325 | } |
| 326 | fn loadElf(mod: *Module, gpa: Allocator) Error!LoadedElf { | 326 | fn loadElf(mod: *Module, gpa: Allocator, io: Io) Error!LoadedElf { |
| 327 | const load_result = if (mod.name.len > 0) res: { | 327 | const load_result = if (mod.name.len > 0) res: { |
| 328 | var file = std.fs.cwd().openFile(mod.name, .{}) catch return error.MissingDebugInfo; | 328 | var file = std.fs.cwd().openFile(mod.name, .{}) catch return error.MissingDebugInfo; |
| 329 | defer file.close(); | 329 | defer file.close(io); |
| 330 | break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(mod.name)); | 330 | break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(mod.name)); |
| 331 | } else res: { | 331 | } else res: { |
| 332 | const path = std.fs.selfExePathAlloc(gpa) catch |err| switch (err) { | 332 | const path = std.fs.selfExePathAlloc(gpa) catch |err| switch (err) { |
| ... | @@ -335,7 +335,7 @@ const Module = struct { | ... | @@ -335,7 +335,7 @@ const Module = struct { |
| 335 | }; | 335 | }; |
| 336 | defer gpa.free(path); | 336 | defer gpa.free(path); |
| 337 | var file = std.fs.cwd().openFile(path, .{}) catch return error.MissingDebugInfo; | 337 | var file = std.fs.cwd().openFile(path, .{}) catch return error.MissingDebugInfo; |
| 338 | defer file.close(); | 338 | defer file.close(io); |
| 339 | break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(path)); | 339 | break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(path)); |
| 340 | }; | 340 | }; |
| 341 | 341 |
lib/std/debug/SelfInfo/MachO.zig+2-2| ... | @@ -615,12 +615,12 @@ test { | ... | @@ -615,12 +615,12 @@ test { |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | /// Uses `mmap` to map the file at `path` into memory. | 617 | /// Uses `mmap` to map the file at `path` into memory. |
| 618 | fn mapDebugInfoFile(path: []const u8) ![]align(std.heap.page_size_min) const u8 { | 618 | fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { |
| 619 | const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { | 619 | const file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 620 | error.FileNotFound => return error.MissingDebugInfo, | 620 | error.FileNotFound => return error.MissingDebugInfo, |
| 621 | else => return error.ReadFailed, | 621 | else => return error.ReadFailed, |
| 622 | }; | 622 | }; |
| 623 | defer file.close(); | 623 | defer file.close(io); |
| 624 | 624 | ||
| 625 | const file_end_pos = file.getEndPos() catch |err| switch (err) { | 625 | const file_end_pos = file.getEndPos() catch |err| switch (err) { |
| 626 | error.Unexpected => |e| return e, | 626 | error.Unexpected => |e| return e, |
lib/std/debug/SelfInfo/Windows.zig+3-3| ... | @@ -207,11 +207,11 @@ const Module = struct { | ... | @@ -207,11 +207,11 @@ const Module = struct { |
| 207 | file: fs.File, | 207 | file: fs.File, |
| 208 | section_handle: windows.HANDLE, | 208 | section_handle: windows.HANDLE, |
| 209 | section_view: []const u8, | 209 | section_view: []const u8, |
| 210 | fn deinit(mf: *const MappedFile) void { | 210 | fn deinit(mf: *const MappedFile, io: Io) void { |
| 211 | const process_handle = windows.GetCurrentProcess(); | 211 | const process_handle = windows.GetCurrentProcess(); |
| 212 | assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mf.section_view.ptr)) == .SUCCESS); | 212 | assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mf.section_view.ptr)) == .SUCCESS); |
| 213 | windows.CloseHandle(mf.section_handle); | 213 | windows.CloseHandle(mf.section_handle); |
| 214 | mf.file.close(); | 214 | mf.file.close(io); |
| 215 | } | 215 | } |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
| ... | @@ -447,7 +447,7 @@ const Module = struct { | ... | @@ -447,7 +447,7 @@ const Module = struct { |
| 447 | error.FileNotFound, error.IsDir => break :pdb null, | 447 | error.FileNotFound, error.IsDir => break :pdb null, |
| 448 | else => return error.ReadFailed, | 448 | else => return error.ReadFailed, |
| 449 | }; | 449 | }; |
| 450 | errdefer pdb_file.close(); | 450 | errdefer pdb_file.close(io); |
| 451 | 451 | ||
| 452 | const pdb_reader = try arena.create(Io.File.Reader); | 452 | const pdb_reader = try arena.create(Io.File.Reader); |
| 453 | pdb_reader.* = pdb_file.reader(io, try arena.alloc(u8, 4096)); | 453 | pdb_reader.* = pdb_file.reader(io, try arena.alloc(u8, 4096)); |
lib/std/dynamic_library.zig+18-16| ... | @@ -1,10 +1,12 @@ | ... | @@ -1,10 +1,12 @@ |
| 1 | const std = @import("std.zig"); | ||
| 2 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const native_os = builtin.os.tag; | ||
| 3 | |||
| 4 | const std = @import("std.zig"); | ||
| 5 | const Io = std.Io; | ||
| 3 | const mem = std.mem; | 6 | const mem = std.mem; |
| 4 | const testing = std.testing; | 7 | const testing = std.testing; |
| 5 | const elf = std.elf; | 8 | const elf = std.elf; |
| 6 | const windows = std.os.windows; | 9 | const windows = std.os.windows; |
| 7 | const native_os = builtin.os.tag; | ||
| 8 | const posix = std.posix; | 10 | const posix = std.posix; |
| 9 | 11 | ||
| 10 | /// Cross-platform dynamic library loading and symbol lookup. | 12 | /// Cross-platform dynamic library loading and symbol lookup. |
| ... | @@ -38,8 +40,8 @@ pub const DynLib = struct { | ... | @@ -38,8 +40,8 @@ pub const DynLib = struct { |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | /// Trusts the file. | 42 | /// Trusts the file. |
| 41 | pub fn close(self: *DynLib) void { | 43 | pub fn close(self: *DynLib, io: Io) void { |
| 42 | return self.inner.close(); | 44 | return self.inner.close(io); |
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | pub fn lookup(self: *DynLib, comptime T: type, name: [:0]const u8) ?T { | 47 | pub fn lookup(self: *DynLib, comptime T: type, name: [:0]const u8) ?T { |
| ... | @@ -155,23 +157,23 @@ pub const ElfDynLib = struct { | ... | @@ -155,23 +157,23 @@ pub const ElfDynLib = struct { |
| 155 | dt_gnu_hash: *elf.gnu_hash.Header, | 157 | dt_gnu_hash: *elf.gnu_hash.Header, |
| 156 | }; | 158 | }; |
| 157 | 159 | ||
| 158 | fn openPath(path: []const u8) !std.fs.Dir { | 160 | fn openPath(path: []const u8, io: Io) !std.fs.Dir { |
| 159 | if (path.len == 0) return error.NotDir; | 161 | if (path.len == 0) return error.NotDir; |
| 160 | var parts = std.mem.tokenizeScalar(u8, path, '/'); | 162 | var parts = std.mem.tokenizeScalar(u8, path, '/'); |
| 161 | var parent = if (path[0] == '/') try std.fs.cwd().openDir("/", .{}) else std.fs.cwd(); | 163 | var parent = if (path[0] == '/') try std.fs.cwd().openDir("/", .{}) else std.fs.cwd(); |
| 162 | while (parts.next()) |part| { | 164 | while (parts.next()) |part| { |
| 163 | const child = try parent.openDir(part, .{}); | 165 | const child = try parent.openDir(part, .{}); |
| 164 | parent.close(); | 166 | parent.close(io); |
| 165 | parent = child; | 167 | parent = child; |
| 166 | } | 168 | } |
| 167 | return parent; | 169 | return parent; |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | fn resolveFromSearchPath(search_path: []const u8, file_name: []const u8, delim: u8) ?posix.fd_t { | 172 | fn resolveFromSearchPath(io: Io, search_path: []const u8, file_name: []const u8, delim: u8) ?posix.fd_t { |
| 171 | var paths = std.mem.tokenizeScalar(u8, search_path, delim); | 173 | var paths = std.mem.tokenizeScalar(u8, search_path, delim); |
| 172 | while (paths.next()) |p| { | 174 | while (paths.next()) |p| { |
| 173 | var dir = openPath(p) catch continue; | 175 | var dir = openPath(p) catch continue; |
| 174 | defer dir.close(); | 176 | defer dir.close(io); |
| 175 | const fd = posix.openat(dir.fd, file_name, .{ | 177 | const fd = posix.openat(dir.fd, file_name, .{ |
| 176 | .ACCMODE = .RDONLY, | 178 | .ACCMODE = .RDONLY, |
| 177 | .CLOEXEC = true, | 179 | .CLOEXEC = true, |
| ... | @@ -181,9 +183,9 @@ pub const ElfDynLib = struct { | ... | @@ -181,9 +183,9 @@ pub const ElfDynLib = struct { |
| 181 | return null; | 183 | return null; |
| 182 | } | 184 | } |
| 183 | 185 | ||
| 184 | fn resolveFromParent(dir_path: []const u8, file_name: []const u8) ?posix.fd_t { | 186 | fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t { |
| 185 | var dir = std.fs.cwd().openDir(dir_path, .{}) catch return null; | 187 | var dir = std.fs.cwd().openDir(dir_path, .{}) catch return null; |
| 186 | defer dir.close(); | 188 | defer dir.close(io); |
| 187 | return posix.openat(dir.fd, file_name, .{ | 189 | return posix.openat(dir.fd, file_name, .{ |
| 188 | .ACCMODE = .RDONLY, | 190 | .ACCMODE = .RDONLY, |
| 189 | .CLOEXEC = true, | 191 | .CLOEXEC = true, |
| ... | @@ -195,7 +197,7 @@ pub const ElfDynLib = struct { | ... | @@ -195,7 +197,7 @@ pub const ElfDynLib = struct { |
| 195 | // - DT_RPATH of the calling binary is not used as a search path | 197 | // - DT_RPATH of the calling binary is not used as a search path |
| 196 | // - DT_RUNPATH of the calling binary is not used as a search path | 198 | // - DT_RUNPATH of the calling binary is not used as a search path |
| 197 | // - /etc/ld.so.cache is not read | 199 | // - /etc/ld.so.cache is not read |
| 198 | fn resolveFromName(path_or_name: []const u8) !posix.fd_t { | 200 | fn resolveFromName(io: Io, path_or_name: []const u8) !posix.fd_t { |
| 199 | // If filename contains a slash ("/"), then it is interpreted as a (relative or absolute) pathname | 201 | // If filename contains a slash ("/"), then it is interpreted as a (relative or absolute) pathname |
| 200 | if (std.mem.findScalarPos(u8, path_or_name, 0, '/')) |_| { | 202 | if (std.mem.findScalarPos(u8, path_or_name, 0, '/')) |_| { |
| 201 | return posix.open(path_or_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0); | 203 | return posix.open(path_or_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0); |
| ... | @@ -206,21 +208,21 @@ pub const ElfDynLib = struct { | ... | @@ -206,21 +208,21 @@ pub const ElfDynLib = struct { |
| 206 | std.os.linux.getegid() == std.os.linux.getgid()) | 208 | std.os.linux.getegid() == std.os.linux.getgid()) |
| 207 | { | 209 | { |
| 208 | if (posix.getenvZ("LD_LIBRARY_PATH")) |ld_library_path| { | 210 | if (posix.getenvZ("LD_LIBRARY_PATH")) |ld_library_path| { |
| 209 | if (resolveFromSearchPath(ld_library_path, path_or_name, ':')) |fd| { | 211 | if (resolveFromSearchPath(io, ld_library_path, path_or_name, ':')) |fd| { |
| 210 | return fd; | 212 | return fd; |
| 211 | } | 213 | } |
| 212 | } | 214 | } |
| 213 | } | 215 | } |
| 214 | 216 | ||
| 215 | // Lastly the directories /lib and /usr/lib are searched (in this exact order) | 217 | // Lastly the directories /lib and /usr/lib are searched (in this exact order) |
| 216 | if (resolveFromParent("/lib", path_or_name)) |fd| return fd; | 218 | if (resolveFromParent(io, "/lib", path_or_name)) |fd| return fd; |
| 217 | if (resolveFromParent("/usr/lib", path_or_name)) |fd| return fd; | 219 | if (resolveFromParent(io, "/usr/lib", path_or_name)) |fd| return fd; |
| 218 | return error.FileNotFound; | 220 | return error.FileNotFound; |
| 219 | } | 221 | } |
| 220 | 222 | ||
| 221 | /// Trusts the file. Malicious file will be able to execute arbitrary code. | 223 | /// Trusts the file. Malicious file will be able to execute arbitrary code. |
| 222 | pub fn open(path: []const u8) Error!ElfDynLib { | 224 | pub fn open(io: Io, path: []const u8) Error!ElfDynLib { |
| 223 | const fd = try resolveFromName(path); | 225 | const fd = try resolveFromName(io, path); |
| 224 | defer posix.close(fd); | 226 | defer posix.close(fd); |
| 225 | 227 | ||
| 226 | const file: std.fs.File = .{ .handle = fd }; | 228 | const file: std.fs.File = .{ .handle = fd }; |
lib/std/fs.zig+2-2| ... | @@ -227,7 +227,7 @@ pub fn deleteFileAbsolute(absolute_path: []const u8) Dir.DeleteFileError!void { | ... | @@ -227,7 +227,7 @@ pub fn deleteFileAbsolute(absolute_path: []const u8) Dir.DeleteFileError!void { |
| 227 | /// On Windows, `absolute_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | 227 | /// On Windows, `absolute_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). |
| 228 | /// On WASI, `absolute_path` should be encoded as valid UTF-8. | 228 | /// On WASI, `absolute_path` should be encoded as valid UTF-8. |
| 229 | /// On other platforms, `absolute_path` is an opaque sequence of bytes with no particular encoding. | 229 | /// On other platforms, `absolute_path` is an opaque sequence of bytes with no particular encoding. |
| 230 | pub fn deleteTreeAbsolute(absolute_path: []const u8) !void { | 230 | pub fn deleteTreeAbsolute(io: Io, absolute_path: []const u8) !void { |
| 231 | assert(path.isAbsolute(absolute_path)); | 231 | assert(path.isAbsolute(absolute_path)); |
| 232 | const dirname = path.dirname(absolute_path) orelse return error{ | 232 | const dirname = path.dirname(absolute_path) orelse return error{ |
| 233 | /// Attempt to remove the root file system path. | 233 | /// Attempt to remove the root file system path. |
| ... | @@ -236,7 +236,7 @@ pub fn deleteTreeAbsolute(absolute_path: []const u8) !void { | ... | @@ -236,7 +236,7 @@ pub fn deleteTreeAbsolute(absolute_path: []const u8) !void { |
| 236 | }.CannotDeleteRootDirectory; | 236 | }.CannotDeleteRootDirectory; |
| 237 | 237 | ||
| 238 | var dir = try cwd().openDir(dirname, .{}); | 238 | var dir = try cwd().openDir(dirname, .{}); |
| 239 | defer dir.close(); | 239 | defer dir.close(io); |
| 240 | 240 | ||
| 241 | return dir.deleteTree(path.basename(absolute_path)); | 241 | return dir.deleteTree(path.basename(absolute_path)); |
| 242 | } | 242 | } |
lib/std/fs/test.zig+171-99| ... | @@ -178,6 +178,8 @@ fn setupSymlinkAbsolute(target: []const u8, link: []const u8, flags: SymLinkFlag | ... | @@ -178,6 +178,8 @@ fn setupSymlinkAbsolute(target: []const u8, link: []const u8, flags: SymLinkFlag |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | test "Dir.readLink" { | 180 | test "Dir.readLink" { |
| 181 | const io = testing.io; | ||
| 182 | |||
| 181 | try testWithAllSupportedPathTypes(struct { | 183 | try testWithAllSupportedPathTypes(struct { |
| 182 | fn impl(ctx: *TestContext) !void { | 184 | fn impl(ctx: *TestContext) !void { |
| 183 | // Create some targets | 185 | // Create some targets |
| ... | @@ -208,7 +210,7 @@ test "Dir.readLink" { | ... | @@ -208,7 +210,7 @@ test "Dir.readLink" { |
| 208 | const parent_file = ".." ++ fs.path.sep_str ++ "target.txt"; | 210 | const parent_file = ".." ++ fs.path.sep_str ++ "target.txt"; |
| 209 | const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); | 211 | const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); |
| 210 | var subdir = try ctx.dir.makeOpenPath("subdir", .{}); | 212 | var subdir = try ctx.dir.makeOpenPath("subdir", .{}); |
| 211 | defer subdir.close(); | 213 | defer subdir.close(io); |
| 212 | try setupSymlink(subdir, canonical_parent_file, "relative-link.txt", .{}); | 214 | try setupSymlink(subdir, canonical_parent_file, "relative-link.txt", .{}); |
| 213 | try testReadLink(subdir, canonical_parent_file, "relative-link.txt"); | 215 | try testReadLink(subdir, canonical_parent_file, "relative-link.txt"); |
| 214 | if (builtin.os.tag == .windows) { | 216 | if (builtin.os.tag == .windows) { |
| ... | @@ -268,6 +270,8 @@ fn testReadLinkAbsolute(target_path: []const u8, symlink_path: []const u8) !void | ... | @@ -268,6 +270,8 @@ fn testReadLinkAbsolute(target_path: []const u8, symlink_path: []const u8) !void |
| 268 | } | 270 | } |
| 269 | 271 | ||
| 270 | test "File.stat on a File that is a symlink returns Kind.sym_link" { | 272 | test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 273 | const io = testing.io; | ||
| 274 | |||
| 271 | // This test requires getting a file descriptor of a symlink which | 275 | // This test requires getting a file descriptor of a symlink which |
| 272 | // is not possible on all targets | 276 | // is not possible on all targets |
| 273 | switch (builtin.target.os.tag) { | 277 | switch (builtin.target.os.tag) { |
| ... | @@ -302,7 +306,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { | ... | @@ -302,7 +306,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 302 | .SecurityDescriptor = null, | 306 | .SecurityDescriptor = null, |
| 303 | .SecurityQualityOfService = null, | 307 | .SecurityQualityOfService = null, |
| 304 | }; | 308 | }; |
| 305 | var io: windows.IO_STATUS_BLOCK = undefined; | 309 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 306 | const rc = windows.ntdll.NtCreateFile( | 310 | const rc = windows.ntdll.NtCreateFile( |
| 307 | &handle, | 311 | &handle, |
| 308 | .{ | 312 | .{ |
| ... | @@ -317,7 +321,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { | ... | @@ -317,7 +321,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 317 | }, | 321 | }, |
| 318 | }, | 322 | }, |
| 319 | &attr, | 323 | &attr, |
| 320 | &io, | 324 | &io_status_block, |
| 321 | null, | 325 | null, |
| 322 | .{ .NORMAL = true }, | 326 | .{ .NORMAL = true }, |
| 323 | .VALID_FLAGS, | 327 | .VALID_FLAGS, |
| ... | @@ -352,7 +356,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { | ... | @@ -352,7 +356,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 352 | }, | 356 | }, |
| 353 | else => unreachable, | 357 | else => unreachable, |
| 354 | }; | 358 | }; |
| 355 | defer symlink.close(); | 359 | defer symlink.close(io); |
| 356 | 360 | ||
| 357 | const stat = try symlink.stat(); | 361 | const stat = try symlink.stat(); |
| 358 | try testing.expectEqual(File.Kind.sym_link, stat.kind); | 362 | try testing.expectEqual(File.Kind.sym_link, stat.kind); |
| ... | @@ -361,6 +365,8 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { | ... | @@ -361,6 +365,8 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 361 | } | 365 | } |
| 362 | 366 | ||
| 363 | test "openDir" { | 367 | test "openDir" { |
| 368 | const io = testing.io; | ||
| 369 | |||
| 364 | try testWithAllSupportedPathTypes(struct { | 370 | try testWithAllSupportedPathTypes(struct { |
| 365 | fn impl(ctx: *TestContext) !void { | 371 | fn impl(ctx: *TestContext) !void { |
| 366 | const allocator = ctx.arena.allocator(); | 372 | const allocator = ctx.arena.allocator(); |
| ... | @@ -370,7 +376,7 @@ test "openDir" { | ... | @@ -370,7 +376,7 @@ test "openDir" { |
| 370 | for ([_][]const u8{ "", ".", ".." }) |sub_path| { | 376 | for ([_][]const u8{ "", ".", ".." }) |sub_path| { |
| 371 | const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path }); | 377 | const dir_path = try fs.path.join(allocator, &.{ subdir_path, sub_path }); |
| 372 | var dir = try ctx.dir.openDir(dir_path, .{}); | 378 | var dir = try ctx.dir.openDir(dir_path, .{}); |
| 373 | defer dir.close(); | 379 | defer dir.close(io); |
| 374 | } | 380 | } |
| 375 | } | 381 | } |
| 376 | }.impl); | 382 | }.impl); |
| ... | @@ -393,6 +399,8 @@ test "openDirAbsolute" { | ... | @@ -393,6 +399,8 @@ test "openDirAbsolute" { |
| 393 | if (native_os == .wasi) return error.SkipZigTest; | 399 | if (native_os == .wasi) return error.SkipZigTest; |
| 394 | if (native_os == .openbsd) return error.SkipZigTest; | 400 | if (native_os == .openbsd) return error.SkipZigTest; |
| 395 | 401 | ||
| 402 | const io = testing.io; | ||
| 403 | |||
| 396 | var tmp = tmpDir(.{}); | 404 | var tmp = tmpDir(.{}); |
| 397 | defer tmp.cleanup(); | 405 | defer tmp.cleanup(); |
| 398 | 406 | ||
| ... | @@ -404,7 +412,7 @@ test "openDirAbsolute" { | ... | @@ -404,7 +412,7 @@ test "openDirAbsolute" { |
| 404 | 412 | ||
| 405 | // Can open sub_path | 413 | // Can open sub_path |
| 406 | var tmp_sub = try fs.openDirAbsolute(sub_path, .{}); | 414 | var tmp_sub = try fs.openDirAbsolute(sub_path, .{}); |
| 407 | defer tmp_sub.close(); | 415 | defer tmp_sub.close(io); |
| 408 | 416 | ||
| 409 | const sub_ino = (try tmp_sub.stat()).inode; | 417 | const sub_ino = (try tmp_sub.stat()).inode; |
| 410 | 418 | ||
| ... | @@ -414,7 +422,7 @@ test "openDirAbsolute" { | ... | @@ -414,7 +422,7 @@ test "openDirAbsolute" { |
| 414 | defer testing.allocator.free(dir_path); | 422 | defer testing.allocator.free(dir_path); |
| 415 | 423 | ||
| 416 | var dir = try fs.openDirAbsolute(dir_path, .{}); | 424 | var dir = try fs.openDirAbsolute(dir_path, .{}); |
| 417 | defer dir.close(); | 425 | defer dir.close(io); |
| 418 | 426 | ||
| 419 | const ino = (try dir.stat()).inode; | 427 | const ino = (try dir.stat()).inode; |
| 420 | try testing.expectEqual(tmp_ino, ino); | 428 | try testing.expectEqual(tmp_ino, ino); |
| ... | @@ -426,7 +434,7 @@ test "openDirAbsolute" { | ... | @@ -426,7 +434,7 @@ test "openDirAbsolute" { |
| 426 | defer testing.allocator.free(dir_path); | 434 | defer testing.allocator.free(dir_path); |
| 427 | 435 | ||
| 428 | var dir = try fs.openDirAbsolute(dir_path, .{}); | 436 | var dir = try fs.openDirAbsolute(dir_path, .{}); |
| 429 | defer dir.close(); | 437 | defer dir.close(io); |
| 430 | 438 | ||
| 431 | const ino = (try dir.stat()).inode; | 439 | const ino = (try dir.stat()).inode; |
| 432 | try testing.expectEqual(sub_ino, ino); | 440 | try testing.expectEqual(sub_ino, ino); |
| ... | @@ -438,7 +446,7 @@ test "openDirAbsolute" { | ... | @@ -438,7 +446,7 @@ test "openDirAbsolute" { |
| 438 | defer testing.allocator.free(dir_path); | 446 | defer testing.allocator.free(dir_path); |
| 439 | 447 | ||
| 440 | var dir = try fs.openDirAbsolute(dir_path, .{}); | 448 | var dir = try fs.openDirAbsolute(dir_path, .{}); |
| 441 | defer dir.close(); | 449 | defer dir.close(io); |
| 442 | 450 | ||
| 443 | const ino = (try dir.stat()).inode; | 451 | const ino = (try dir.stat()).inode; |
| 444 | try testing.expectEqual(tmp_ino, ino); | 452 | try testing.expectEqual(tmp_ino, ino); |
| ... | @@ -446,13 +454,15 @@ test "openDirAbsolute" { | ... | @@ -446,13 +454,15 @@ test "openDirAbsolute" { |
| 446 | } | 454 | } |
| 447 | 455 | ||
| 448 | test "openDir cwd parent '..'" { | 456 | test "openDir cwd parent '..'" { |
| 457 | const io = testing.io; | ||
| 458 | |||
| 449 | var dir = fs.cwd().openDir("..", .{}) catch |err| { | 459 | var dir = fs.cwd().openDir("..", .{}) catch |err| { |
| 450 | if (native_os == .wasi and err == error.PermissionDenied) { | 460 | if (native_os == .wasi and err == error.PermissionDenied) { |
| 451 | return; // This is okay. WASI disallows escaping from the fs sandbox | 461 | return; // This is okay. WASI disallows escaping from the fs sandbox |
| 452 | } | 462 | } |
| 453 | return err; | 463 | return err; |
| 454 | }; | 464 | }; |
| 455 | defer dir.close(); | 465 | defer dir.close(io); |
| 456 | } | 466 | } |
| 457 | 467 | ||
| 458 | test "openDir non-cwd parent '..'" { | 468 | test "openDir non-cwd parent '..'" { |
| ... | @@ -461,14 +471,16 @@ test "openDir non-cwd parent '..'" { | ... | @@ -461,14 +471,16 @@ test "openDir non-cwd parent '..'" { |
| 461 | else => {}, | 471 | else => {}, |
| 462 | } | 472 | } |
| 463 | 473 | ||
| 474 | const io = testing.io; | ||
| 475 | |||
| 464 | var tmp = tmpDir(.{}); | 476 | var tmp = tmpDir(.{}); |
| 465 | defer tmp.cleanup(); | 477 | defer tmp.cleanup(); |
| 466 | 478 | ||
| 467 | var subdir = try tmp.dir.makeOpenPath("subdir", .{}); | 479 | var subdir = try tmp.dir.makeOpenPath("subdir", .{}); |
| 468 | defer subdir.close(); | 480 | defer subdir.close(io); |
| 469 | 481 | ||
| 470 | var dir = try subdir.openDir("..", .{}); | 482 | var dir = try subdir.openDir("..", .{}); |
| 471 | defer dir.close(); | 483 | defer dir.close(io); |
| 472 | 484 | ||
| 473 | const expected_path = try tmp.dir.realpathAlloc(testing.allocator, "."); | 485 | const expected_path = try tmp.dir.realpathAlloc(testing.allocator, "."); |
| 474 | defer testing.allocator.free(expected_path); | 486 | defer testing.allocator.free(expected_path); |
| ... | @@ -516,12 +528,14 @@ test "readLinkAbsolute" { | ... | @@ -516,12 +528,14 @@ test "readLinkAbsolute" { |
| 516 | } | 528 | } |
| 517 | 529 | ||
| 518 | test "Dir.Iterator" { | 530 | test "Dir.Iterator" { |
| 531 | const io = testing.io; | ||
| 532 | |||
| 519 | var tmp_dir = tmpDir(.{ .iterate = true }); | 533 | var tmp_dir = tmpDir(.{ .iterate = true }); |
| 520 | defer tmp_dir.cleanup(); | 534 | defer tmp_dir.cleanup(); |
| 521 | 535 | ||
| 522 | // First, create a couple of entries to iterate over. | 536 | // First, create a couple of entries to iterate over. |
| 523 | const file = try tmp_dir.dir.createFile("some_file", .{}); | 537 | const file = try tmp_dir.dir.createFile("some_file", .{}); |
| 524 | file.close(); | 538 | file.close(io); |
| 525 | 539 | ||
| 526 | try tmp_dir.dir.makeDir("some_dir"); | 540 | try tmp_dir.dir.makeDir("some_dir"); |
| 527 | 541 | ||
| ... | @@ -546,6 +560,8 @@ test "Dir.Iterator" { | ... | @@ -546,6 +560,8 @@ test "Dir.Iterator" { |
| 546 | } | 560 | } |
| 547 | 561 | ||
| 548 | test "Dir.Iterator many entries" { | 562 | test "Dir.Iterator many entries" { |
| 563 | const io = testing.io; | ||
| 564 | |||
| 549 | var tmp_dir = tmpDir(.{ .iterate = true }); | 565 | var tmp_dir = tmpDir(.{ .iterate = true }); |
| 550 | defer tmp_dir.cleanup(); | 566 | defer tmp_dir.cleanup(); |
| 551 | 567 | ||
| ... | @@ -555,7 +571,7 @@ test "Dir.Iterator many entries" { | ... | @@ -555,7 +571,7 @@ test "Dir.Iterator many entries" { |
| 555 | while (i < num) : (i += 1) { | 571 | while (i < num) : (i += 1) { |
| 556 | const name = try std.fmt.bufPrint(&buf, "{}", .{i}); | 572 | const name = try std.fmt.bufPrint(&buf, "{}", .{i}); |
| 557 | const file = try tmp_dir.dir.createFile(name, .{}); | 573 | const file = try tmp_dir.dir.createFile(name, .{}); |
| 558 | file.close(); | 574 | file.close(io); |
| 559 | } | 575 | } |
| 560 | 576 | ||
| 561 | var arena = ArenaAllocator.init(testing.allocator); | 577 | var arena = ArenaAllocator.init(testing.allocator); |
| ... | @@ -581,12 +597,14 @@ test "Dir.Iterator many entries" { | ... | @@ -581,12 +597,14 @@ test "Dir.Iterator many entries" { |
| 581 | } | 597 | } |
| 582 | 598 | ||
| 583 | test "Dir.Iterator twice" { | 599 | test "Dir.Iterator twice" { |
| 600 | const io = testing.io; | ||
| 601 | |||
| 584 | var tmp_dir = tmpDir(.{ .iterate = true }); | 602 | var tmp_dir = tmpDir(.{ .iterate = true }); |
| 585 | defer tmp_dir.cleanup(); | 603 | defer tmp_dir.cleanup(); |
| 586 | 604 | ||
| 587 | // First, create a couple of entries to iterate over. | 605 | // First, create a couple of entries to iterate over. |
| 588 | const file = try tmp_dir.dir.createFile("some_file", .{}); | 606 | const file = try tmp_dir.dir.createFile("some_file", .{}); |
| 589 | file.close(); | 607 | file.close(io); |
| 590 | 608 | ||
| 591 | try tmp_dir.dir.makeDir("some_dir"); | 609 | try tmp_dir.dir.makeDir("some_dir"); |
| 592 | 610 | ||
| ... | @@ -614,12 +632,14 @@ test "Dir.Iterator twice" { | ... | @@ -614,12 +632,14 @@ test "Dir.Iterator twice" { |
| 614 | } | 632 | } |
| 615 | 633 | ||
| 616 | test "Dir.Iterator reset" { | 634 | test "Dir.Iterator reset" { |
| 635 | const io = testing.io; | ||
| 636 | |||
| 617 | var tmp_dir = tmpDir(.{ .iterate = true }); | 637 | var tmp_dir = tmpDir(.{ .iterate = true }); |
| 618 | defer tmp_dir.cleanup(); | 638 | defer tmp_dir.cleanup(); |
| 619 | 639 | ||
| 620 | // First, create a couple of entries to iterate over. | 640 | // First, create a couple of entries to iterate over. |
| 621 | const file = try tmp_dir.dir.createFile("some_file", .{}); | 641 | const file = try tmp_dir.dir.createFile("some_file", .{}); |
| 622 | file.close(); | 642 | file.close(io); |
| 623 | 643 | ||
| 624 | try tmp_dir.dir.makeDir("some_dir"); | 644 | try tmp_dir.dir.makeDir("some_dir"); |
| 625 | 645 | ||
| ... | @@ -650,12 +670,14 @@ test "Dir.Iterator reset" { | ... | @@ -650,12 +670,14 @@ test "Dir.Iterator reset" { |
| 650 | } | 670 | } |
| 651 | 671 | ||
| 652 | test "Dir.Iterator but dir is deleted during iteration" { | 672 | test "Dir.Iterator but dir is deleted during iteration" { |
| 673 | const io = testing.io; | ||
| 674 | |||
| 653 | var tmp = std.testing.tmpDir(.{}); | 675 | var tmp = std.testing.tmpDir(.{}); |
| 654 | defer tmp.cleanup(); | 676 | defer tmp.cleanup(); |
| 655 | 677 | ||
| 656 | // Create directory and setup an iterator for it | 678 | // Create directory and setup an iterator for it |
| 657 | var subdir = try tmp.dir.makeOpenPath("subdir", .{ .iterate = true }); | 679 | var subdir = try tmp.dir.makeOpenPath("subdir", .{ .iterate = true }); |
| 658 | defer subdir.close(); | 680 | defer subdir.close(io); |
| 659 | 681 | ||
| 660 | var iterator = subdir.iterate(); | 682 | var iterator = subdir.iterate(); |
| 661 | 683 | ||
| ... | @@ -742,11 +764,13 @@ test "Dir.realpath smoke test" { | ... | @@ -742,11 +764,13 @@ test "Dir.realpath smoke test" { |
| 742 | } | 764 | } |
| 743 | 765 | ||
| 744 | test "readFileAlloc" { | 766 | test "readFileAlloc" { |
| 767 | const io = testing.io; | ||
| 768 | |||
| 745 | var tmp_dir = tmpDir(.{}); | 769 | var tmp_dir = tmpDir(.{}); |
| 746 | defer tmp_dir.cleanup(); | 770 | defer tmp_dir.cleanup(); |
| 747 | 771 | ||
| 748 | var file = try tmp_dir.dir.createFile("test_file", .{ .read = true }); | 772 | var file = try tmp_dir.dir.createFile("test_file", .{ .read = true }); |
| 749 | defer file.close(); | 773 | defer file.close(io); |
| 750 | 774 | ||
| 751 | const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); | 775 | const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); |
| 752 | defer testing.allocator.free(buf1); | 776 | defer testing.allocator.free(buf1); |
| ... | @@ -815,10 +839,12 @@ test "statFile on dangling symlink" { | ... | @@ -815,10 +839,12 @@ test "statFile on dangling symlink" { |
| 815 | test "directory operations on files" { | 839 | test "directory operations on files" { |
| 816 | try testWithAllSupportedPathTypes(struct { | 840 | try testWithAllSupportedPathTypes(struct { |
| 817 | fn impl(ctx: *TestContext) !void { | 841 | fn impl(ctx: *TestContext) !void { |
| 842 | const io = ctx.io; | ||
| 843 | |||
| 818 | const test_file_name = try ctx.transformPath("test_file"); | 844 | const test_file_name = try ctx.transformPath("test_file"); |
| 819 | 845 | ||
| 820 | var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); | 846 | var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); |
| 821 | file.close(); | 847 | file.close(io); |
| 822 | 848 | ||
| 823 | try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); | 849 | try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); |
| 824 | try testing.expectError(error.NotDir, ctx.dir.openDir(test_file_name, .{})); | 850 | try testing.expectError(error.NotDir, ctx.dir.openDir(test_file_name, .{})); |
| ... | @@ -833,7 +859,7 @@ test "directory operations on files" { | ... | @@ -833,7 +859,7 @@ test "directory operations on files" { |
| 833 | file = try ctx.dir.openFile(test_file_name, .{}); | 859 | file = try ctx.dir.openFile(test_file_name, .{}); |
| 834 | const stat = try file.stat(); | 860 | const stat = try file.stat(); |
| 835 | try testing.expectEqual(File.Kind.file, stat.kind); | 861 | try testing.expectEqual(File.Kind.file, stat.kind); |
| 836 | file.close(); | 862 | file.close(io); |
| 837 | } | 863 | } |
| 838 | }.impl); | 864 | }.impl); |
| 839 | } | 865 | } |
| ... | @@ -842,6 +868,8 @@ test "file operations on directories" { | ... | @@ -842,6 +868,8 @@ test "file operations on directories" { |
| 842 | // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 | 868 | // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 |
| 843 | if (native_os == .freebsd) return error.SkipZigTest; | 869 | if (native_os == .freebsd) return error.SkipZigTest; |
| 844 | 870 | ||
| 871 | const io = testing.io; | ||
| 872 | |||
| 845 | try testWithAllSupportedPathTypes(struct { | 873 | try testWithAllSupportedPathTypes(struct { |
| 846 | fn impl(ctx: *TestContext) !void { | 874 | fn impl(ctx: *TestContext) !void { |
| 847 | const test_dir_name = try ctx.transformPath("test_dir"); | 875 | const test_dir_name = try ctx.transformPath("test_dir"); |
| ... | @@ -869,7 +897,7 @@ test "file operations on directories" { | ... | @@ -869,7 +897,7 @@ test "file operations on directories" { |
| 869 | if (native_os == .wasi and builtin.link_libc) { | 897 | if (native_os == .wasi and builtin.link_libc) { |
| 870 | // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747 | 898 | // wasmtime unexpectedly succeeds here, see https://github.com/ziglang/zig/issues/20747 |
| 871 | const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }); | 899 | const handle = try ctx.dir.openFile(test_dir_name, .{ .mode = .read_write }); |
| 872 | handle.close(); | 900 | handle.close(io); |
| 873 | } else { | 901 | } else { |
| 874 | // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms. | 902 | // Note: The `.mode = .read_write` is necessary to ensure the error occurs on all platforms. |
| 875 | // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732 | 903 | // TODO: Add a read-only test as well, see https://github.com/ziglang/zig/issues/5732 |
| ... | @@ -883,21 +911,23 @@ test "file operations on directories" { | ... | @@ -883,21 +911,23 @@ test "file operations on directories" { |
| 883 | 911 | ||
| 884 | // ensure the directory still exists as a sanity check | 912 | // ensure the directory still exists as a sanity check |
| 885 | var dir = try ctx.dir.openDir(test_dir_name, .{}); | 913 | var dir = try ctx.dir.openDir(test_dir_name, .{}); |
| 886 | dir.close(); | 914 | dir.close(io); |
| 887 | } | 915 | } |
| 888 | }.impl); | 916 | }.impl); |
| 889 | } | 917 | } |
| 890 | 918 | ||
| 891 | test "makeOpenPath parent dirs do not exist" { | 919 | test "makeOpenPath parent dirs do not exist" { |
| 920 | const io = testing.io; | ||
| 921 | |||
| 892 | var tmp_dir = tmpDir(.{}); | 922 | var tmp_dir = tmpDir(.{}); |
| 893 | defer tmp_dir.cleanup(); | 923 | defer tmp_dir.cleanup(); |
| 894 | 924 | ||
| 895 | var dir = try tmp_dir.dir.makeOpenPath("root_dir/parent_dir/some_dir", .{}); | 925 | var dir = try tmp_dir.dir.makeOpenPath("root_dir/parent_dir/some_dir", .{}); |
| 896 | dir.close(); | 926 | dir.close(io); |
| 897 | 927 | ||
| 898 | // double check that the full directory structure was created | 928 | // double check that the full directory structure was created |
| 899 | var dir_verification = try tmp_dir.dir.openDir("root_dir/parent_dir/some_dir", .{}); | 929 | var dir_verification = try tmp_dir.dir.openDir("root_dir/parent_dir/some_dir", .{}); |
| 900 | dir_verification.close(); | 930 | dir_verification.close(io); |
| 901 | } | 931 | } |
| 902 | 932 | ||
| 903 | test "deleteDir" { | 933 | test "deleteDir" { |
| ... | @@ -924,6 +954,7 @@ test "deleteDir" { | ... | @@ -924,6 +954,7 @@ test "deleteDir" { |
| 924 | test "Dir.rename files" { | 954 | test "Dir.rename files" { |
| 925 | try testWithAllSupportedPathTypes(struct { | 955 | try testWithAllSupportedPathTypes(struct { |
| 926 | fn impl(ctx: *TestContext) !void { | 956 | fn impl(ctx: *TestContext) !void { |
| 957 | const io = ctx.io; | ||
| 927 | // Rename on Windows can hit intermittent AccessDenied errors | 958 | // Rename on Windows can hit intermittent AccessDenied errors |
| 928 | // when certain conditions are true about the host system. | 959 | // when certain conditions are true about the host system. |
| 929 | // For now, skip this test when the path type is UNC to avoid them. | 960 | // For now, skip this test when the path type is UNC to avoid them. |
| ... | @@ -939,13 +970,13 @@ test "Dir.rename files" { | ... | @@ -939,13 +970,13 @@ test "Dir.rename files" { |
| 939 | const test_file_name = try ctx.transformPath("test_file"); | 970 | const test_file_name = try ctx.transformPath("test_file"); |
| 940 | const renamed_test_file_name = try ctx.transformPath("test_file_renamed"); | 971 | const renamed_test_file_name = try ctx.transformPath("test_file_renamed"); |
| 941 | var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); | 972 | var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); |
| 942 | file.close(); | 973 | file.close(io); |
| 943 | try ctx.dir.rename(test_file_name, renamed_test_file_name); | 974 | try ctx.dir.rename(test_file_name, renamed_test_file_name); |
| 944 | 975 | ||
| 945 | // Ensure the file was renamed | 976 | // Ensure the file was renamed |
| 946 | try testing.expectError(error.FileNotFound, ctx.dir.openFile(test_file_name, .{})); | 977 | try testing.expectError(error.FileNotFound, ctx.dir.openFile(test_file_name, .{})); |
| 947 | file = try ctx.dir.openFile(renamed_test_file_name, .{}); | 978 | file = try ctx.dir.openFile(renamed_test_file_name, .{}); |
| 948 | file.close(); | 979 | file.close(io); |
| 949 | 980 | ||
| 950 | // Rename to self succeeds | 981 | // Rename to self succeeds |
| 951 | try ctx.dir.rename(renamed_test_file_name, renamed_test_file_name); | 982 | try ctx.dir.rename(renamed_test_file_name, renamed_test_file_name); |
| ... | @@ -953,12 +984,12 @@ test "Dir.rename files" { | ... | @@ -953,12 +984,12 @@ test "Dir.rename files" { |
| 953 | // Rename to existing file succeeds | 984 | // Rename to existing file succeeds |
| 954 | const existing_file_path = try ctx.transformPath("existing_file"); | 985 | const existing_file_path = try ctx.transformPath("existing_file"); |
| 955 | var existing_file = try ctx.dir.createFile(existing_file_path, .{ .read = true }); | 986 | var existing_file = try ctx.dir.createFile(existing_file_path, .{ .read = true }); |
| 956 | existing_file.close(); | 987 | existing_file.close(io); |
| 957 | try ctx.dir.rename(renamed_test_file_name, existing_file_path); | 988 | try ctx.dir.rename(renamed_test_file_name, existing_file_path); |
| 958 | 989 | ||
| 959 | try testing.expectError(error.FileNotFound, ctx.dir.openFile(renamed_test_file_name, .{})); | 990 | try testing.expectError(error.FileNotFound, ctx.dir.openFile(renamed_test_file_name, .{})); |
| 960 | file = try ctx.dir.openFile(existing_file_path, .{}); | 991 | file = try ctx.dir.openFile(existing_file_path, .{}); |
| 961 | file.close(); | 992 | file.close(io); |
| 962 | } | 993 | } |
| 963 | }.impl); | 994 | }.impl); |
| 964 | } | 995 | } |
| ... | @@ -966,6 +997,8 @@ test "Dir.rename files" { | ... | @@ -966,6 +997,8 @@ test "Dir.rename files" { |
| 966 | test "Dir.rename directories" { | 997 | test "Dir.rename directories" { |
| 967 | try testWithAllSupportedPathTypes(struct { | 998 | try testWithAllSupportedPathTypes(struct { |
| 968 | fn impl(ctx: *TestContext) !void { | 999 | fn impl(ctx: *TestContext) !void { |
| 1000 | const io = ctx.io; | ||
| 1001 | |||
| 969 | // Rename on Windows can hit intermittent AccessDenied errors | 1002 | // Rename on Windows can hit intermittent AccessDenied errors |
| 970 | // when certain conditions are true about the host system. | 1003 | // when certain conditions are true about the host system. |
| 971 | // For now, skip this test when the path type is UNC to avoid them. | 1004 | // For now, skip this test when the path type is UNC to avoid them. |
| ... | @@ -985,8 +1018,8 @@ test "Dir.rename directories" { | ... | @@ -985,8 +1018,8 @@ test "Dir.rename directories" { |
| 985 | 1018 | ||
| 986 | // Put a file in the directory | 1019 | // Put a file in the directory |
| 987 | var file = try dir.createFile("test_file", .{ .read = true }); | 1020 | var file = try dir.createFile("test_file", .{ .read = true }); |
| 988 | file.close(); | 1021 | file.close(io); |
| 989 | dir.close(); | 1022 | dir.close(io); |
| 990 | 1023 | ||
| 991 | const test_dir_renamed_again_path = try ctx.transformPath("test_dir_renamed_again"); | 1024 | const test_dir_renamed_again_path = try ctx.transformPath("test_dir_renamed_again"); |
| 992 | try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path); | 1025 | try ctx.dir.rename(test_dir_renamed_path, test_dir_renamed_again_path); |
| ... | @@ -995,8 +1028,8 @@ test "Dir.rename directories" { | ... | @@ -995,8 +1028,8 @@ test "Dir.rename directories" { |
| 995 | try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_renamed_path, .{})); | 1028 | try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_renamed_path, .{})); |
| 996 | dir = try ctx.dir.openDir(test_dir_renamed_again_path, .{}); | 1029 | dir = try ctx.dir.openDir(test_dir_renamed_again_path, .{}); |
| 997 | file = try dir.openFile("test_file", .{}); | 1030 | file = try dir.openFile("test_file", .{}); |
| 998 | file.close(); | 1031 | file.close(io); |
| 999 | dir.close(); | 1032 | dir.close(io); |
| 1000 | } | 1033 | } |
| 1001 | }.impl); | 1034 | }.impl); |
| 1002 | } | 1035 | } |
| ... | @@ -1007,6 +1040,8 @@ test "Dir.rename directory onto empty dir" { | ... | @@ -1007,6 +1040,8 @@ test "Dir.rename directory onto empty dir" { |
| 1007 | 1040 | ||
| 1008 | try testWithAllSupportedPathTypes(struct { | 1041 | try testWithAllSupportedPathTypes(struct { |
| 1009 | fn impl(ctx: *TestContext) !void { | 1042 | fn impl(ctx: *TestContext) !void { |
| 1043 | const io = ctx.io; | ||
| 1044 | |||
| 1010 | const test_dir_path = try ctx.transformPath("test_dir"); | 1045 | const test_dir_path = try ctx.transformPath("test_dir"); |
| 1011 | const target_dir_path = try ctx.transformPath("target_dir_path"); | 1046 | const target_dir_path = try ctx.transformPath("target_dir_path"); |
| 1012 | 1047 | ||
| ... | @@ -1017,7 +1052,7 @@ test "Dir.rename directory onto empty dir" { | ... | @@ -1017,7 +1052,7 @@ test "Dir.rename directory onto empty dir" { |
| 1017 | // Ensure the directory was renamed | 1052 | // Ensure the directory was renamed |
| 1018 | try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{})); | 1053 | try testing.expectError(error.FileNotFound, ctx.dir.openDir(test_dir_path, .{})); |
| 1019 | var dir = try ctx.dir.openDir(target_dir_path, .{}); | 1054 | var dir = try ctx.dir.openDir(target_dir_path, .{}); |
| 1020 | dir.close(); | 1055 | dir.close(io); |
| 1021 | } | 1056 | } |
| 1022 | }.impl); | 1057 | }.impl); |
| 1023 | } | 1058 | } |
| ... | @@ -1028,6 +1063,7 @@ test "Dir.rename directory onto non-empty dir" { | ... | @@ -1028,6 +1063,7 @@ test "Dir.rename directory onto non-empty dir" { |
| 1028 | 1063 | ||
| 1029 | try testWithAllSupportedPathTypes(struct { | 1064 | try testWithAllSupportedPathTypes(struct { |
| 1030 | fn impl(ctx: *TestContext) !void { | 1065 | fn impl(ctx: *TestContext) !void { |
| 1066 | const io = ctx.io; | ||
| 1031 | const test_dir_path = try ctx.transformPath("test_dir"); | 1067 | const test_dir_path = try ctx.transformPath("test_dir"); |
| 1032 | const target_dir_path = try ctx.transformPath("target_dir_path"); | 1068 | const target_dir_path = try ctx.transformPath("target_dir_path"); |
| 1033 | 1069 | ||
| ... | @@ -1035,15 +1071,15 @@ test "Dir.rename directory onto non-empty dir" { | ... | @@ -1035,15 +1071,15 @@ test "Dir.rename directory onto non-empty dir" { |
| 1035 | 1071 | ||
| 1036 | var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); | 1072 | var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); |
| 1037 | var file = try target_dir.createFile("test_file", .{ .read = true }); | 1073 | var file = try target_dir.createFile("test_file", .{ .read = true }); |
| 1038 | file.close(); | 1074 | file.close(io); |
| 1039 | target_dir.close(); | 1075 | target_dir.close(io); |
| 1040 | 1076 | ||
| 1041 | // Rename should fail with PathAlreadyExists if target_dir is non-empty | 1077 | // Rename should fail with PathAlreadyExists if target_dir is non-empty |
| 1042 | try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path)); | 1078 | try testing.expectError(error.PathAlreadyExists, ctx.dir.rename(test_dir_path, target_dir_path)); |
| 1043 | 1079 | ||
| 1044 | // Ensure the directory was not renamed | 1080 | // Ensure the directory was not renamed |
| 1045 | var dir = try ctx.dir.openDir(test_dir_path, .{}); | 1081 | var dir = try ctx.dir.openDir(test_dir_path, .{}); |
| 1046 | dir.close(); | 1082 | dir.close(io); |
| 1047 | } | 1083 | } |
| 1048 | }.impl); | 1084 | }.impl); |
| 1049 | } | 1085 | } |
| ... | @@ -1054,11 +1090,12 @@ test "Dir.rename file <-> dir" { | ... | @@ -1054,11 +1090,12 @@ test "Dir.rename file <-> dir" { |
| 1054 | 1090 | ||
| 1055 | try testWithAllSupportedPathTypes(struct { | 1091 | try testWithAllSupportedPathTypes(struct { |
| 1056 | fn impl(ctx: *TestContext) !void { | 1092 | fn impl(ctx: *TestContext) !void { |
| 1093 | const io = ctx.io; | ||
| 1057 | const test_file_path = try ctx.transformPath("test_file"); | 1094 | const test_file_path = try ctx.transformPath("test_file"); |
| 1058 | const test_dir_path = try ctx.transformPath("test_dir"); | 1095 | const test_dir_path = try ctx.transformPath("test_dir"); |
| 1059 | 1096 | ||
| 1060 | var file = try ctx.dir.createFile(test_file_path, .{ .read = true }); | 1097 | var file = try ctx.dir.createFile(test_file_path, .{ .read = true }); |
| 1061 | file.close(); | 1098 | file.close(io); |
| 1062 | try ctx.dir.makeDir(test_dir_path); | 1099 | try ctx.dir.makeDir(test_dir_path); |
| 1063 | try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, test_dir_path)); | 1100 | try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, test_dir_path)); |
| 1064 | try testing.expectError(error.NotDir, ctx.dir.rename(test_dir_path, test_file_path)); | 1101 | try testing.expectError(error.NotDir, ctx.dir.rename(test_dir_path, test_file_path)); |
| ... | @@ -1067,6 +1104,8 @@ test "Dir.rename file <-> dir" { | ... | @@ -1067,6 +1104,8 @@ test "Dir.rename file <-> dir" { |
| 1067 | } | 1104 | } |
| 1068 | 1105 | ||
| 1069 | test "rename" { | 1106 | test "rename" { |
| 1107 | const io = testing.io; | ||
| 1108 | |||
| 1070 | var tmp_dir1 = tmpDir(.{}); | 1109 | var tmp_dir1 = tmpDir(.{}); |
| 1071 | defer tmp_dir1.cleanup(); | 1110 | defer tmp_dir1.cleanup(); |
| 1072 | 1111 | ||
| ... | @@ -1077,19 +1116,21 @@ test "rename" { | ... | @@ -1077,19 +1116,21 @@ test "rename" { |
| 1077 | const test_file_name = "test_file"; | 1116 | const test_file_name = "test_file"; |
| 1078 | const renamed_test_file_name = "test_file_renamed"; | 1117 | const renamed_test_file_name = "test_file_renamed"; |
| 1079 | var file = try tmp_dir1.dir.createFile(test_file_name, .{ .read = true }); | 1118 | var file = try tmp_dir1.dir.createFile(test_file_name, .{ .read = true }); |
| 1080 | file.close(); | 1119 | file.close(io); |
| 1081 | try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); | 1120 | try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); |
| 1082 | 1121 | ||
| 1083 | // ensure the file was renamed | 1122 | // ensure the file was renamed |
| 1084 | try testing.expectError(error.FileNotFound, tmp_dir1.dir.openFile(test_file_name, .{})); | 1123 | try testing.expectError(error.FileNotFound, tmp_dir1.dir.openFile(test_file_name, .{})); |
| 1085 | file = try tmp_dir2.dir.openFile(renamed_test_file_name, .{}); | 1124 | file = try tmp_dir2.dir.openFile(renamed_test_file_name, .{}); |
| 1086 | file.close(); | 1125 | file.close(io); |
| 1087 | } | 1126 | } |
| 1088 | 1127 | ||
| 1089 | test "renameAbsolute" { | 1128 | test "renameAbsolute" { |
| 1090 | if (native_os == .wasi) return error.SkipZigTest; | 1129 | if (native_os == .wasi) return error.SkipZigTest; |
| 1091 | if (native_os == .openbsd) return error.SkipZigTest; | 1130 | if (native_os == .openbsd) return error.SkipZigTest; |
| 1092 | 1131 | ||
| 1132 | const io = testing.io; | ||
| 1133 | |||
| 1093 | var tmp_dir = tmpDir(.{}); | 1134 | var tmp_dir = tmpDir(.{}); |
| 1094 | defer tmp_dir.cleanup(); | 1135 | defer tmp_dir.cleanup(); |
| 1095 | 1136 | ||
| ... | @@ -1109,7 +1150,7 @@ test "renameAbsolute" { | ... | @@ -1109,7 +1150,7 @@ test "renameAbsolute" { |
| 1109 | const test_file_name = "test_file"; | 1150 | const test_file_name = "test_file"; |
| 1110 | const renamed_test_file_name = "test_file_renamed"; | 1151 | const renamed_test_file_name = "test_file_renamed"; |
| 1111 | var file = try tmp_dir.dir.createFile(test_file_name, .{ .read = true }); | 1152 | var file = try tmp_dir.dir.createFile(test_file_name, .{ .read = true }); |
| 1112 | file.close(); | 1153 | file.close(io); |
| 1113 | try fs.renameAbsolute( | 1154 | try fs.renameAbsolute( |
| 1114 | try fs.path.join(allocator, &.{ base_path, test_file_name }), | 1155 | try fs.path.join(allocator, &.{ base_path, test_file_name }), |
| 1115 | try fs.path.join(allocator, &.{ base_path, renamed_test_file_name }), | 1156 | try fs.path.join(allocator, &.{ base_path, renamed_test_file_name }), |
| ... | @@ -1120,7 +1161,7 @@ test "renameAbsolute" { | ... | @@ -1120,7 +1161,7 @@ test "renameAbsolute" { |
| 1120 | file = try tmp_dir.dir.openFile(renamed_test_file_name, .{}); | 1161 | file = try tmp_dir.dir.openFile(renamed_test_file_name, .{}); |
| 1121 | const stat = try file.stat(); | 1162 | const stat = try file.stat(); |
| 1122 | try testing.expectEqual(File.Kind.file, stat.kind); | 1163 | try testing.expectEqual(File.Kind.file, stat.kind); |
| 1123 | file.close(); | 1164 | file.close(io); |
| 1124 | 1165 | ||
| 1125 | // Renaming directories | 1166 | // Renaming directories |
| 1126 | const test_dir_name = "test_dir"; | 1167 | const test_dir_name = "test_dir"; |
| ... | @@ -1134,14 +1175,16 @@ test "renameAbsolute" { | ... | @@ -1134,14 +1175,16 @@ test "renameAbsolute" { |
| 1134 | // ensure the directory was renamed | 1175 | // ensure the directory was renamed |
| 1135 | try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(test_dir_name, .{})); | 1176 | try testing.expectError(error.FileNotFound, tmp_dir.dir.openDir(test_dir_name, .{})); |
| 1136 | var dir = try tmp_dir.dir.openDir(renamed_test_dir_name, .{}); | 1177 | var dir = try tmp_dir.dir.openDir(renamed_test_dir_name, .{}); |
| 1137 | dir.close(); | 1178 | dir.close(io); |
| 1138 | } | 1179 | } |
| 1139 | 1180 | ||
| 1140 | test "openSelfExe" { | 1181 | test "openSelfExe" { |
| 1141 | if (native_os == .wasi) return error.SkipZigTest; | 1182 | if (native_os == .wasi) return error.SkipZigTest; |
| 1142 | 1183 | ||
| 1184 | const io = testing.io; | ||
| 1185 | |||
| 1143 | const self_exe_file = try std.fs.openSelfExe(.{}); | 1186 | const self_exe_file = try std.fs.openSelfExe(.{}); |
| 1144 | self_exe_file.close(); | 1187 | self_exe_file.close(io); |
| 1145 | } | 1188 | } |
| 1146 | 1189 | ||
| 1147 | test "selfExePath" { | 1190 | test "selfExePath" { |
| ... | @@ -1155,13 +1198,15 @@ test "selfExePath" { | ... | @@ -1155,13 +1198,15 @@ test "selfExePath" { |
| 1155 | } | 1198 | } |
| 1156 | 1199 | ||
| 1157 | test "deleteTree does not follow symlinks" { | 1200 | test "deleteTree does not follow symlinks" { |
| 1201 | const io = testing.io; | ||
| 1202 | |||
| 1158 | var tmp = tmpDir(.{}); | 1203 | var tmp = tmpDir(.{}); |
| 1159 | defer tmp.cleanup(); | 1204 | defer tmp.cleanup(); |
| 1160 | 1205 | ||
| 1161 | try tmp.dir.makePath("b"); | 1206 | try tmp.dir.makePath("b"); |
| 1162 | { | 1207 | { |
| 1163 | var a = try tmp.dir.makeOpenPath("a", .{}); | 1208 | var a = try tmp.dir.makeOpenPath("a", .{}); |
| 1164 | defer a.close(); | 1209 | defer a.close(io); |
| 1165 | 1210 | ||
| 1166 | try setupSymlink(a, "../b", "b", .{ .is_directory = true }); | 1211 | try setupSymlink(a, "../b", "b", .{ .is_directory = true }); |
| 1167 | } | 1212 | } |
| ... | @@ -1257,27 +1302,31 @@ test "makePath but sub_path contains pre-existing file" { | ... | @@ -1257,27 +1302,31 @@ test "makePath but sub_path contains pre-existing file" { |
| 1257 | try testing.expectError(error.NotDir, tmp.dir.makePath("foo/bar/baz")); | 1302 | try testing.expectError(error.NotDir, tmp.dir.makePath("foo/bar/baz")); |
| 1258 | } | 1303 | } |
| 1259 | 1304 | ||
| 1260 | fn expectDir(dir: Dir, path: []const u8) !void { | 1305 | fn expectDir(io: Io, dir: Dir, path: []const u8) !void { |
| 1261 | var d = try dir.openDir(path, .{}); | 1306 | var d = try dir.openDir(path, .{}); |
| 1262 | d.close(); | 1307 | d.close(io); |
| 1263 | } | 1308 | } |
| 1264 | 1309 | ||
| 1265 | test "makepath existing directories" { | 1310 | test "makepath existing directories" { |
| 1311 | const io = testing.io; | ||
| 1312 | |||
| 1266 | var tmp = tmpDir(.{}); | 1313 | var tmp = tmpDir(.{}); |
| 1267 | defer tmp.cleanup(); | 1314 | defer tmp.cleanup(); |
| 1268 | 1315 | ||
| 1269 | try tmp.dir.makeDir("A"); | 1316 | try tmp.dir.makeDir("A"); |
| 1270 | var tmpA = try tmp.dir.openDir("A", .{}); | 1317 | var tmpA = try tmp.dir.openDir("A", .{}); |
| 1271 | defer tmpA.close(); | 1318 | defer tmpA.close(io); |
| 1272 | try tmpA.makeDir("B"); | 1319 | try tmpA.makeDir("B"); |
| 1273 | 1320 | ||
| 1274 | const testPath = "A" ++ fs.path.sep_str ++ "B" ++ fs.path.sep_str ++ "C"; | 1321 | const testPath = "A" ++ fs.path.sep_str ++ "B" ++ fs.path.sep_str ++ "C"; |
| 1275 | try tmp.dir.makePath(testPath); | 1322 | try tmp.dir.makePath(testPath); |
| 1276 | 1323 | ||
| 1277 | try expectDir(tmp.dir, testPath); | 1324 | try expectDir(io, tmp.dir, testPath); |
| 1278 | } | 1325 | } |
| 1279 | 1326 | ||
| 1280 | test "makepath through existing valid symlink" { | 1327 | test "makepath through existing valid symlink" { |
| 1328 | const io = testing.io; | ||
| 1329 | |||
| 1281 | var tmp = tmpDir(.{}); | 1330 | var tmp = tmpDir(.{}); |
| 1282 | defer tmp.cleanup(); | 1331 | defer tmp.cleanup(); |
| 1283 | 1332 | ||
| ... | @@ -1286,10 +1335,12 @@ test "makepath through existing valid symlink" { | ... | @@ -1286,10 +1335,12 @@ test "makepath through existing valid symlink" { |
| 1286 | 1335 | ||
| 1287 | try tmp.dir.makePath("working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); | 1336 | try tmp.dir.makePath("working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); |
| 1288 | 1337 | ||
| 1289 | try expectDir(tmp.dir, "realfolder" ++ fs.path.sep_str ++ "in-realfolder"); | 1338 | try expectDir(io, tmp.dir, "realfolder" ++ fs.path.sep_str ++ "in-realfolder"); |
| 1290 | } | 1339 | } |
| 1291 | 1340 | ||
| 1292 | test "makepath relative walks" { | 1341 | test "makepath relative walks" { |
| 1342 | const io = testing.io; | ||
| 1343 | |||
| 1293 | var tmp = tmpDir(.{}); | 1344 | var tmp = tmpDir(.{}); |
| 1294 | defer tmp.cleanup(); | 1345 | defer tmp.cleanup(); |
| 1295 | 1346 | ||
| ... | @@ -1305,21 +1356,23 @@ test "makepath relative walks" { | ... | @@ -1305,21 +1356,23 @@ test "makepath relative walks" { |
| 1305 | .windows => { | 1356 | .windows => { |
| 1306 | // On Windows, .. is resolved before passing the path to NtCreateFile, | 1357 | // On Windows, .. is resolved before passing the path to NtCreateFile, |
| 1307 | // meaning everything except `first/C` drops out. | 1358 | // meaning everything except `first/C` drops out. |
| 1308 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C"); | 1359 | try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "C"); |
| 1309 | try testing.expectError(error.FileNotFound, tmp.dir.access("second", .{})); | 1360 | try testing.expectError(error.FileNotFound, tmp.dir.access("second", .{})); |
| 1310 | try testing.expectError(error.FileNotFound, tmp.dir.access("third", .{})); | 1361 | try testing.expectError(error.FileNotFound, tmp.dir.access("third", .{})); |
| 1311 | }, | 1362 | }, |
| 1312 | else => { | 1363 | else => { |
| 1313 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "A"); | 1364 | try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "A"); |
| 1314 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "B"); | 1365 | try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "B"); |
| 1315 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C"); | 1366 | try expectDir(io, tmp.dir, "first" ++ fs.path.sep_str ++ "C"); |
| 1316 | try expectDir(tmp.dir, "second"); | 1367 | try expectDir(io, tmp.dir, "second"); |
| 1317 | try expectDir(tmp.dir, "third"); | 1368 | try expectDir(io, tmp.dir, "third"); |
| 1318 | }, | 1369 | }, |
| 1319 | } | 1370 | } |
| 1320 | } | 1371 | } |
| 1321 | 1372 | ||
| 1322 | test "makepath ignores '.'" { | 1373 | test "makepath ignores '.'" { |
| 1374 | const io = testing.io; | ||
| 1375 | |||
| 1323 | var tmp = tmpDir(.{}); | 1376 | var tmp = tmpDir(.{}); |
| 1324 | defer tmp.cleanup(); | 1377 | defer tmp.cleanup(); |
| 1325 | 1378 | ||
| ... | @@ -1337,14 +1390,14 @@ test "makepath ignores '.'" { | ... | @@ -1337,14 +1390,14 @@ test "makepath ignores '.'" { |
| 1337 | 1390 | ||
| 1338 | try tmp.dir.makePath(dotPath); | 1391 | try tmp.dir.makePath(dotPath); |
| 1339 | 1392 | ||
| 1340 | try expectDir(tmp.dir, expectedPath); | 1393 | try expectDir(io, tmp.dir, expectedPath); |
| 1341 | } | 1394 | } |
| 1342 | 1395 | ||
| 1343 | fn testFilenameLimits(iterable_dir: Dir, maxed_filename: []const u8) !void { | 1396 | fn testFilenameLimits(io: Io, iterable_dir: Dir, maxed_filename: []const u8) !void { |
| 1344 | // setup, create a dir and a nested file both with maxed filenames, and walk the dir | 1397 | // setup, create a dir and a nested file both with maxed filenames, and walk the dir |
| 1345 | { | 1398 | { |
| 1346 | var maxed_dir = try iterable_dir.makeOpenPath(maxed_filename, .{}); | 1399 | var maxed_dir = try iterable_dir.makeOpenPath(maxed_filename, .{}); |
| 1347 | defer maxed_dir.close(); | 1400 | defer maxed_dir.close(io); |
| 1348 | 1401 | ||
| 1349 | try maxed_dir.writeFile(.{ .sub_path = maxed_filename, .data = "" }); | 1402 | try maxed_dir.writeFile(.{ .sub_path = maxed_filename, .data = "" }); |
| 1350 | 1403 | ||
| ... | @@ -1364,6 +1417,8 @@ fn testFilenameLimits(iterable_dir: Dir, maxed_filename: []const u8) !void { | ... | @@ -1364,6 +1417,8 @@ fn testFilenameLimits(iterable_dir: Dir, maxed_filename: []const u8) !void { |
| 1364 | } | 1417 | } |
| 1365 | 1418 | ||
| 1366 | test "max file name component lengths" { | 1419 | test "max file name component lengths" { |
| 1420 | const io = testing.io; | ||
| 1421 | |||
| 1367 | var tmp = tmpDir(.{ .iterate = true }); | 1422 | var tmp = tmpDir(.{ .iterate = true }); |
| 1368 | defer tmp.cleanup(); | 1423 | defer tmp.cleanup(); |
| 1369 | 1424 | ||
| ... | @@ -1371,16 +1426,16 @@ test "max file name component lengths" { | ... | @@ -1371,16 +1426,16 @@ test "max file name component lengths" { |
| 1371 | // U+FFFF is the character with the largest code point that is encoded as a single | 1426 | // U+FFFF is the character with the largest code point that is encoded as a single |
| 1372 | // UTF-16 code unit, so Windows allows for NAME_MAX of them. | 1427 | // UTF-16 code unit, so Windows allows for NAME_MAX of them. |
| 1373 | const maxed_windows_filename = ("\u{FFFF}".*) ** windows.NAME_MAX; | 1428 | const maxed_windows_filename = ("\u{FFFF}".*) ** windows.NAME_MAX; |
| 1374 | try testFilenameLimits(tmp.dir, &maxed_windows_filename); | 1429 | try testFilenameLimits(io, tmp.dir, &maxed_windows_filename); |
| 1375 | } else if (native_os == .wasi) { | 1430 | } else if (native_os == .wasi) { |
| 1376 | // On WASI, the maxed filename depends on the host OS, so in order for this test to | 1431 | // On WASI, the maxed filename depends on the host OS, so in order for this test to |
| 1377 | // work on any host, we need to use a length that will work for all platforms | 1432 | // work on any host, we need to use a length that will work for all platforms |
| 1378 | // (i.e. the minimum max_name_bytes of all supported platforms). | 1433 | // (i.e. the minimum max_name_bytes of all supported platforms). |
| 1379 | const maxed_wasi_filename = [_]u8{'1'} ** 255; | 1434 | const maxed_wasi_filename = [_]u8{'1'} ** 255; |
| 1380 | try testFilenameLimits(tmp.dir, &maxed_wasi_filename); | 1435 | try testFilenameLimits(io, tmp.dir, &maxed_wasi_filename); |
| 1381 | } else { | 1436 | } else { |
| 1382 | const maxed_ascii_filename = [_]u8{'1'} ** std.fs.max_name_bytes; | 1437 | const maxed_ascii_filename = [_]u8{'1'} ** std.fs.max_name_bytes; |
| 1383 | try testFilenameLimits(tmp.dir, &maxed_ascii_filename); | 1438 | try testFilenameLimits(io, tmp.dir, &maxed_ascii_filename); |
| 1384 | } | 1439 | } |
| 1385 | } | 1440 | } |
| 1386 | 1441 | ||
| ... | @@ -1399,7 +1454,7 @@ test "writev, readv" { | ... | @@ -1399,7 +1454,7 @@ test "writev, readv" { |
| 1399 | var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; | 1454 | var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; |
| 1400 | 1455 | ||
| 1401 | var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); | 1456 | var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); |
| 1402 | defer src_file.close(); | 1457 | defer src_file.close(io); |
| 1403 | 1458 | ||
| 1404 | var writer = src_file.writerStreaming(&.{}); | 1459 | var writer = src_file.writerStreaming(&.{}); |
| 1405 | 1460 | ||
| ... | @@ -1429,7 +1484,7 @@ test "pwritev, preadv" { | ... | @@ -1429,7 +1484,7 @@ test "pwritev, preadv" { |
| 1429 | var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; | 1484 | var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; |
| 1430 | 1485 | ||
| 1431 | var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); | 1486 | var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); |
| 1432 | defer src_file.close(); | 1487 | defer src_file.close(io); |
| 1433 | 1488 | ||
| 1434 | var writer = src_file.writer(&.{}); | 1489 | var writer = src_file.writer(&.{}); |
| 1435 | 1490 | ||
| ... | @@ -1459,7 +1514,7 @@ test "setEndPos" { | ... | @@ -1459,7 +1514,7 @@ test "setEndPos" { |
| 1459 | const file_name = "afile.txt"; | 1514 | const file_name = "afile.txt"; |
| 1460 | try tmp.dir.writeFile(.{ .sub_path = file_name, .data = "ninebytes" }); | 1515 | try tmp.dir.writeFile(.{ .sub_path = file_name, .data = "ninebytes" }); |
| 1461 | const f = try tmp.dir.openFile(file_name, .{ .mode = .read_write }); | 1516 | const f = try tmp.dir.openFile(file_name, .{ .mode = .read_write }); |
| 1462 | defer f.close(); | 1517 | defer f.close(io); |
| 1463 | 1518 | ||
| 1464 | const initial_size = try f.getEndPos(); | 1519 | const initial_size = try f.getEndPos(); |
| 1465 | var buffer: [32]u8 = undefined; | 1520 | var buffer: [32]u8 = undefined; |
| ... | @@ -1522,21 +1577,21 @@ test "sendfile" { | ... | @@ -1522,21 +1577,21 @@ test "sendfile" { |
| 1522 | try tmp.dir.makePath("os_test_tmp"); | 1577 | try tmp.dir.makePath("os_test_tmp"); |
| 1523 | 1578 | ||
| 1524 | var dir = try tmp.dir.openDir("os_test_tmp", .{}); | 1579 | var dir = try tmp.dir.openDir("os_test_tmp", .{}); |
| 1525 | defer dir.close(); | 1580 | defer dir.close(io); |
| 1526 | 1581 | ||
| 1527 | const line1 = "line1\n"; | 1582 | const line1 = "line1\n"; |
| 1528 | const line2 = "second line\n"; | 1583 | const line2 = "second line\n"; |
| 1529 | var vecs = [_][]const u8{ line1, line2 }; | 1584 | var vecs = [_][]const u8{ line1, line2 }; |
| 1530 | 1585 | ||
| 1531 | var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); | 1586 | var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); |
| 1532 | defer src_file.close(); | 1587 | defer src_file.close(io); |
| 1533 | { | 1588 | { |
| 1534 | var fw = src_file.writer(&.{}); | 1589 | var fw = src_file.writer(&.{}); |
| 1535 | try fw.interface.writeVecAll(&vecs); | 1590 | try fw.interface.writeVecAll(&vecs); |
| 1536 | } | 1591 | } |
| 1537 | 1592 | ||
| 1538 | var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); | 1593 | var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); |
| 1539 | defer dest_file.close(); | 1594 | defer dest_file.close(io); |
| 1540 | 1595 | ||
| 1541 | const header1 = "header1\n"; | 1596 | const header1 = "header1\n"; |
| 1542 | const header2 = "second header\n"; | 1597 | const header2 = "second header\n"; |
| ... | @@ -1569,15 +1624,15 @@ test "sendfile with buffered data" { | ... | @@ -1569,15 +1624,15 @@ test "sendfile with buffered data" { |
| 1569 | try tmp.dir.makePath("os_test_tmp"); | 1624 | try tmp.dir.makePath("os_test_tmp"); |
| 1570 | 1625 | ||
| 1571 | var dir = try tmp.dir.openDir("os_test_tmp", .{}); | 1626 | var dir = try tmp.dir.openDir("os_test_tmp", .{}); |
| 1572 | defer dir.close(); | 1627 | defer dir.close(io); |
| 1573 | 1628 | ||
| 1574 | var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); | 1629 | var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); |
| 1575 | defer src_file.close(); | 1630 | defer src_file.close(io); |
| 1576 | 1631 | ||
| 1577 | try src_file.writeAll("AAAABBBB"); | 1632 | try src_file.writeAll("AAAABBBB"); |
| 1578 | 1633 | ||
| 1579 | var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); | 1634 | var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); |
| 1580 | defer dest_file.close(); | 1635 | defer dest_file.close(io); |
| 1581 | 1636 | ||
| 1582 | var src_buffer: [32]u8 = undefined; | 1637 | var src_buffer: [32]u8 = undefined; |
| 1583 | var file_reader = src_file.reader(io, &src_buffer); | 1638 | var file_reader = src_file.reader(io, &src_buffer); |
| ... | @@ -1659,10 +1714,11 @@ test "open file with exclusive nonblocking lock twice" { | ... | @@ -1659,10 +1714,11 @@ test "open file with exclusive nonblocking lock twice" { |
| 1659 | 1714 | ||
| 1660 | try testWithAllSupportedPathTypes(struct { | 1715 | try testWithAllSupportedPathTypes(struct { |
| 1661 | fn impl(ctx: *TestContext) !void { | 1716 | fn impl(ctx: *TestContext) !void { |
| 1717 | const io = ctx.io; | ||
| 1662 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); | 1718 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); |
| 1663 | 1719 | ||
| 1664 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); | 1720 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); |
| 1665 | defer file1.close(); | 1721 | defer file1.close(io); |
| 1666 | 1722 | ||
| 1667 | const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); | 1723 | const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); |
| 1668 | try testing.expectError(error.WouldBlock, file2); | 1724 | try testing.expectError(error.WouldBlock, file2); |
| ... | @@ -1675,10 +1731,11 @@ test "open file with shared and exclusive nonblocking lock" { | ... | @@ -1675,10 +1731,11 @@ test "open file with shared and exclusive nonblocking lock" { |
| 1675 | 1731 | ||
| 1676 | try testWithAllSupportedPathTypes(struct { | 1732 | try testWithAllSupportedPathTypes(struct { |
| 1677 | fn impl(ctx: *TestContext) !void { | 1733 | fn impl(ctx: *TestContext) !void { |
| 1734 | const io = ctx.io; | ||
| 1678 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); | 1735 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); |
| 1679 | 1736 | ||
| 1680 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); | 1737 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); |
| 1681 | defer file1.close(); | 1738 | defer file1.close(io); |
| 1682 | 1739 | ||
| 1683 | const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); | 1740 | const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); |
| 1684 | try testing.expectError(error.WouldBlock, file2); | 1741 | try testing.expectError(error.WouldBlock, file2); |
| ... | @@ -1691,10 +1748,11 @@ test "open file with exclusive and shared nonblocking lock" { | ... | @@ -1691,10 +1748,11 @@ test "open file with exclusive and shared nonblocking lock" { |
| 1691 | 1748 | ||
| 1692 | try testWithAllSupportedPathTypes(struct { | 1749 | try testWithAllSupportedPathTypes(struct { |
| 1693 | fn impl(ctx: *TestContext) !void { | 1750 | fn impl(ctx: *TestContext) !void { |
| 1751 | const io = ctx.io; | ||
| 1694 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); | 1752 | const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); |
| 1695 | 1753 | ||
| 1696 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); | 1754 | const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); |
| 1697 | defer file1.close(); | 1755 | defer file1.close(io); |
| 1698 | 1756 | ||
| 1699 | const file2 = ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); | 1757 | const file2 = ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); |
| 1700 | try testing.expectError(error.WouldBlock, file2); | 1758 | try testing.expectError(error.WouldBlock, file2); |
| ... | @@ -1707,10 +1765,11 @@ test "open file with exclusive lock twice, make sure second lock waits" { | ... | @@ -1707,10 +1765,11 @@ test "open file with exclusive lock twice, make sure second lock waits" { |
| 1707 | 1765 | ||
| 1708 | try testWithAllSupportedPathTypes(struct { | 1766 | try testWithAllSupportedPathTypes(struct { |
| 1709 | fn impl(ctx: *TestContext) !void { | 1767 | fn impl(ctx: *TestContext) !void { |
| 1768 | const io = ctx.io; | ||
| 1710 | const filename = try ctx.transformPath("file_lock_test.txt"); | 1769 | const filename = try ctx.transformPath("file_lock_test.txt"); |
| 1711 | 1770 | ||
| 1712 | const file = try ctx.dir.createFile(filename, .{ .lock = .exclusive }); | 1771 | const file = try ctx.dir.createFile(filename, .{ .lock = .exclusive }); |
| 1713 | errdefer file.close(); | 1772 | errdefer file.close(io); |
| 1714 | 1773 | ||
| 1715 | const S = struct { | 1774 | const S = struct { |
| 1716 | fn checkFn(dir: *fs.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { | 1775 | fn checkFn(dir: *fs.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { |
| ... | @@ -1718,7 +1777,7 @@ test "open file with exclusive lock twice, make sure second lock waits" { | ... | @@ -1718,7 +1777,7 @@ test "open file with exclusive lock twice, make sure second lock waits" { |
| 1718 | const file1 = try dir.createFile(path, .{ .lock = .exclusive }); | 1777 | const file1 = try dir.createFile(path, .{ .lock = .exclusive }); |
| 1719 | 1778 | ||
| 1720 | locked.set(); | 1779 | locked.set(); |
| 1721 | file1.close(); | 1780 | file1.close(io); |
| 1722 | } | 1781 | } |
| 1723 | }; | 1782 | }; |
| 1724 | 1783 | ||
| ... | @@ -1739,7 +1798,7 @@ test "open file with exclusive lock twice, make sure second lock waits" { | ... | @@ -1739,7 +1798,7 @@ test "open file with exclusive lock twice, make sure second lock waits" { |
| 1739 | try testing.expectError(error.Timeout, locked.timedWait(10 * std.time.ns_per_ms)); | 1798 | try testing.expectError(error.Timeout, locked.timedWait(10 * std.time.ns_per_ms)); |
| 1740 | 1799 | ||
| 1741 | // Release the file lock which should unlock the thread to lock it and set the locked event. | 1800 | // Release the file lock which should unlock the thread to lock it and set the locked event. |
| 1742 | file.close(); | 1801 | file.close(io); |
| 1743 | locked.wait(); | 1802 | locked.wait(); |
| 1744 | } | 1803 | } |
| 1745 | }.impl); | 1804 | }.impl); |
| ... | @@ -1748,6 +1807,8 @@ test "open file with exclusive lock twice, make sure second lock waits" { | ... | @@ -1748,6 +1807,8 @@ test "open file with exclusive lock twice, make sure second lock waits" { |
| 1748 | test "open file with exclusive nonblocking lock twice (absolute paths)" { | 1807 | test "open file with exclusive nonblocking lock twice (absolute paths)" { |
| 1749 | if (native_os == .wasi) return error.SkipZigTest; | 1808 | if (native_os == .wasi) return error.SkipZigTest; |
| 1750 | 1809 | ||
| 1810 | const io = testing.io; | ||
| 1811 | |||
| 1751 | var random_bytes: [12]u8 = undefined; | 1812 | var random_bytes: [12]u8 = undefined; |
| 1752 | std.crypto.random.bytes(&random_bytes); | 1813 | std.crypto.random.bytes(&random_bytes); |
| 1753 | 1814 | ||
| ... | @@ -1774,18 +1835,19 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" { | ... | @@ -1774,18 +1835,19 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" { |
| 1774 | .lock = .exclusive, | 1835 | .lock = .exclusive, |
| 1775 | .lock_nonblocking = true, | 1836 | .lock_nonblocking = true, |
| 1776 | }); | 1837 | }); |
| 1777 | file1.close(); | 1838 | file1.close(io); |
| 1778 | try testing.expectError(error.WouldBlock, file2); | 1839 | try testing.expectError(error.WouldBlock, file2); |
| 1779 | } | 1840 | } |
| 1780 | 1841 | ||
| 1781 | test "read from locked file" { | 1842 | test "read from locked file" { |
| 1782 | try testWithAllSupportedPathTypes(struct { | 1843 | try testWithAllSupportedPathTypes(struct { |
| 1783 | fn impl(ctx: *TestContext) !void { | 1844 | fn impl(ctx: *TestContext) !void { |
| 1845 | const io = ctx.io; | ||
| 1784 | const filename = try ctx.transformPath("read_lock_file_test.txt"); | 1846 | const filename = try ctx.transformPath("read_lock_file_test.txt"); |
| 1785 | 1847 | ||
| 1786 | { | 1848 | { |
| 1787 | const f = try ctx.dir.createFile(filename, .{ .read = true }); | 1849 | const f = try ctx.dir.createFile(filename, .{ .read = true }); |
| 1788 | defer f.close(); | 1850 | defer f.close(io); |
| 1789 | var buffer: [1]u8 = undefined; | 1851 | var buffer: [1]u8 = undefined; |
| 1790 | _ = try f.read(&buffer); | 1852 | _ = try f.read(&buffer); |
| 1791 | } | 1853 | } |
| ... | @@ -1794,9 +1856,9 @@ test "read from locked file" { | ... | @@ -1794,9 +1856,9 @@ test "read from locked file" { |
| 1794 | .read = true, | 1856 | .read = true, |
| 1795 | .lock = .exclusive, | 1857 | .lock = .exclusive, |
| 1796 | }); | 1858 | }); |
| 1797 | defer f.close(); | 1859 | defer f.close(io); |
| 1798 | const f2 = try ctx.dir.openFile(filename, .{}); | 1860 | const f2 = try ctx.dir.openFile(filename, .{}); |
| 1799 | defer f2.close(); | 1861 | defer f2.close(io); |
| 1800 | var buffer: [1]u8 = undefined; | 1862 | var buffer: [1]u8 = undefined; |
| 1801 | if (builtin.os.tag == .windows) { | 1863 | if (builtin.os.tag == .windows) { |
| 1802 | try std.testing.expectError(error.LockViolation, f2.read(&buffer)); | 1864 | try std.testing.expectError(error.LockViolation, f2.read(&buffer)); |
| ... | @@ -1809,6 +1871,8 @@ test "read from locked file" { | ... | @@ -1809,6 +1871,8 @@ test "read from locked file" { |
| 1809 | } | 1871 | } |
| 1810 | 1872 | ||
| 1811 | test "walker" { | 1873 | test "walker" { |
| 1874 | const io = testing.io; | ||
| 1875 | |||
| 1812 | var tmp = tmpDir(.{ .iterate = true }); | 1876 | var tmp = tmpDir(.{ .iterate = true }); |
| 1813 | defer tmp.cleanup(); | 1877 | defer tmp.cleanup(); |
| 1814 | 1878 | ||
| ... | @@ -1857,13 +1921,15 @@ test "walker" { | ... | @@ -1857,13 +1921,15 @@ test "walker" { |
| 1857 | }; | 1921 | }; |
| 1858 | // make sure that the entry.dir is the containing dir | 1922 | // make sure that the entry.dir is the containing dir |
| 1859 | var entry_dir = try entry.dir.openDir(entry.basename, .{}); | 1923 | var entry_dir = try entry.dir.openDir(entry.basename, .{}); |
| 1860 | defer entry_dir.close(); | 1924 | defer entry_dir.close(io); |
| 1861 | num_walked += 1; | 1925 | num_walked += 1; |
| 1862 | } | 1926 | } |
| 1863 | try testing.expectEqual(expected_paths.kvs.len, num_walked); | 1927 | try testing.expectEqual(expected_paths.kvs.len, num_walked); |
| 1864 | } | 1928 | } |
| 1865 | 1929 | ||
| 1866 | test "selective walker, skip entries that start with ." { | 1930 | test "selective walker, skip entries that start with ." { |
| 1931 | const io = testing.io; | ||
| 1932 | |||
| 1867 | var tmp = tmpDir(.{ .iterate = true }); | 1933 | var tmp = tmpDir(.{ .iterate = true }); |
| 1868 | defer tmp.cleanup(); | 1934 | defer tmp.cleanup(); |
| 1869 | 1935 | ||
| ... | @@ -1923,7 +1989,7 @@ test "selective walker, skip entries that start with ." { | ... | @@ -1923,7 +1989,7 @@ test "selective walker, skip entries that start with ." { |
| 1923 | 1989 | ||
| 1924 | // make sure that the entry.dir is the containing dir | 1990 | // make sure that the entry.dir is the containing dir |
| 1925 | var entry_dir = try entry.dir.openDir(entry.basename, .{}); | 1991 | var entry_dir = try entry.dir.openDir(entry.basename, .{}); |
| 1926 | defer entry_dir.close(); | 1992 | defer entry_dir.close(io); |
| 1927 | num_walked += 1; | 1993 | num_walked += 1; |
| 1928 | } | 1994 | } |
| 1929 | try testing.expectEqual(expected_paths.kvs.len, num_walked); | 1995 | try testing.expectEqual(expected_paths.kvs.len, num_walked); |
| ... | @@ -1968,16 +2034,16 @@ test "'.' and '..' in fs.Dir functions" { | ... | @@ -1968,16 +2034,16 @@ test "'.' and '..' in fs.Dir functions" { |
| 1968 | try ctx.dir.makeDir(subdir_path); | 2034 | try ctx.dir.makeDir(subdir_path); |
| 1969 | try ctx.dir.access(subdir_path, .{}); | 2035 | try ctx.dir.access(subdir_path, .{}); |
| 1970 | var created_subdir = try ctx.dir.openDir(subdir_path, .{}); | 2036 | var created_subdir = try ctx.dir.openDir(subdir_path, .{}); |
| 1971 | created_subdir.close(); | 2037 | created_subdir.close(io); |
| 1972 | 2038 | ||
| 1973 | const created_file = try ctx.dir.createFile(file_path, .{}); | 2039 | const created_file = try ctx.dir.createFile(file_path, .{}); |
| 1974 | created_file.close(); | 2040 | created_file.close(io); |
| 1975 | try ctx.dir.access(file_path, .{}); | 2041 | try ctx.dir.access(file_path, .{}); |
| 1976 | 2042 | ||
| 1977 | try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{}); | 2043 | try ctx.dir.copyFile(file_path, ctx.dir, copy_path, .{}); |
| 1978 | try ctx.dir.rename(copy_path, rename_path); | 2044 | try ctx.dir.rename(copy_path, rename_path); |
| 1979 | const renamed_file = try ctx.dir.openFile(rename_path, .{}); | 2045 | const renamed_file = try ctx.dir.openFile(rename_path, .{}); |
| 1980 | renamed_file.close(); | 2046 | renamed_file.close(io); |
| 1981 | try ctx.dir.deleteFile(rename_path); | 2047 | try ctx.dir.deleteFile(rename_path); |
| 1982 | 2048 | ||
| 1983 | try ctx.dir.writeFile(.{ .sub_path = update_path, .data = "something" }); | 2049 | try ctx.dir.writeFile(.{ .sub_path = update_path, .data = "something" }); |
| ... | @@ -1994,6 +2060,8 @@ test "'.' and '..' in absolute functions" { | ... | @@ -1994,6 +2060,8 @@ test "'.' and '..' in absolute functions" { |
| 1994 | if (native_os == .wasi) return error.SkipZigTest; | 2060 | if (native_os == .wasi) return error.SkipZigTest; |
| 1995 | if (native_os == .openbsd) return error.SkipZigTest; | 2061 | if (native_os == .openbsd) return error.SkipZigTest; |
| 1996 | 2062 | ||
| 2063 | const io = testing.io; | ||
| 2064 | |||
| 1997 | var tmp = tmpDir(.{}); | 2065 | var tmp = tmpDir(.{}); |
| 1998 | defer tmp.cleanup(); | 2066 | defer tmp.cleanup(); |
| 1999 | 2067 | ||
| ... | @@ -2007,11 +2075,11 @@ test "'.' and '..' in absolute functions" { | ... | @@ -2007,11 +2075,11 @@ test "'.' and '..' in absolute functions" { |
| 2007 | try fs.makeDirAbsolute(subdir_path); | 2075 | try fs.makeDirAbsolute(subdir_path); |
| 2008 | try fs.accessAbsolute(subdir_path, .{}); | 2076 | try fs.accessAbsolute(subdir_path, .{}); |
| 2009 | var created_subdir = try fs.openDirAbsolute(subdir_path, .{}); | 2077 | var created_subdir = try fs.openDirAbsolute(subdir_path, .{}); |
| 2010 | created_subdir.close(); | 2078 | created_subdir.close(io); |
| 2011 | 2079 | ||
| 2012 | const created_file_path = try fs.path.join(allocator, &.{ subdir_path, "../file" }); | 2080 | const created_file_path = try fs.path.join(allocator, &.{ subdir_path, "../file" }); |
| 2013 | const created_file = try fs.createFileAbsolute(created_file_path, .{}); | 2081 | const created_file = try fs.createFileAbsolute(created_file_path, .{}); |
| 2014 | created_file.close(); | 2082 | created_file.close(io); |
| 2015 | try fs.accessAbsolute(created_file_path, .{}); | 2083 | try fs.accessAbsolute(created_file_path, .{}); |
| 2016 | 2084 | ||
| 2017 | const copied_file_path = try fs.path.join(allocator, &.{ subdir_path, "../copy" }); | 2085 | const copied_file_path = try fs.path.join(allocator, &.{ subdir_path, "../copy" }); |
| ... | @@ -2019,7 +2087,7 @@ test "'.' and '..' in absolute functions" { | ... | @@ -2019,7 +2087,7 @@ test "'.' and '..' in absolute functions" { |
| 2019 | const renamed_file_path = try fs.path.join(allocator, &.{ subdir_path, "../rename" }); | 2087 | const renamed_file_path = try fs.path.join(allocator, &.{ subdir_path, "../rename" }); |
| 2020 | try fs.renameAbsolute(copied_file_path, renamed_file_path); | 2088 | try fs.renameAbsolute(copied_file_path, renamed_file_path); |
| 2021 | const renamed_file = try fs.openFileAbsolute(renamed_file_path, .{}); | 2089 | const renamed_file = try fs.openFileAbsolute(renamed_file_path, .{}); |
| 2022 | renamed_file.close(); | 2090 | renamed_file.close(io); |
| 2023 | try fs.deleteFileAbsolute(renamed_file_path); | 2091 | try fs.deleteFileAbsolute(renamed_file_path); |
| 2024 | 2092 | ||
| 2025 | try fs.deleteDirAbsolute(subdir_path); | 2093 | try fs.deleteDirAbsolute(subdir_path); |
| ... | @@ -2029,11 +2097,13 @@ test "chmod" { | ... | @@ -2029,11 +2097,13 @@ test "chmod" { |
| 2029 | if (native_os == .windows or native_os == .wasi) | 2097 | if (native_os == .windows or native_os == .wasi) |
| 2030 | return error.SkipZigTest; | 2098 | return error.SkipZigTest; |
| 2031 | 2099 | ||
| 2100 | const io = testing.io; | ||
| 2101 | |||
| 2032 | var tmp = tmpDir(.{}); | 2102 | var tmp = tmpDir(.{}); |
| 2033 | defer tmp.cleanup(); | 2103 | defer tmp.cleanup(); |
| 2034 | 2104 | ||
| 2035 | const file = try tmp.dir.createFile("test_file", .{ .mode = 0o600 }); | 2105 | const file = try tmp.dir.createFile("test_file", .{ .mode = 0o600 }); |
| 2036 | defer file.close(); | 2106 | defer file.close(io); |
| 2037 | try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777); | 2107 | try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777); |
| 2038 | 2108 | ||
| 2039 | try file.chmod(0o644); | 2109 | try file.chmod(0o644); |
| ... | @@ -2041,7 +2111,7 @@ test "chmod" { | ... | @@ -2041,7 +2111,7 @@ test "chmod" { |
| 2041 | 2111 | ||
| 2042 | try tmp.dir.makeDir("test_dir"); | 2112 | try tmp.dir.makeDir("test_dir"); |
| 2043 | var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); | 2113 | var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); |
| 2044 | defer dir.close(); | 2114 | defer dir.close(io); |
| 2045 | 2115 | ||
| 2046 | try dir.chmod(0o700); | 2116 | try dir.chmod(0o700); |
| 2047 | try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat()).mode & 0o7777); | 2117 | try testing.expectEqual(@as(File.Mode, 0o700), (try dir.stat()).mode & 0o7777); |
| ... | @@ -2051,17 +2121,19 @@ test "chown" { | ... | @@ -2051,17 +2121,19 @@ test "chown" { |
| 2051 | if (native_os == .windows or native_os == .wasi) | 2121 | if (native_os == .windows or native_os == .wasi) |
| 2052 | return error.SkipZigTest; | 2122 | return error.SkipZigTest; |
| 2053 | 2123 | ||
| 2124 | const io = testing.io; | ||
| 2125 | |||
| 2054 | var tmp = tmpDir(.{}); | 2126 | var tmp = tmpDir(.{}); |
| 2055 | defer tmp.cleanup(); | 2127 | defer tmp.cleanup(); |
| 2056 | 2128 | ||
| 2057 | const file = try tmp.dir.createFile("test_file", .{}); | 2129 | const file = try tmp.dir.createFile("test_file", .{}); |
| 2058 | defer file.close(); | 2130 | defer file.close(io); |
| 2059 | try file.chown(null, null); | 2131 | try file.chown(null, null); |
| 2060 | 2132 | ||
| 2061 | try tmp.dir.makeDir("test_dir"); | 2133 | try tmp.dir.makeDir("test_dir"); |
| 2062 | 2134 | ||
| 2063 | var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); | 2135 | var dir = try tmp.dir.openDir("test_dir", .{ .iterate = true }); |
| 2064 | defer dir.close(); | 2136 | defer dir.close(io); |
| 2065 | try dir.chown(null, null); | 2137 | try dir.chown(null, null); |
| 2066 | } | 2138 | } |
| 2067 | 2139 | ||
| ... | @@ -2157,7 +2229,7 @@ test "read file non vectored" { | ... | @@ -2157,7 +2229,7 @@ test "read file non vectored" { |
| 2157 | const contents = "hello, world!\n"; | 2229 | const contents = "hello, world!\n"; |
| 2158 | 2230 | ||
| 2159 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | 2231 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2160 | defer file.close(); | 2232 | defer file.close(io); |
| 2161 | { | 2233 | { |
| 2162 | var file_writer: std.fs.File.Writer = .init(file, &.{}); | 2234 | var file_writer: std.fs.File.Writer = .init(file, &.{}); |
| 2163 | try file_writer.interface.writeAll(contents); | 2235 | try file_writer.interface.writeAll(contents); |
| ... | @@ -2189,7 +2261,7 @@ test "seek keeping partial buffer" { | ... | @@ -2189,7 +2261,7 @@ test "seek keeping partial buffer" { |
| 2189 | const contents = "0123456789"; | 2261 | const contents = "0123456789"; |
| 2190 | 2262 | ||
| 2191 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); | 2263 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2192 | defer file.close(); | 2264 | defer file.close(io); |
| 2193 | { | 2265 | { |
| 2194 | var file_writer: std.fs.File.Writer = .init(file, &.{}); | 2266 | var file_writer: std.fs.File.Writer = .init(file, &.{}); |
| 2195 | try file_writer.interface.writeAll(contents); | 2267 | try file_writer.interface.writeAll(contents); |
| ... | @@ -2231,7 +2303,7 @@ test "seekBy" { | ... | @@ -2231,7 +2303,7 @@ test "seekBy" { |
| 2231 | 2303 | ||
| 2232 | try tmp_dir.dir.writeFile(.{ .sub_path = "blah.txt", .data = "let's test seekBy" }); | 2304 | try tmp_dir.dir.writeFile(.{ .sub_path = "blah.txt", .data = "let's test seekBy" }); |
| 2233 | const f = try tmp_dir.dir.openFile("blah.txt", .{ .mode = .read_only }); | 2305 | const f = try tmp_dir.dir.openFile("blah.txt", .{ .mode = .read_only }); |
| 2234 | defer f.close(); | 2306 | defer f.close(io); |
| 2235 | var reader = f.readerStreaming(io, &.{}); | 2307 | var reader = f.readerStreaming(io, &.{}); |
| 2236 | try reader.seekBy(2); | 2308 | try reader.seekBy(2); |
| 2237 | 2309 | ||
| ... | @@ -2250,7 +2322,7 @@ test "seekTo flushes buffered data" { | ... | @@ -2250,7 +2322,7 @@ test "seekTo flushes buffered data" { |
| 2250 | const contents = "data"; | 2322 | const contents = "data"; |
| 2251 | 2323 | ||
| 2252 | const file = try tmp.dir.createFile("seek.bin", .{ .read = true }); | 2324 | const file = try tmp.dir.createFile("seek.bin", .{ .read = true }); |
| 2253 | defer file.close(); | 2325 | defer file.close(io); |
| 2254 | { | 2326 | { |
| 2255 | var buf: [16]u8 = undefined; | 2327 | var buf: [16]u8 = undefined; |
| 2256 | var file_writer = std.fs.File.writer(file, &buf); | 2328 | var file_writer = std.fs.File.writer(file, &buf); |
| ... | @@ -2277,9 +2349,9 @@ test "File.Writer sendfile with buffered contents" { | ... | @@ -2277,9 +2349,9 @@ test "File.Writer sendfile with buffered contents" { |
| 2277 | { | 2349 | { |
| 2278 | try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); | 2350 | try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); |
| 2279 | const in = try tmp_dir.dir.openFile("a", .{}); | 2351 | const in = try tmp_dir.dir.openFile("a", .{}); |
| 2280 | defer in.close(); | 2352 | defer in.close(io); |
| 2281 | const out = try tmp_dir.dir.createFile("b", .{}); | 2353 | const out = try tmp_dir.dir.createFile("b", .{}); |
| 2282 | defer out.close(); | 2354 | defer out.close(io); |
| 2283 | 2355 | ||
| 2284 | var in_buf: [2]u8 = undefined; | 2356 | var in_buf: [2]u8 = undefined; |
| 2285 | var in_r = in.reader(io, &in_buf); | 2357 | var in_r = in.reader(io, &in_buf); |
| ... | @@ -2294,7 +2366,7 @@ test "File.Writer sendfile with buffered contents" { | ... | @@ -2294,7 +2366,7 @@ test "File.Writer sendfile with buffered contents" { |
| 2294 | } | 2366 | } |
| 2295 | 2367 | ||
| 2296 | var check = try tmp_dir.dir.openFile("b", .{}); | 2368 | var check = try tmp_dir.dir.openFile("b", .{}); |
| 2297 | defer check.close(); | 2369 | defer check.close(io); |
| 2298 | var check_buf: [4]u8 = undefined; | 2370 | var check_buf: [4]u8 = undefined; |
| 2299 | var check_r = check.reader(io, &check_buf); | 2371 | var check_r = check.reader(io, &check_buf); |
| 2300 | try testing.expectEqualStrings("abcd", try check_r.interface.take(4)); | 2372 | try testing.expectEqualStrings("abcd", try check_r.interface.take(4)); |
lib/std/http/Client.zig+3-1| ... | @@ -1473,6 +1473,8 @@ pub const ConnectUnixError = Allocator.Error || std.posix.SocketError || error{N | ... | @@ -1473,6 +1473,8 @@ pub const ConnectUnixError = Allocator.Error || std.posix.SocketError || error{N |
| 1473 | /// | 1473 | /// |
| 1474 | /// This function is threadsafe. | 1474 | /// This function is threadsafe. |
| 1475 | pub fn connectUnix(client: *Client, path: []const u8) ConnectUnixError!*Connection { | 1475 | pub fn connectUnix(client: *Client, path: []const u8) ConnectUnixError!*Connection { |
| 1476 | const io = client.io; | ||
| 1477 | |||
| 1476 | if (client.connection_pool.findConnection(.{ | 1478 | if (client.connection_pool.findConnection(.{ |
| 1477 | .host = path, | 1479 | .host = path, |
| 1478 | .port = 0, | 1480 | .port = 0, |
| ... | @@ -1485,7 +1487,7 @@ pub fn connectUnix(client: *Client, path: []const u8) ConnectUnixError!*Connecti | ... | @@ -1485,7 +1487,7 @@ pub fn connectUnix(client: *Client, path: []const u8) ConnectUnixError!*Connecti |
| 1485 | conn.* = .{ .data = undefined }; | 1487 | conn.* = .{ .data = undefined }; |
| 1486 | 1488 | ||
| 1487 | const stream = try Io.net.connectUnixSocket(path); | 1489 | const stream = try Io.net.connectUnixSocket(path); |
| 1488 | errdefer stream.close(); | 1490 | errdefer stream.close(io); |
| 1489 | 1491 | ||
| 1490 | conn.data = .{ | 1492 | conn.data = .{ |
| 1491 | .stream = stream, | 1493 | .stream = stream, |
lib/std/os/linux/IoUring.zig+63-22| ... | @@ -1,13 +1,16 @@ | ... | @@ -1,13 +1,16 @@ |
| 1 | const IoUring = @This(); | 1 | const IoUring = @This(); |
| 2 | const std = @import("std"); | 2 | |
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const is_linux = builtin.os.tag == .linux; | ||
| 5 | |||
| 6 | const std = @import("std"); | ||
| 7 | const Io = std.Io; | ||
| 4 | const assert = std.debug.assert; | 8 | const assert = std.debug.assert; |
| 5 | const mem = std.mem; | 9 | const mem = std.mem; |
| 6 | const net = std.Io.net; | 10 | const net = std.Io.net; |
| 7 | const posix = std.posix; | 11 | const posix = std.posix; |
| 8 | const linux = std.os.linux; | 12 | const linux = std.os.linux; |
| 9 | const testing = std.testing; | 13 | const testing = std.testing; |
| 10 | const is_linux = builtin.os.tag == .linux; | ||
| 11 | const page_size_min = std.heap.page_size_min; | 14 | const page_size_min = std.heap.page_size_min; |
| 12 | 15 | ||
| 13 | fd: linux.fd_t = -1, | 16 | fd: linux.fd_t = -1, |
| ... | @@ -1975,6 +1978,8 @@ test "readv" { | ... | @@ -1975,6 +1978,8 @@ test "readv" { |
| 1975 | test "writev/fsync/readv" { | 1978 | test "writev/fsync/readv" { |
| 1976 | if (!is_linux) return error.SkipZigTest; | 1979 | if (!is_linux) return error.SkipZigTest; |
| 1977 | 1980 | ||
| 1981 | const io = testing.io; | ||
| 1982 | |||
| 1978 | var ring = IoUring.init(4, 0) catch |err| switch (err) { | 1983 | var ring = IoUring.init(4, 0) catch |err| switch (err) { |
| 1979 | error.SystemOutdated => return error.SkipZigTest, | 1984 | error.SystemOutdated => return error.SkipZigTest, |
| 1980 | error.PermissionDenied => return error.SkipZigTest, | 1985 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -1987,7 +1992,7 @@ test "writev/fsync/readv" { | ... | @@ -1987,7 +1992,7 @@ test "writev/fsync/readv" { |
| 1987 | 1992 | ||
| 1988 | const path = "test_io_uring_writev_fsync_readv"; | 1993 | const path = "test_io_uring_writev_fsync_readv"; |
| 1989 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); | 1994 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 1990 | defer file.close(); | 1995 | defer file.close(io); |
| 1991 | const fd = file.handle; | 1996 | const fd = file.handle; |
| 1992 | 1997 | ||
| 1993 | const buffer_write = [_]u8{42} ** 128; | 1998 | const buffer_write = [_]u8{42} ** 128; |
| ... | @@ -2045,6 +2050,8 @@ test "writev/fsync/readv" { | ... | @@ -2045,6 +2050,8 @@ test "writev/fsync/readv" { |
| 2045 | test "write/read" { | 2050 | test "write/read" { |
| 2046 | if (!is_linux) return error.SkipZigTest; | 2051 | if (!is_linux) return error.SkipZigTest; |
| 2047 | 2052 | ||
| 2053 | const io = testing.io; | ||
| 2054 | |||
| 2048 | var ring = IoUring.init(2, 0) catch |err| switch (err) { | 2055 | var ring = IoUring.init(2, 0) catch |err| switch (err) { |
| 2049 | error.SystemOutdated => return error.SkipZigTest, | 2056 | error.SystemOutdated => return error.SkipZigTest, |
| 2050 | error.PermissionDenied => return error.SkipZigTest, | 2057 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2056,7 +2063,7 @@ test "write/read" { | ... | @@ -2056,7 +2063,7 @@ test "write/read" { |
| 2056 | defer tmp.cleanup(); | 2063 | defer tmp.cleanup(); |
| 2057 | const path = "test_io_uring_write_read"; | 2064 | const path = "test_io_uring_write_read"; |
| 2058 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); | 2065 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 2059 | defer file.close(); | 2066 | defer file.close(io); |
| 2060 | const fd = file.handle; | 2067 | const fd = file.handle; |
| 2061 | 2068 | ||
| 2062 | const buffer_write = [_]u8{97} ** 20; | 2069 | const buffer_write = [_]u8{97} ** 20; |
| ... | @@ -2092,6 +2099,8 @@ test "write/read" { | ... | @@ -2092,6 +2099,8 @@ test "write/read" { |
| 2092 | test "splice/read" { | 2099 | test "splice/read" { |
| 2093 | if (!is_linux) return error.SkipZigTest; | 2100 | if (!is_linux) return error.SkipZigTest; |
| 2094 | 2101 | ||
| 2102 | const io = testing.io; | ||
| 2103 | |||
| 2095 | var ring = IoUring.init(4, 0) catch |err| switch (err) { | 2104 | var ring = IoUring.init(4, 0) catch |err| switch (err) { |
| 2096 | error.SystemOutdated => return error.SkipZigTest, | 2105 | error.SystemOutdated => return error.SkipZigTest, |
| 2097 | error.PermissionDenied => return error.SkipZigTest, | 2106 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2102,12 +2111,12 @@ test "splice/read" { | ... | @@ -2102,12 +2111,12 @@ test "splice/read" { |
| 2102 | var tmp = std.testing.tmpDir(.{}); | 2111 | var tmp = std.testing.tmpDir(.{}); |
| 2103 | const path_src = "test_io_uring_splice_src"; | 2112 | const path_src = "test_io_uring_splice_src"; |
| 2104 | const file_src = try tmp.dir.createFile(path_src, .{ .read = true, .truncate = true }); | 2113 | const file_src = try tmp.dir.createFile(path_src, .{ .read = true, .truncate = true }); |
| 2105 | defer file_src.close(); | 2114 | defer file_src.close(io); |
| 2106 | const fd_src = file_src.handle; | 2115 | const fd_src = file_src.handle; |
| 2107 | 2116 | ||
| 2108 | const path_dst = "test_io_uring_splice_dst"; | 2117 | const path_dst = "test_io_uring_splice_dst"; |
| 2109 | const file_dst = try tmp.dir.createFile(path_dst, .{ .read = true, .truncate = true }); | 2118 | const file_dst = try tmp.dir.createFile(path_dst, .{ .read = true, .truncate = true }); |
| 2110 | defer file_dst.close(); | 2119 | defer file_dst.close(io); |
| 2111 | const fd_dst = file_dst.handle; | 2120 | const fd_dst = file_dst.handle; |
| 2112 | 2121 | ||
| 2113 | const buffer_write = [_]u8{97} ** 20; | 2122 | const buffer_write = [_]u8{97} ** 20; |
| ... | @@ -2163,6 +2172,8 @@ test "splice/read" { | ... | @@ -2163,6 +2172,8 @@ test "splice/read" { |
| 2163 | test "write_fixed/read_fixed" { | 2172 | test "write_fixed/read_fixed" { |
| 2164 | if (!is_linux) return error.SkipZigTest; | 2173 | if (!is_linux) return error.SkipZigTest; |
| 2165 | 2174 | ||
| 2175 | const io = testing.io; | ||
| 2176 | |||
| 2166 | var ring = IoUring.init(2, 0) catch |err| switch (err) { | 2177 | var ring = IoUring.init(2, 0) catch |err| switch (err) { |
| 2167 | error.SystemOutdated => return error.SkipZigTest, | 2178 | error.SystemOutdated => return error.SkipZigTest, |
| 2168 | error.PermissionDenied => return error.SkipZigTest, | 2179 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2175,7 +2186,7 @@ test "write_fixed/read_fixed" { | ... | @@ -2175,7 +2186,7 @@ test "write_fixed/read_fixed" { |
| 2175 | 2186 | ||
| 2176 | const path = "test_io_uring_write_read_fixed"; | 2187 | const path = "test_io_uring_write_read_fixed"; |
| 2177 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); | 2188 | const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); |
| 2178 | defer file.close(); | 2189 | defer file.close(io); |
| 2179 | const fd = file.handle; | 2190 | const fd = file.handle; |
| 2180 | 2191 | ||
| 2181 | var raw_buffers: [2][11]u8 = undefined; | 2192 | var raw_buffers: [2][11]u8 = undefined; |
| ... | @@ -2282,6 +2293,8 @@ test "openat" { | ... | @@ -2282,6 +2293,8 @@ test "openat" { |
| 2282 | test "close" { | 2293 | test "close" { |
| 2283 | if (!is_linux) return error.SkipZigTest; | 2294 | if (!is_linux) return error.SkipZigTest; |
| 2284 | 2295 | ||
| 2296 | const io = testing.io; | ||
| 2297 | |||
| 2285 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 2298 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 2286 | error.SystemOutdated => return error.SkipZigTest, | 2299 | error.SystemOutdated => return error.SkipZigTest, |
| 2287 | error.PermissionDenied => return error.SkipZigTest, | 2300 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2294,7 +2307,7 @@ test "close" { | ... | @@ -2294,7 +2307,7 @@ test "close" { |
| 2294 | 2307 | ||
| 2295 | const path = "test_io_uring_close"; | 2308 | const path = "test_io_uring_close"; |
| 2296 | const file = try tmp.dir.createFile(path, .{}); | 2309 | const file = try tmp.dir.createFile(path, .{}); |
| 2297 | errdefer file.close(); | 2310 | errdefer file.close(io); |
| 2298 | 2311 | ||
| 2299 | const sqe_close = try ring.close(0x44444444, file.handle); | 2312 | const sqe_close = try ring.close(0x44444444, file.handle); |
| 2300 | try testing.expectEqual(linux.IORING_OP.CLOSE, sqe_close.opcode); | 2313 | try testing.expectEqual(linux.IORING_OP.CLOSE, sqe_close.opcode); |
| ... | @@ -2313,6 +2326,8 @@ test "close" { | ... | @@ -2313,6 +2326,8 @@ test "close" { |
| 2313 | test "accept/connect/send/recv" { | 2326 | test "accept/connect/send/recv" { |
| 2314 | if (!is_linux) return error.SkipZigTest; | 2327 | if (!is_linux) return error.SkipZigTest; |
| 2315 | 2328 | ||
| 2329 | const io = testing.io; | ||
| 2330 | |||
| 2316 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 2331 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 2317 | error.SystemOutdated => return error.SkipZigTest, | 2332 | error.SystemOutdated => return error.SkipZigTest, |
| 2318 | error.PermissionDenied => return error.SkipZigTest, | 2333 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2321,7 +2336,7 @@ test "accept/connect/send/recv" { | ... | @@ -2321,7 +2336,7 @@ test "accept/connect/send/recv" { |
| 2321 | defer ring.deinit(); | 2336 | defer ring.deinit(); |
| 2322 | 2337 | ||
| 2323 | const socket_test_harness = try createSocketTestHarness(&ring); | 2338 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 2324 | defer socket_test_harness.close(); | 2339 | defer socket_test_harness.close(io); |
| 2325 | 2340 | ||
| 2326 | const buffer_send = [_]u8{ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; | 2341 | const buffer_send = [_]u8{ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; |
| 2327 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; | 2342 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; |
| ... | @@ -2573,6 +2588,8 @@ test "timeout_remove" { | ... | @@ -2573,6 +2588,8 @@ test "timeout_remove" { |
| 2573 | test "accept/connect/recv/link_timeout" { | 2588 | test "accept/connect/recv/link_timeout" { |
| 2574 | if (!is_linux) return error.SkipZigTest; | 2589 | if (!is_linux) return error.SkipZigTest; |
| 2575 | 2590 | ||
| 2591 | const io = testing.io; | ||
| 2592 | |||
| 2576 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 2593 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 2577 | error.SystemOutdated => return error.SkipZigTest, | 2594 | error.SystemOutdated => return error.SkipZigTest, |
| 2578 | error.PermissionDenied => return error.SkipZigTest, | 2595 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2581,7 +2598,7 @@ test "accept/connect/recv/link_timeout" { | ... | @@ -2581,7 +2598,7 @@ test "accept/connect/recv/link_timeout" { |
| 2581 | defer ring.deinit(); | 2598 | defer ring.deinit(); |
| 2582 | 2599 | ||
| 2583 | const socket_test_harness = try createSocketTestHarness(&ring); | 2600 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 2584 | defer socket_test_harness.close(); | 2601 | defer socket_test_harness.close(io); |
| 2585 | 2602 | ||
| 2586 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; | 2603 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; |
| 2587 | 2604 | ||
| ... | @@ -2622,6 +2639,8 @@ test "accept/connect/recv/link_timeout" { | ... | @@ -2622,6 +2639,8 @@ test "accept/connect/recv/link_timeout" { |
| 2622 | test "fallocate" { | 2639 | test "fallocate" { |
| 2623 | if (!is_linux) return error.SkipZigTest; | 2640 | if (!is_linux) return error.SkipZigTest; |
| 2624 | 2641 | ||
| 2642 | const io = testing.io; | ||
| 2643 | |||
| 2625 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 2644 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 2626 | error.SystemOutdated => return error.SkipZigTest, | 2645 | error.SystemOutdated => return error.SkipZigTest, |
| 2627 | error.PermissionDenied => return error.SkipZigTest, | 2646 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2634,7 +2653,7 @@ test "fallocate" { | ... | @@ -2634,7 +2653,7 @@ test "fallocate" { |
| 2634 | 2653 | ||
| 2635 | const path = "test_io_uring_fallocate"; | 2654 | const path = "test_io_uring_fallocate"; |
| 2636 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); | 2655 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2637 | defer file.close(); | 2656 | defer file.close(io); |
| 2638 | 2657 | ||
| 2639 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); | 2658 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); |
| 2640 | 2659 | ||
| ... | @@ -2668,6 +2687,8 @@ test "fallocate" { | ... | @@ -2668,6 +2687,8 @@ test "fallocate" { |
| 2668 | test "statx" { | 2687 | test "statx" { |
| 2669 | if (!is_linux) return error.SkipZigTest; | 2688 | if (!is_linux) return error.SkipZigTest; |
| 2670 | 2689 | ||
| 2690 | const io = testing.io; | ||
| 2691 | |||
| 2671 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 2692 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 2672 | error.SystemOutdated => return error.SkipZigTest, | 2693 | error.SystemOutdated => return error.SkipZigTest, |
| 2673 | error.PermissionDenied => return error.SkipZigTest, | 2694 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2679,7 +2700,7 @@ test "statx" { | ... | @@ -2679,7 +2700,7 @@ test "statx" { |
| 2679 | defer tmp.cleanup(); | 2700 | defer tmp.cleanup(); |
| 2680 | const path = "test_io_uring_statx"; | 2701 | const path = "test_io_uring_statx"; |
| 2681 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); | 2702 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 2682 | defer file.close(); | 2703 | defer file.close(io); |
| 2683 | 2704 | ||
| 2684 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); | 2705 | try testing.expectEqual(@as(u64, 0), (try file.stat()).size); |
| 2685 | 2706 | ||
| ... | @@ -2725,6 +2746,8 @@ test "statx" { | ... | @@ -2725,6 +2746,8 @@ test "statx" { |
| 2725 | test "accept/connect/recv/cancel" { | 2746 | test "accept/connect/recv/cancel" { |
| 2726 | if (!is_linux) return error.SkipZigTest; | 2747 | if (!is_linux) return error.SkipZigTest; |
| 2727 | 2748 | ||
| 2749 | const io = testing.io; | ||
| 2750 | |||
| 2728 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 2751 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 2729 | error.SystemOutdated => return error.SkipZigTest, | 2752 | error.SystemOutdated => return error.SkipZigTest, |
| 2730 | error.PermissionDenied => return error.SkipZigTest, | 2753 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2733,7 +2756,7 @@ test "accept/connect/recv/cancel" { | ... | @@ -2733,7 +2756,7 @@ test "accept/connect/recv/cancel" { |
| 2733 | defer ring.deinit(); | 2756 | defer ring.deinit(); |
| 2734 | 2757 | ||
| 2735 | const socket_test_harness = try createSocketTestHarness(&ring); | 2758 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 2736 | defer socket_test_harness.close(); | 2759 | defer socket_test_harness.close(io); |
| 2737 | 2760 | ||
| 2738 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; | 2761 | var buffer_recv = [_]u8{ 0, 1, 0, 1, 0 }; |
| 2739 | 2762 | ||
| ... | @@ -2929,6 +2952,8 @@ test "shutdown" { | ... | @@ -2929,6 +2952,8 @@ test "shutdown" { |
| 2929 | test "renameat" { | 2952 | test "renameat" { |
| 2930 | if (!is_linux) return error.SkipZigTest; | 2953 | if (!is_linux) return error.SkipZigTest; |
| 2931 | 2954 | ||
| 2955 | const io = testing.io; | ||
| 2956 | |||
| 2932 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 2957 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 2933 | error.SystemOutdated => return error.SkipZigTest, | 2958 | error.SystemOutdated => return error.SkipZigTest, |
| 2934 | error.PermissionDenied => return error.SkipZigTest, | 2959 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2945,7 +2970,7 @@ test "renameat" { | ... | @@ -2945,7 +2970,7 @@ test "renameat" { |
| 2945 | // Write old file with data | 2970 | // Write old file with data |
| 2946 | 2971 | ||
| 2947 | const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 }); | 2972 | const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 }); |
| 2948 | defer old_file.close(); | 2973 | defer old_file.close(io); |
| 2949 | try old_file.writeAll("hello"); | 2974 | try old_file.writeAll("hello"); |
| 2950 | 2975 | ||
| 2951 | // Submit renameat | 2976 | // Submit renameat |
| ... | @@ -2987,6 +3012,8 @@ test "renameat" { | ... | @@ -2987,6 +3012,8 @@ test "renameat" { |
| 2987 | test "unlinkat" { | 3012 | test "unlinkat" { |
| 2988 | if (!is_linux) return error.SkipZigTest; | 3013 | if (!is_linux) return error.SkipZigTest; |
| 2989 | 3014 | ||
| 3015 | const io = testing.io; | ||
| 3016 | |||
| 2990 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 3017 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 2991 | error.SystemOutdated => return error.SkipZigTest, | 3018 | error.SystemOutdated => return error.SkipZigTest, |
| 2992 | error.PermissionDenied => return error.SkipZigTest, | 3019 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -3002,7 +3029,7 @@ test "unlinkat" { | ... | @@ -3002,7 +3029,7 @@ test "unlinkat" { |
| 3002 | // Write old file with data | 3029 | // Write old file with data |
| 3003 | 3030 | ||
| 3004 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); | 3031 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 3005 | defer file.close(); | 3032 | defer file.close(io); |
| 3006 | 3033 | ||
| 3007 | // Submit unlinkat | 3034 | // Submit unlinkat |
| 3008 | 3035 | ||
| ... | @@ -3083,6 +3110,8 @@ test "mkdirat" { | ... | @@ -3083,6 +3110,8 @@ test "mkdirat" { |
| 3083 | test "symlinkat" { | 3110 | test "symlinkat" { |
| 3084 | if (!is_linux) return error.SkipZigTest; | 3111 | if (!is_linux) return error.SkipZigTest; |
| 3085 | 3112 | ||
| 3113 | const io = testing.io; | ||
| 3114 | |||
| 3086 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 3115 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 3087 | error.SystemOutdated => return error.SkipZigTest, | 3116 | error.SystemOutdated => return error.SkipZigTest, |
| 3088 | error.PermissionDenied => return error.SkipZigTest, | 3117 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -3097,7 +3126,7 @@ test "symlinkat" { | ... | @@ -3097,7 +3126,7 @@ test "symlinkat" { |
| 3097 | const link_path = "test_io_uring_symlinkat_link"; | 3126 | const link_path = "test_io_uring_symlinkat_link"; |
| 3098 | 3127 | ||
| 3099 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); | 3128 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 3100 | defer file.close(); | 3129 | defer file.close(io); |
| 3101 | 3130 | ||
| 3102 | // Submit symlinkat | 3131 | // Submit symlinkat |
| 3103 | 3132 | ||
| ... | @@ -3131,6 +3160,8 @@ test "symlinkat" { | ... | @@ -3131,6 +3160,8 @@ test "symlinkat" { |
| 3131 | test "linkat" { | 3160 | test "linkat" { |
| 3132 | if (!is_linux) return error.SkipZigTest; | 3161 | if (!is_linux) return error.SkipZigTest; |
| 3133 | 3162 | ||
| 3163 | const io = testing.io; | ||
| 3164 | |||
| 3134 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 3165 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 3135 | error.SystemOutdated => return error.SkipZigTest, | 3166 | error.SystemOutdated => return error.SkipZigTest, |
| 3136 | error.PermissionDenied => return error.SkipZigTest, | 3167 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -3147,7 +3178,7 @@ test "linkat" { | ... | @@ -3147,7 +3178,7 @@ test "linkat" { |
| 3147 | // Write file with data | 3178 | // Write file with data |
| 3148 | 3179 | ||
| 3149 | const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 }); | 3180 | const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 }); |
| 3150 | defer first_file.close(); | 3181 | defer first_file.close(io); |
| 3151 | try first_file.writeAll("hello"); | 3182 | try first_file.writeAll("hello"); |
| 3152 | 3183 | ||
| 3153 | // Submit linkat | 3184 | // Submit linkat |
| ... | @@ -3407,6 +3438,8 @@ test "remove_buffers" { | ... | @@ -3407,6 +3438,8 @@ test "remove_buffers" { |
| 3407 | test "provide_buffers: accept/connect/send/recv" { | 3438 | test "provide_buffers: accept/connect/send/recv" { |
| 3408 | if (!is_linux) return error.SkipZigTest; | 3439 | if (!is_linux) return error.SkipZigTest; |
| 3409 | 3440 | ||
| 3441 | const io = testing.io; | ||
| 3442 | |||
| 3410 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 3443 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 3411 | error.SystemOutdated => return error.SkipZigTest, | 3444 | error.SystemOutdated => return error.SkipZigTest, |
| 3412 | error.PermissionDenied => return error.SkipZigTest, | 3445 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -3443,7 +3476,7 @@ test "provide_buffers: accept/connect/send/recv" { | ... | @@ -3443,7 +3476,7 @@ test "provide_buffers: accept/connect/send/recv" { |
| 3443 | } | 3476 | } |
| 3444 | 3477 | ||
| 3445 | const socket_test_harness = try createSocketTestHarness(&ring); | 3478 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 3446 | defer socket_test_harness.close(); | 3479 | defer socket_test_harness.close(io); |
| 3447 | 3480 | ||
| 3448 | // Do 4 send on the socket | 3481 | // Do 4 send on the socket |
| 3449 | 3482 | ||
| ... | @@ -3696,6 +3729,8 @@ test "accept multishot" { | ... | @@ -3696,6 +3729,8 @@ test "accept multishot" { |
| 3696 | test "accept/connect/send_zc/recv" { | 3729 | test "accept/connect/send_zc/recv" { |
| 3697 | try skipKernelLessThan(.{ .major = 6, .minor = 0, .patch = 0 }); | 3730 | try skipKernelLessThan(.{ .major = 6, .minor = 0, .patch = 0 }); |
| 3698 | 3731 | ||
| 3732 | const io = testing.io; | ||
| 3733 | |||
| 3699 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 3734 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 3700 | error.SystemOutdated => return error.SkipZigTest, | 3735 | error.SystemOutdated => return error.SkipZigTest, |
| 3701 | error.PermissionDenied => return error.SkipZigTest, | 3736 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -3704,7 +3739,7 @@ test "accept/connect/send_zc/recv" { | ... | @@ -3704,7 +3739,7 @@ test "accept/connect/send_zc/recv" { |
| 3704 | defer ring.deinit(); | 3739 | defer ring.deinit(); |
| 3705 | 3740 | ||
| 3706 | const socket_test_harness = try createSocketTestHarness(&ring); | 3741 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 3707 | defer socket_test_harness.close(); | 3742 | defer socket_test_harness.close(io); |
| 3708 | 3743 | ||
| 3709 | const buffer_send = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; | 3744 | const buffer_send = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; |
| 3710 | var buffer_recv = [_]u8{0} ** 10; | 3745 | var buffer_recv = [_]u8{0} ** 10; |
| ... | @@ -4105,6 +4140,8 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void { | ... | @@ -4105,6 +4140,8 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void { |
| 4105 | test BufferGroup { | 4140 | test BufferGroup { |
| 4106 | if (!is_linux) return error.SkipZigTest; | 4141 | if (!is_linux) return error.SkipZigTest; |
| 4107 | 4142 | ||
| 4143 | const io = testing.io; | ||
| 4144 | |||
| 4108 | // Init IoUring | 4145 | // Init IoUring |
| 4109 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 4146 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 4110 | error.SystemOutdated => return error.SkipZigTest, | 4147 | error.SystemOutdated => return error.SkipZigTest, |
| ... | @@ -4132,7 +4169,7 @@ test BufferGroup { | ... | @@ -4132,7 +4169,7 @@ test BufferGroup { |
| 4132 | 4169 | ||
| 4133 | // Create client/server fds | 4170 | // Create client/server fds |
| 4134 | const fds = try createSocketTestHarness(&ring); | 4171 | const fds = try createSocketTestHarness(&ring); |
| 4135 | defer fds.close(); | 4172 | defer fds.close(io); |
| 4136 | const data = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; | 4173 | const data = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; |
| 4137 | 4174 | ||
| 4138 | // Client sends data | 4175 | // Client sends data |
| ... | @@ -4170,6 +4207,8 @@ test BufferGroup { | ... | @@ -4170,6 +4207,8 @@ test BufferGroup { |
| 4170 | test "ring mapped buffers recv" { | 4207 | test "ring mapped buffers recv" { |
| 4171 | if (!is_linux) return error.SkipZigTest; | 4208 | if (!is_linux) return error.SkipZigTest; |
| 4172 | 4209 | ||
| 4210 | const io = testing.io; | ||
| 4211 | |||
| 4173 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 4212 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 4174 | error.SystemOutdated => return error.SkipZigTest, | 4213 | error.SystemOutdated => return error.SkipZigTest, |
| 4175 | error.PermissionDenied => return error.SkipZigTest, | 4214 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -4196,7 +4235,7 @@ test "ring mapped buffers recv" { | ... | @@ -4196,7 +4235,7 @@ test "ring mapped buffers recv" { |
| 4196 | 4235 | ||
| 4197 | // create client/server fds | 4236 | // create client/server fds |
| 4198 | const fds = try createSocketTestHarness(&ring); | 4237 | const fds = try createSocketTestHarness(&ring); |
| 4199 | defer fds.close(); | 4238 | defer fds.close(io); |
| 4200 | 4239 | ||
| 4201 | // for random user_data in sqe/cqe | 4240 | // for random user_data in sqe/cqe |
| 4202 | var Rnd = std.Random.DefaultPrng.init(std.testing.random_seed); | 4241 | var Rnd = std.Random.DefaultPrng.init(std.testing.random_seed); |
| ... | @@ -4259,6 +4298,8 @@ test "ring mapped buffers recv" { | ... | @@ -4259,6 +4298,8 @@ test "ring mapped buffers recv" { |
| 4259 | test "ring mapped buffers multishot recv" { | 4298 | test "ring mapped buffers multishot recv" { |
| 4260 | if (!is_linux) return error.SkipZigTest; | 4299 | if (!is_linux) return error.SkipZigTest; |
| 4261 | 4300 | ||
| 4301 | const io = testing.io; | ||
| 4302 | |||
| 4262 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 4303 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 4263 | error.SystemOutdated => return error.SkipZigTest, | 4304 | error.SystemOutdated => return error.SkipZigTest, |
| 4264 | error.PermissionDenied => return error.SkipZigTest, | 4305 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -4285,7 +4326,7 @@ test "ring mapped buffers multishot recv" { | ... | @@ -4285,7 +4326,7 @@ test "ring mapped buffers multishot recv" { |
| 4285 | 4326 | ||
| 4286 | // create client/server fds | 4327 | // create client/server fds |
| 4287 | const fds = try createSocketTestHarness(&ring); | 4328 | const fds = try createSocketTestHarness(&ring); |
| 4288 | defer fds.close(); | 4329 | defer fds.close(io); |
| 4289 | 4330 | ||
| 4290 | // for random user_data in sqe/cqe | 4331 | // for random user_data in sqe/cqe |
| 4291 | var Rnd = std.Random.DefaultPrng.init(std.testing.random_seed); | 4332 | var Rnd = std.Random.DefaultPrng.init(std.testing.random_seed); |
lib/std/os/linux/test.zig+9-3| ... | @@ -12,12 +12,14 @@ const fs = std.fs; | ... | @@ -12,12 +12,14 @@ const fs = std.fs; |
| 12 | test "fallocate" { | 12 | test "fallocate" { |
| 13 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30220 | 13 | if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30220 |
| 14 | 14 | ||
| 15 | const io = std.testing.io; | ||
| 16 | |||
| 15 | var tmp = std.testing.tmpDir(.{}); | 17 | var tmp = std.testing.tmpDir(.{}); |
| 16 | defer tmp.cleanup(); | 18 | defer tmp.cleanup(); |
| 17 | 19 | ||
| 18 | const path = "test_fallocate"; | 20 | const path = "test_fallocate"; |
| 19 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); | 21 | const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); |
| 20 | defer file.close(); | 22 | defer file.close(io); |
| 21 | 23 | ||
| 22 | try expect((try file.stat()).size == 0); | 24 | try expect((try file.stat()).size == 0); |
| 23 | 25 | ||
| ... | @@ -77,12 +79,14 @@ test "timer" { | ... | @@ -77,12 +79,14 @@ test "timer" { |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 79 | test "statx" { | 81 | test "statx" { |
| 82 | const io = std.testing.io; | ||
| 83 | |||
| 80 | var tmp = std.testing.tmpDir(.{}); | 84 | var tmp = std.testing.tmpDir(.{}); |
| 81 | defer tmp.cleanup(); | 85 | defer tmp.cleanup(); |
| 82 | 86 | ||
| 83 | const tmp_file_name = "just_a_temporary_file.txt"; | 87 | const tmp_file_name = "just_a_temporary_file.txt"; |
| 84 | var file = try tmp.dir.createFile(tmp_file_name, .{}); | 88 | var file = try tmp.dir.createFile(tmp_file_name, .{}); |
| 85 | defer file.close(); | 89 | defer file.close(io); |
| 86 | 90 | ||
| 87 | var buf: linux.Statx = undefined; | 91 | var buf: linux.Statx = undefined; |
| 88 | switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .BASIC_STATS, &buf))) { | 92 | switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .BASIC_STATS, &buf))) { |
| ... | @@ -111,12 +115,14 @@ test "user and group ids" { | ... | @@ -111,12 +115,14 @@ test "user and group ids" { |
| 111 | } | 115 | } |
| 112 | 116 | ||
| 113 | test "fadvise" { | 117 | test "fadvise" { |
| 118 | const io = std.testing.io; | ||
| 119 | |||
| 114 | var tmp = std.testing.tmpDir(.{}); | 120 | var tmp = std.testing.tmpDir(.{}); |
| 115 | defer tmp.cleanup(); | 121 | defer tmp.cleanup(); |
| 116 | 122 | ||
| 117 | const tmp_file_name = "temp_posix_fadvise.txt"; | 123 | const tmp_file_name = "temp_posix_fadvise.txt"; |
| 118 | var file = try tmp.dir.createFile(tmp_file_name, .{}); | 124 | var file = try tmp.dir.createFile(tmp_file_name, .{}); |
| 119 | defer file.close(); | 125 | defer file.close(io); |
| 120 | 126 | ||
| 121 | var buf: [2048]u8 = undefined; | 127 | var buf: [2048]u8 = undefined; |
| 122 | try file.writeAll(&buf); | 128 | try file.writeAll(&buf); |
lib/std/posix/test.zig+38-16| ... | @@ -148,6 +148,8 @@ test "linkat with different directories" { | ... | @@ -148,6 +148,8 @@ test "linkat with different directories" { |
| 148 | else => return error.SkipZigTest, | 148 | else => return error.SkipZigTest, |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | const io = testing.io; | ||
| 152 | |||
| 151 | var tmp = tmpDir(.{}); | 153 | var tmp = tmpDir(.{}); |
| 152 | defer tmp.cleanup(); | 154 | defer tmp.cleanup(); |
| 153 | 155 | ||
| ... | @@ -163,10 +165,10 @@ test "linkat with different directories" { | ... | @@ -163,10 +165,10 @@ test "linkat with different directories" { |
| 163 | try posix.linkat(tmp.dir.fd, target_name, subdir.fd, link_name, 0); | 165 | try posix.linkat(tmp.dir.fd, target_name, subdir.fd, link_name, 0); |
| 164 | 166 | ||
| 165 | const efd = try tmp.dir.openFile(target_name, .{}); | 167 | const efd = try tmp.dir.openFile(target_name, .{}); |
| 166 | defer efd.close(); | 168 | defer efd.close(io); |
| 167 | 169 | ||
| 168 | const nfd = try subdir.openFile(link_name, .{}); | 170 | const nfd = try subdir.openFile(link_name, .{}); |
| 169 | defer nfd.close(); | 171 | defer nfd.close(io); |
| 170 | 172 | ||
| 171 | { | 173 | { |
| 172 | const eino, _ = try getLinkInfo(efd.handle); | 174 | const eino, _ = try getLinkInfo(efd.handle); |
| ... | @@ -381,6 +383,8 @@ test "mmap" { | ... | @@ -381,6 +383,8 @@ test "mmap" { |
| 381 | if (native_os == .windows or native_os == .wasi) | 383 | if (native_os == .windows or native_os == .wasi) |
| 382 | return error.SkipZigTest; | 384 | return error.SkipZigTest; |
| 383 | 385 | ||
| 386 | const io = testing.io; | ||
| 387 | |||
| 384 | var tmp = tmpDir(.{}); | 388 | var tmp = tmpDir(.{}); |
| 385 | defer tmp.cleanup(); | 389 | defer tmp.cleanup(); |
| 386 | 390 | ||
| ... | @@ -413,7 +417,7 @@ test "mmap" { | ... | @@ -413,7 +417,7 @@ test "mmap" { |
| 413 | // Create a file used for testing mmap() calls with a file descriptor | 417 | // Create a file used for testing mmap() calls with a file descriptor |
| 414 | { | 418 | { |
| 415 | const file = try tmp.dir.createFile(test_out_file, .{}); | 419 | const file = try tmp.dir.createFile(test_out_file, .{}); |
| 416 | defer file.close(); | 420 | defer file.close(io); |
| 417 | 421 | ||
| 418 | var stream = file.writer(&.{}); | 422 | var stream = file.writer(&.{}); |
| 419 | 423 | ||
| ... | @@ -426,7 +430,7 @@ test "mmap" { | ... | @@ -426,7 +430,7 @@ test "mmap" { |
| 426 | // Map the whole file | 430 | // Map the whole file |
| 427 | { | 431 | { |
| 428 | const file = try tmp.dir.openFile(test_out_file, .{}); | 432 | const file = try tmp.dir.openFile(test_out_file, .{}); |
| 429 | defer file.close(); | 433 | defer file.close(io); |
| 430 | 434 | ||
| 431 | const data = try posix.mmap( | 435 | const data = try posix.mmap( |
| 432 | null, | 436 | null, |
| ... | @@ -451,7 +455,7 @@ test "mmap" { | ... | @@ -451,7 +455,7 @@ test "mmap" { |
| 451 | // Map the upper half of the file | 455 | // Map the upper half of the file |
| 452 | { | 456 | { |
| 453 | const file = try tmp.dir.openFile(test_out_file, .{}); | 457 | const file = try tmp.dir.openFile(test_out_file, .{}); |
| 454 | defer file.close(); | 458 | defer file.close(io); |
| 455 | 459 | ||
| 456 | const data = try posix.mmap( | 460 | const data = try posix.mmap( |
| 457 | null, | 461 | null, |
| ... | @@ -476,13 +480,15 @@ test "fcntl" { | ... | @@ -476,13 +480,15 @@ test "fcntl" { |
| 476 | if (native_os == .windows or native_os == .wasi) | 480 | if (native_os == .windows or native_os == .wasi) |
| 477 | return error.SkipZigTest; | 481 | return error.SkipZigTest; |
| 478 | 482 | ||
| 483 | const io = testing.io; | ||
| 484 | |||
| 479 | var tmp = tmpDir(.{}); | 485 | var tmp = tmpDir(.{}); |
| 480 | defer tmp.cleanup(); | 486 | defer tmp.cleanup(); |
| 481 | 487 | ||
| 482 | const test_out_file = "os_tmp_test"; | 488 | const test_out_file = "os_tmp_test"; |
| 483 | 489 | ||
| 484 | const file = try tmp.dir.createFile(test_out_file, .{}); | 490 | const file = try tmp.dir.createFile(test_out_file, .{}); |
| 485 | defer file.close(); | 491 | defer file.close(io); |
| 486 | 492 | ||
| 487 | // Note: The test assumes createFile opens the file with CLOEXEC | 493 | // Note: The test assumes createFile opens the file with CLOEXEC |
| 488 | { | 494 | { |
| ... | @@ -526,12 +532,14 @@ test "fsync" { | ... | @@ -526,12 +532,14 @@ test "fsync" { |
| 526 | else => return error.SkipZigTest, | 532 | else => return error.SkipZigTest, |
| 527 | } | 533 | } |
| 528 | 534 | ||
| 535 | const io = testing.io; | ||
| 536 | |||
| 529 | var tmp = tmpDir(.{}); | 537 | var tmp = tmpDir(.{}); |
| 530 | defer tmp.cleanup(); | 538 | defer tmp.cleanup(); |
| 531 | 539 | ||
| 532 | const test_out_file = "os_tmp_test"; | 540 | const test_out_file = "os_tmp_test"; |
| 533 | const file = try tmp.dir.createFile(test_out_file, .{}); | 541 | const file = try tmp.dir.createFile(test_out_file, .{}); |
| 534 | defer file.close(); | 542 | defer file.close(io); |
| 535 | 543 | ||
| 536 | try posix.fsync(file.handle); | 544 | try posix.fsync(file.handle); |
| 537 | try posix.fdatasync(file.handle); | 545 | try posix.fdatasync(file.handle); |
| ... | @@ -646,22 +654,24 @@ test "dup & dup2" { | ... | @@ -646,22 +654,24 @@ test "dup & dup2" { |
| 646 | else => return error.SkipZigTest, | 654 | else => return error.SkipZigTest, |
| 647 | } | 655 | } |
| 648 | 656 | ||
| 657 | const io = testing.io; | ||
| 658 | |||
| 649 | var tmp = tmpDir(.{}); | 659 | var tmp = tmpDir(.{}); |
| 650 | defer tmp.cleanup(); | 660 | defer tmp.cleanup(); |
| 651 | 661 | ||
| 652 | { | 662 | { |
| 653 | var file = try tmp.dir.createFile("os_dup_test", .{}); | 663 | var file = try tmp.dir.createFile("os_dup_test", .{}); |
| 654 | defer file.close(); | 664 | defer file.close(io); |
| 655 | 665 | ||
| 656 | var duped = std.fs.File{ .handle = try posix.dup(file.handle) }; | 666 | var duped = std.fs.File{ .handle = try posix.dup(file.handle) }; |
| 657 | defer duped.close(); | 667 | defer duped.close(io); |
| 658 | try duped.writeAll("dup"); | 668 | try duped.writeAll("dup"); |
| 659 | 669 | ||
| 660 | // Tests aren't run in parallel so using the next fd shouldn't be an issue. | 670 | // Tests aren't run in parallel so using the next fd shouldn't be an issue. |
| 661 | const new_fd = duped.handle + 1; | 671 | const new_fd = duped.handle + 1; |
| 662 | try posix.dup2(file.handle, new_fd); | 672 | try posix.dup2(file.handle, new_fd); |
| 663 | var dup2ed = std.fs.File{ .handle = new_fd }; | 673 | var dup2ed = std.fs.File{ .handle = new_fd }; |
| 664 | defer dup2ed.close(); | 674 | defer dup2ed.close(io); |
| 665 | try dup2ed.writeAll("dup2"); | 675 | try dup2ed.writeAll("dup2"); |
| 666 | } | 676 | } |
| 667 | 677 | ||
| ... | @@ -687,11 +697,13 @@ test "getppid" { | ... | @@ -687,11 +697,13 @@ test "getppid" { |
| 687 | test "writev longer than IOV_MAX" { | 697 | test "writev longer than IOV_MAX" { |
| 688 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; | 698 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; |
| 689 | 699 | ||
| 700 | const io = testing.io; | ||
| 701 | |||
| 690 | var tmp = tmpDir(.{}); | 702 | var tmp = tmpDir(.{}); |
| 691 | defer tmp.cleanup(); | 703 | defer tmp.cleanup(); |
| 692 | 704 | ||
| 693 | var file = try tmp.dir.createFile("pwritev", .{}); | 705 | var file = try tmp.dir.createFile("pwritev", .{}); |
| 694 | defer file.close(); | 706 | defer file.close(io); |
| 695 | 707 | ||
| 696 | const iovecs = [_]posix.iovec_const{.{ .base = "a", .len = 1 }} ** (posix.IOV_MAX + 1); | 708 | const iovecs = [_]posix.iovec_const{.{ .base = "a", .len = 1 }} ** (posix.IOV_MAX + 1); |
| 697 | const amt = try file.writev(&iovecs); | 709 | const amt = try file.writev(&iovecs); |
| ... | @@ -709,12 +721,14 @@ test "POSIX file locking with fcntl" { | ... | @@ -709,12 +721,14 @@ test "POSIX file locking with fcntl" { |
| 709 | return error.SkipZigTest; | 721 | return error.SkipZigTest; |
| 710 | } | 722 | } |
| 711 | 723 | ||
| 724 | const io = testing.io; | ||
| 725 | |||
| 712 | var tmp = tmpDir(.{}); | 726 | var tmp = tmpDir(.{}); |
| 713 | defer tmp.cleanup(); | 727 | defer tmp.cleanup(); |
| 714 | 728 | ||
| 715 | // Create a temporary lock file | 729 | // Create a temporary lock file |
| 716 | var file = try tmp.dir.createFile("lock", .{ .read = true }); | 730 | var file = try tmp.dir.createFile("lock", .{ .read = true }); |
| 717 | defer file.close(); | 731 | defer file.close(io); |
| 718 | try file.setEndPos(2); | 732 | try file.setEndPos(2); |
| 719 | const fd = file.handle; | 733 | const fd = file.handle; |
| 720 | 734 | ||
| ... | @@ -905,21 +919,25 @@ test "timerfd" { | ... | @@ -905,21 +919,25 @@ test "timerfd" { |
| 905 | } | 919 | } |
| 906 | 920 | ||
| 907 | test "isatty" { | 921 | test "isatty" { |
| 922 | const io = testing.io; | ||
| 923 | |||
| 908 | var tmp = tmpDir(.{}); | 924 | var tmp = tmpDir(.{}); |
| 909 | defer tmp.cleanup(); | 925 | defer tmp.cleanup(); |
| 910 | 926 | ||
| 911 | var file = try tmp.dir.createFile("foo", .{}); | 927 | var file = try tmp.dir.createFile("foo", .{}); |
| 912 | defer file.close(); | 928 | defer file.close(io); |
| 913 | 929 | ||
| 914 | try expectEqual(posix.isatty(file.handle), false); | 930 | try expectEqual(posix.isatty(file.handle), false); |
| 915 | } | 931 | } |
| 916 | 932 | ||
| 917 | test "pread with empty buffer" { | 933 | test "pread with empty buffer" { |
| 934 | const io = testing.io; | ||
| 935 | |||
| 918 | var tmp = tmpDir(.{}); | 936 | var tmp = tmpDir(.{}); |
| 919 | defer tmp.cleanup(); | 937 | defer tmp.cleanup(); |
| 920 | 938 | ||
| 921 | var file = try tmp.dir.createFile("pread_empty", .{ .read = true }); | 939 | var file = try tmp.dir.createFile("pread_empty", .{ .read = true }); |
| 922 | defer file.close(); | 940 | defer file.close(io); |
| 923 | 941 | ||
| 924 | const bytes = try a.alloc(u8, 0); | 942 | const bytes = try a.alloc(u8, 0); |
| 925 | defer a.free(bytes); | 943 | defer a.free(bytes); |
| ... | @@ -929,11 +947,13 @@ test "pread with empty buffer" { | ... | @@ -929,11 +947,13 @@ test "pread with empty buffer" { |
| 929 | } | 947 | } |
| 930 | 948 | ||
| 931 | test "write with empty buffer" { | 949 | test "write with empty buffer" { |
| 950 | const io = testing.io; | ||
| 951 | |||
| 932 | var tmp = tmpDir(.{}); | 952 | var tmp = tmpDir(.{}); |
| 933 | defer tmp.cleanup(); | 953 | defer tmp.cleanup(); |
| 934 | 954 | ||
| 935 | var file = try tmp.dir.createFile("write_empty", .{}); | 955 | var file = try tmp.dir.createFile("write_empty", .{}); |
| 936 | defer file.close(); | 956 | defer file.close(io); |
| 937 | 957 | ||
| 938 | const bytes = try a.alloc(u8, 0); | 958 | const bytes = try a.alloc(u8, 0); |
| 939 | defer a.free(bytes); | 959 | defer a.free(bytes); |
| ... | @@ -943,11 +963,13 @@ test "write with empty buffer" { | ... | @@ -943,11 +963,13 @@ test "write with empty buffer" { |
| 943 | } | 963 | } |
| 944 | 964 | ||
| 945 | test "pwrite with empty buffer" { | 965 | test "pwrite with empty buffer" { |
| 966 | const io = testing.io; | ||
| 967 | |||
| 946 | var tmp = tmpDir(.{}); | 968 | var tmp = tmpDir(.{}); |
| 947 | defer tmp.cleanup(); | 969 | defer tmp.cleanup(); |
| 948 | 970 | ||
| 949 | var file = try tmp.dir.createFile("pwrite_empty", .{}); | 971 | var file = try tmp.dir.createFile("pwrite_empty", .{}); |
| 950 | defer file.close(); | 972 | defer file.close(io); |
| 951 | 973 | ||
| 952 | const bytes = try a.alloc(u8, 0); | 974 | const bytes = try a.alloc(u8, 0); |
| 953 | defer a.free(bytes); | 975 | defer a.free(bytes); |
lib/std/process.zig+7-5| ... | @@ -1,12 +1,14 @@ | ... | @@ -1,12 +1,14 @@ |
| 1 | const std = @import("std.zig"); | ||
| 2 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const native_os = builtin.os.tag; | ||
| 3 | |||
| 4 | const std = @import("std.zig"); | ||
| 5 | const Io = std.Io; | ||
| 3 | const fs = std.fs; | 6 | const fs = std.fs; |
| 4 | const mem = std.mem; | 7 | const mem = std.mem; |
| 5 | const math = std.math; | 8 | const math = std.math; |
| 6 | const Allocator = mem.Allocator; | 9 | const Allocator = std.mem.Allocator; |
| 7 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 8 | const testing = std.testing; | 11 | const testing = std.testing; |
| 9 | const native_os = builtin.os.tag; | ||
| 10 | const posix = std.posix; | 12 | const posix = std.posix; |
| 11 | const windows = std.os.windows; | 13 | const windows = std.os.windows; |
| 12 | const unicode = std.unicode; | 14 | const unicode = std.unicode; |
| ... | @@ -1571,9 +1573,9 @@ pub fn getUserInfo(name: []const u8) !UserInfo { | ... | @@ -1571,9 +1573,9 @@ pub fn getUserInfo(name: []const u8) !UserInfo { |
| 1571 | 1573 | ||
| 1572 | /// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else | 1574 | /// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else |
| 1573 | /// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`. | 1575 | /// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`. |
| 1574 | pub fn posixGetUserInfo(name: []const u8) !UserInfo { | 1576 | pub fn posixGetUserInfo(io: Io, name: []const u8) !UserInfo { |
| 1575 | const file = try std.fs.openFileAbsolute("/etc/passwd", .{}); | 1577 | const file = try std.fs.openFileAbsolute("/etc/passwd", .{}); |
| 1576 | defer file.close(); | 1578 | defer file.close(io); |
| 1577 | var buffer: [4096]u8 = undefined; | 1579 | var buffer: [4096]u8 = undefined; |
| 1578 | var file_reader = file.reader(&buffer); | 1580 | var file_reader = file.reader(&buffer); |
| 1579 | return posixGetUserInfoPasswdStream(name, &file_reader.interface) catch |err| switch (err) { | 1581 | return posixGetUserInfoPasswdStream(name, &file_reader.interface) catch |err| switch (err) { |
lib/std/process/Child.zig+22-21| ... | @@ -4,6 +4,7 @@ const builtin = @import("builtin"); | ... | @@ -4,6 +4,7 @@ const builtin = @import("builtin"); |
| 4 | const native_os = builtin.os.tag; | 4 | const native_os = builtin.os.tag; |
| 5 | 5 | ||
| 6 | const std = @import("../std.zig"); | 6 | const std = @import("../std.zig"); |
| 7 | const Io = std.Io; | ||
| 7 | const unicode = std.unicode; | 8 | const unicode = std.unicode; |
| 8 | const fs = std.fs; | 9 | const fs = std.fs; |
| 9 | const process = std.process; | 10 | const process = std.process; |
| ... | @@ -277,17 +278,17 @@ pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term { | ... | @@ -277,17 +278,17 @@ pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term { |
| 277 | } | 278 | } |
| 278 | 279 | ||
| 279 | /// Forcibly terminates child process and then cleans up all resources. | 280 | /// Forcibly terminates child process and then cleans up all resources. |
| 280 | pub fn kill(self: *ChildProcess) !Term { | 281 | pub fn kill(self: *ChildProcess, io: Io) !Term { |
| 281 | if (native_os == .windows) { | 282 | if (native_os == .windows) { |
| 282 | return self.killWindows(1); | 283 | return self.killWindows(io, 1); |
| 283 | } else { | 284 | } else { |
| 284 | return self.killPosix(); | 285 | return self.killPosix(io); |
| 285 | } | 286 | } |
| 286 | } | 287 | } |
| 287 | 288 | ||
| 288 | pub fn killWindows(self: *ChildProcess, exit_code: windows.UINT) !Term { | 289 | pub fn killWindows(self: *ChildProcess, io: Io, exit_code: windows.UINT) !Term { |
| 289 | if (self.term) |term| { | 290 | if (self.term) |term| { |
| 290 | self.cleanupStreams(); | 291 | self.cleanupStreams(io); |
| 291 | return term; | 292 | return term; |
| 292 | } | 293 | } |
| 293 | 294 | ||
| ... | @@ -303,20 +304,20 @@ pub fn killWindows(self: *ChildProcess, exit_code: windows.UINT) !Term { | ... | @@ -303,20 +304,20 @@ pub fn killWindows(self: *ChildProcess, exit_code: windows.UINT) !Term { |
| 303 | }, | 304 | }, |
| 304 | else => return err, | 305 | else => return err, |
| 305 | }; | 306 | }; |
| 306 | try self.waitUnwrappedWindows(); | 307 | try self.waitUnwrappedWindows(io); |
| 307 | return self.term.?; | 308 | return self.term.?; |
| 308 | } | 309 | } |
| 309 | 310 | ||
| 310 | pub fn killPosix(self: *ChildProcess) !Term { | 311 | pub fn killPosix(self: *ChildProcess, io: Io) !Term { |
| 311 | if (self.term) |term| { | 312 | if (self.term) |term| { |
| 312 | self.cleanupStreams(); | 313 | self.cleanupStreams(io); |
| 313 | return term; | 314 | return term; |
| 314 | } | 315 | } |
| 315 | posix.kill(self.id, posix.SIG.TERM) catch |err| switch (err) { | 316 | posix.kill(self.id, posix.SIG.TERM) catch |err| switch (err) { |
| 316 | error.ProcessNotFound => return error.AlreadyTerminated, | 317 | error.ProcessNotFound => return error.AlreadyTerminated, |
| 317 | else => return err, | 318 | else => return err, |
| 318 | }; | 319 | }; |
| 319 | self.waitUnwrappedPosix(); | 320 | self.waitUnwrappedPosix(io); |
| 320 | return self.term.?; | 321 | return self.term.?; |
| 321 | } | 322 | } |
| 322 | 323 | ||
| ... | @@ -354,15 +355,15 @@ pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { | ... | @@ -354,15 +355,15 @@ pub fn waitForSpawn(self: *ChildProcess) SpawnError!void { |
| 354 | } | 355 | } |
| 355 | 356 | ||
| 356 | /// Blocks until child process terminates and then cleans up all resources. | 357 | /// Blocks until child process terminates and then cleans up all resources. |
| 357 | pub fn wait(self: *ChildProcess) WaitError!Term { | 358 | pub fn wait(self: *ChildProcess, io: Io) WaitError!Term { |
| 358 | try self.waitForSpawn(); // report spawn errors | 359 | try self.waitForSpawn(); // report spawn errors |
| 359 | if (self.term) |term| { | 360 | if (self.term) |term| { |
| 360 | self.cleanupStreams(); | 361 | self.cleanupStreams(io); |
| 361 | return term; | 362 | return term; |
| 362 | } | 363 | } |
| 363 | switch (native_os) { | 364 | switch (native_os) { |
| 364 | .windows => try self.waitUnwrappedWindows(), | 365 | .windows => try self.waitUnwrappedWindows(io), |
| 365 | else => self.waitUnwrappedPosix(), | 366 | else => self.waitUnwrappedPosix(io), |
| 366 | } | 367 | } |
| 367 | self.id = undefined; | 368 | self.id = undefined; |
| 368 | return self.term.?; | 369 | return self.term.?; |
| ... | @@ -474,7 +475,7 @@ pub fn run(args: struct { | ... | @@ -474,7 +475,7 @@ pub fn run(args: struct { |
| 474 | }; | 475 | }; |
| 475 | } | 476 | } |
| 476 | 477 | ||
| 477 | fn waitUnwrappedWindows(self: *ChildProcess) WaitError!void { | 478 | fn waitUnwrappedWindows(self: *ChildProcess, io: Io) WaitError!void { |
| 478 | const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false); | 479 | const result = windows.WaitForSingleObjectEx(self.id, windows.INFINITE, false); |
| 479 | 480 | ||
| 480 | self.term = @as(SpawnError!Term, x: { | 481 | self.term = @as(SpawnError!Term, x: { |
| ... | @@ -492,11 +493,11 @@ fn waitUnwrappedWindows(self: *ChildProcess) WaitError!void { | ... | @@ -492,11 +493,11 @@ fn waitUnwrappedWindows(self: *ChildProcess) WaitError!void { |
| 492 | 493 | ||
| 493 | posix.close(self.id); | 494 | posix.close(self.id); |
| 494 | posix.close(self.thread_handle); | 495 | posix.close(self.thread_handle); |
| 495 | self.cleanupStreams(); | 496 | self.cleanupStreams(io); |
| 496 | return result; | 497 | return result; |
| 497 | } | 498 | } |
| 498 | 499 | ||
| 499 | fn waitUnwrappedPosix(self: *ChildProcess) void { | 500 | fn waitUnwrappedPosix(self: *ChildProcess, io: Io) void { |
| 500 | const res: posix.WaitPidResult = res: { | 501 | const res: posix.WaitPidResult = res: { |
| 501 | if (self.request_resource_usage_statistics) { | 502 | if (self.request_resource_usage_statistics) { |
| 502 | switch (native_os) { | 503 | switch (native_os) { |
| ... | @@ -527,7 +528,7 @@ fn waitUnwrappedPosix(self: *ChildProcess) void { | ... | @@ -527,7 +528,7 @@ fn waitUnwrappedPosix(self: *ChildProcess) void { |
| 527 | break :res posix.waitpid(self.id, 0); | 528 | break :res posix.waitpid(self.id, 0); |
| 528 | }; | 529 | }; |
| 529 | const status = res.status; | 530 | const status = res.status; |
| 530 | self.cleanupStreams(); | 531 | self.cleanupStreams(io); |
| 531 | self.handleWaitResult(status); | 532 | self.handleWaitResult(status); |
| 532 | } | 533 | } |
| 533 | 534 | ||
| ... | @@ -535,17 +536,17 @@ fn handleWaitResult(self: *ChildProcess, status: u32) void { | ... | @@ -535,17 +536,17 @@ fn handleWaitResult(self: *ChildProcess, status: u32) void { |
| 535 | self.term = statusToTerm(status); | 536 | self.term = statusToTerm(status); |
| 536 | } | 537 | } |
| 537 | 538 | ||
| 538 | fn cleanupStreams(self: *ChildProcess) void { | 539 | fn cleanupStreams(self: *ChildProcess, io: Io) void { |
| 539 | if (self.stdin) |*stdin| { | 540 | if (self.stdin) |*stdin| { |
| 540 | stdin.close(); | 541 | stdin.close(io); |
| 541 | self.stdin = null; | 542 | self.stdin = null; |
| 542 | } | 543 | } |
| 543 | if (self.stdout) |*stdout| { | 544 | if (self.stdout) |*stdout| { |
| 544 | stdout.close(); | 545 | stdout.close(io); |
| 545 | self.stdout = null; | 546 | self.stdout = null; |
| 546 | } | 547 | } |
| 547 | if (self.stderr) |*stderr| { | 548 | if (self.stderr) |*stderr| { |
| 548 | stderr.close(); | 549 | stderr.close(io); |
| 549 | self.stderr = null; | 550 | self.stderr = null; |
| 550 | } | 551 | } |
| 551 | } | 552 | } |
lib/std/tar.zig+40-31| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | //! pax reference: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13 | 16 | //! pax reference: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13 |
| 17 | 17 | ||
| 18 | const std = @import("std"); | 18 | const std = @import("std"); |
| 19 | const Io = std.Io; | ||
| 19 | const assert = std.debug.assert; | 20 | const assert = std.debug.assert; |
| 20 | const testing = std.testing; | 21 | const testing = std.testing; |
| 21 | 22 | ||
| ... | @@ -302,7 +303,7 @@ pub const FileKind = enum { | ... | @@ -302,7 +303,7 @@ pub const FileKind = enum { |
| 302 | 303 | ||
| 303 | /// Iterator over entries in the tar file represented by reader. | 304 | /// Iterator over entries in the tar file represented by reader. |
| 304 | pub const Iterator = struct { | 305 | pub const Iterator = struct { |
| 305 | reader: *std.Io.Reader, | 306 | reader: *Io.Reader, |
| 306 | diagnostics: ?*Diagnostics = null, | 307 | diagnostics: ?*Diagnostics = null, |
| 307 | 308 | ||
| 308 | // buffers for heeader and file attributes | 309 | // buffers for heeader and file attributes |
| ... | @@ -328,7 +329,7 @@ pub const Iterator = struct { | ... | @@ -328,7 +329,7 @@ pub const Iterator = struct { |
| 328 | 329 | ||
| 329 | /// Iterates over files in tar archive. | 330 | /// Iterates over files in tar archive. |
| 330 | /// `next` returns each file in tar archive. | 331 | /// `next` returns each file in tar archive. |
| 331 | pub fn init(reader: *std.Io.Reader, options: Options) Iterator { | 332 | pub fn init(reader: *Io.Reader, options: Options) Iterator { |
| 332 | return .{ | 333 | return .{ |
| 333 | .reader = reader, | 334 | .reader = reader, |
| 334 | .diagnostics = options.diagnostics, | 335 | .diagnostics = options.diagnostics, |
| ... | @@ -473,7 +474,7 @@ pub const Iterator = struct { | ... | @@ -473,7 +474,7 @@ pub const Iterator = struct { |
| 473 | return null; | 474 | return null; |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | pub fn streamRemaining(it: *Iterator, file: File, w: *std.Io.Writer) std.Io.Reader.StreamError!void { | 477 | pub fn streamRemaining(it: *Iterator, file: File, w: *Io.Writer) Io.Reader.StreamError!void { |
| 477 | try it.reader.streamExact64(w, file.size); | 478 | try it.reader.streamExact64(w, file.size); |
| 478 | it.unread_file_bytes = 0; | 479 | it.unread_file_bytes = 0; |
| 479 | } | 480 | } |
| ... | @@ -499,14 +500,14 @@ const pax_max_size_attr_len = 64; | ... | @@ -499,14 +500,14 @@ const pax_max_size_attr_len = 64; |
| 499 | 500 | ||
| 500 | pub const PaxIterator = struct { | 501 | pub const PaxIterator = struct { |
| 501 | size: usize, // cumulative size of all pax attributes | 502 | size: usize, // cumulative size of all pax attributes |
| 502 | reader: *std.Io.Reader, | 503 | reader: *Io.Reader, |
| 503 | 504 | ||
| 504 | const Self = @This(); | 505 | const Self = @This(); |
| 505 | 506 | ||
| 506 | const Attribute = struct { | 507 | const Attribute = struct { |
| 507 | kind: PaxAttributeKind, | 508 | kind: PaxAttributeKind, |
| 508 | len: usize, // length of the attribute value | 509 | len: usize, // length of the attribute value |
| 509 | reader: *std.Io.Reader, // reader positioned at value start | 510 | reader: *Io.Reader, // reader positioned at value start |
| 510 | 511 | ||
| 511 | // Copies pax attribute value into destination buffer. | 512 | // Copies pax attribute value into destination buffer. |
| 512 | // Must be called with destination buffer of size at least Attribute.len. | 513 | // Must be called with destination buffer of size at least Attribute.len. |
| ... | @@ -573,13 +574,13 @@ pub const PaxIterator = struct { | ... | @@ -573,13 +574,13 @@ pub const PaxIterator = struct { |
| 573 | } | 574 | } |
| 574 | 575 | ||
| 575 | // Checks that each record ends with new line. | 576 | // Checks that each record ends with new line. |
| 576 | fn validateAttributeEnding(reader: *std.Io.Reader) !void { | 577 | fn validateAttributeEnding(reader: *Io.Reader) !void { |
| 577 | if (try reader.takeByte() != '\n') return error.PaxInvalidAttributeEnd; | 578 | if (try reader.takeByte() != '\n') return error.PaxInvalidAttributeEnd; |
| 578 | } | 579 | } |
| 579 | }; | 580 | }; |
| 580 | 581 | ||
| 581 | /// Saves tar file content to the file systems. | 582 | /// Saves tar file content to the file systems. |
| 582 | pub fn pipeToFileSystem(dir: std.fs.Dir, reader: *std.Io.Reader, options: PipeOptions) !void { | 583 | pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOptions) !void { |
| 583 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; | 584 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| 584 | var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined; | 585 | var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| 585 | var file_contents_buffer: [1024]u8 = undefined; | 586 | var file_contents_buffer: [1024]u8 = undefined; |
| ... | @@ -610,7 +611,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: *std.Io.Reader, options: PipeOp | ... | @@ -610,7 +611,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: *std.Io.Reader, options: PipeOp |
| 610 | }, | 611 | }, |
| 611 | .file => { | 612 | .file => { |
| 612 | if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| { | 613 | if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| { |
| 613 | defer fs_file.close(); | 614 | defer fs_file.close(io); |
| 614 | var file_writer = fs_file.writer(&file_contents_buffer); | 615 | var file_writer = fs_file.writer(&file_contents_buffer); |
| 615 | try it.streamRemaining(file, &file_writer.interface); | 616 | try it.streamRemaining(file, &file_writer.interface); |
| 616 | try file_writer.interface.flush(); | 617 | try file_writer.interface.flush(); |
| ... | @@ -637,7 +638,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: *std.Io.Reader, options: PipeOp | ... | @@ -637,7 +638,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: *std.Io.Reader, options: PipeOp |
| 637 | } | 638 | } |
| 638 | } | 639 | } |
| 639 | 640 | ||
| 640 | fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8, mode: std.fs.File.Mode) !std.fs.File { | 641 | fn createDirAndFile(dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { |
| 641 | const fs_file = dir.createFile(file_name, .{ .exclusive = true, .mode = mode }) catch |err| { | 642 | const fs_file = dir.createFile(file_name, .{ .exclusive = true, .mode = mode }) catch |err| { |
| 642 | if (err == error.FileNotFound) { | 643 | if (err == error.FileNotFound) { |
| 643 | if (std.fs.path.dirname(file_name)) |dir_name| { | 644 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| ... | @@ -651,7 +652,7 @@ fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8, mode: std.fs.File.Mo | ... | @@ -651,7 +652,7 @@ fn createDirAndFile(dir: std.fs.Dir, file_name: []const u8, mode: std.fs.File.Mo |
| 651 | } | 652 | } |
| 652 | 653 | ||
| 653 | // Creates a symbolic link at path `file_name` which points to `link_name`. | 654 | // Creates a symbolic link at path `file_name` which points to `link_name`. |
| 654 | fn createDirAndSymlink(dir: std.fs.Dir, link_name: []const u8, file_name: []const u8) !void { | 655 | fn createDirAndSymlink(dir: Io.Dir, link_name: []const u8, file_name: []const u8) !void { |
| 655 | dir.symLink(link_name, file_name, .{}) catch |err| { | 656 | dir.symLink(link_name, file_name, .{}) catch |err| { |
| 656 | if (err == error.FileNotFound) { | 657 | if (err == error.FileNotFound) { |
| 657 | if (std.fs.path.dirname(file_name)) |dir_name| { | 658 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| ... | @@ -783,7 +784,7 @@ test PaxIterator { | ... | @@ -783,7 +784,7 @@ test PaxIterator { |
| 783 | var buffer: [1024]u8 = undefined; | 784 | var buffer: [1024]u8 = undefined; |
| 784 | 785 | ||
| 785 | outer: for (cases) |case| { | 786 | outer: for (cases) |case| { |
| 786 | var reader: std.Io.Reader = .fixed(case.data); | 787 | var reader: Io.Reader = .fixed(case.data); |
| 787 | var it: PaxIterator = .{ | 788 | var it: PaxIterator = .{ |
| 788 | .size = case.data.len, | 789 | .size = case.data.len, |
| 789 | .reader = &reader, | 790 | .reader = &reader, |
| ... | @@ -874,13 +875,15 @@ test "header parse mode" { | ... | @@ -874,13 +875,15 @@ test "header parse mode" { |
| 874 | } | 875 | } |
| 875 | 876 | ||
| 876 | test "create file and symlink" { | 877 | test "create file and symlink" { |
| 878 | const io = testing.io; | ||
| 879 | |||
| 877 | var root = testing.tmpDir(.{}); | 880 | var root = testing.tmpDir(.{}); |
| 878 | defer root.cleanup(); | 881 | defer root.cleanup(); |
| 879 | 882 | ||
| 880 | var file = try createDirAndFile(root.dir, "file1", default_mode); | 883 | var file = try createDirAndFile(root.dir, "file1", default_mode); |
| 881 | file.close(); | 884 | file.close(io); |
| 882 | file = try createDirAndFile(root.dir, "a/b/c/file2", default_mode); | 885 | file = try createDirAndFile(root.dir, "a/b/c/file2", default_mode); |
| 883 | file.close(); | 886 | file.close(io); |
| 884 | 887 | ||
| 885 | createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { | 888 | createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { |
| 886 | // On Windows when developer mode is not enabled | 889 | // On Windows when developer mode is not enabled |
| ... | @@ -892,7 +895,7 @@ test "create file and symlink" { | ... | @@ -892,7 +895,7 @@ test "create file and symlink" { |
| 892 | // Danglink symlnik, file created later | 895 | // Danglink symlnik, file created later |
| 893 | try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); | 896 | try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); |
| 894 | file = try createDirAndFile(root.dir, "g/h/i/file4", default_mode); | 897 | file = try createDirAndFile(root.dir, "g/h/i/file4", default_mode); |
| 895 | file.close(); | 898 | file.close(io); |
| 896 | } | 899 | } |
| 897 | 900 | ||
| 898 | test Iterator { | 901 | test Iterator { |
| ... | @@ -916,7 +919,7 @@ test Iterator { | ... | @@ -916,7 +919,7 @@ test Iterator { |
| 916 | // example/empty/ | 919 | // example/empty/ |
| 917 | 920 | ||
| 918 | const data = @embedFile("tar/testdata/example.tar"); | 921 | const data = @embedFile("tar/testdata/example.tar"); |
| 919 | var reader: std.Io.Reader = .fixed(data); | 922 | var reader: Io.Reader = .fixed(data); |
| 920 | 923 | ||
| 921 | // User provided buffers to the iterator | 924 | // User provided buffers to the iterator |
| 922 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; | 925 | var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; |
| ... | @@ -942,7 +945,7 @@ test Iterator { | ... | @@ -942,7 +945,7 @@ test Iterator { |
| 942 | .file => { | 945 | .file => { |
| 943 | try testing.expectEqualStrings("example/a/file", file.name); | 946 | try testing.expectEqualStrings("example/a/file", file.name); |
| 944 | var buf: [16]u8 = undefined; | 947 | var buf: [16]u8 = undefined; |
| 945 | var w: std.Io.Writer = .fixed(&buf); | 948 | var w: Io.Writer = .fixed(&buf); |
| 946 | try it.streamRemaining(file, &w); | 949 | try it.streamRemaining(file, &w); |
| 947 | try testing.expectEqualStrings("content\n", w.buffered()); | 950 | try testing.expectEqualStrings("content\n", w.buffered()); |
| 948 | }, | 951 | }, |
| ... | @@ -955,6 +958,7 @@ test Iterator { | ... | @@ -955,6 +958,7 @@ test Iterator { |
| 955 | } | 958 | } |
| 956 | 959 | ||
| 957 | test pipeToFileSystem { | 960 | test pipeToFileSystem { |
| 961 | const io = testing.io; | ||
| 958 | // Example tar file is created from this tree structure: | 962 | // Example tar file is created from this tree structure: |
| 959 | // $ tree example | 963 | // $ tree example |
| 960 | // example | 964 | // example |
| ... | @@ -975,14 +979,14 @@ test pipeToFileSystem { | ... | @@ -975,14 +979,14 @@ test pipeToFileSystem { |
| 975 | // example/empty/ | 979 | // example/empty/ |
| 976 | 980 | ||
| 977 | const data = @embedFile("tar/testdata/example.tar"); | 981 | const data = @embedFile("tar/testdata/example.tar"); |
| 978 | var reader: std.Io.Reader = .fixed(data); | 982 | var reader: Io.Reader = .fixed(data); |
| 979 | 983 | ||
| 980 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); | 984 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 981 | defer tmp.cleanup(); | 985 | defer tmp.cleanup(); |
| 982 | const dir = tmp.dir; | 986 | const dir = tmp.dir; |
| 983 | 987 | ||
| 984 | // Save tar from reader to the file system `dir` | 988 | // Save tar from reader to the file system `dir` |
| 985 | pipeToFileSystem(dir, &reader, .{ | 989 | pipeToFileSystem(io, dir, &reader, .{ |
| 986 | .mode_mode = .ignore, | 990 | .mode_mode = .ignore, |
| 987 | .strip_components = 1, | 991 | .strip_components = 1, |
| 988 | .exclude_empty_directories = true, | 992 | .exclude_empty_directories = true, |
| ... | @@ -1005,8 +1009,9 @@ test pipeToFileSystem { | ... | @@ -1005,8 +1009,9 @@ test pipeToFileSystem { |
| 1005 | } | 1009 | } |
| 1006 | 1010 | ||
| 1007 | test "pipeToFileSystem root_dir" { | 1011 | test "pipeToFileSystem root_dir" { |
| 1012 | const io = testing.io; | ||
| 1008 | const data = @embedFile("tar/testdata/example.tar"); | 1013 | const data = @embedFile("tar/testdata/example.tar"); |
| 1009 | var reader: std.Io.Reader = .fixed(data); | 1014 | var reader: Io.Reader = .fixed(data); |
| 1010 | 1015 | ||
| 1011 | // with strip_components = 1 | 1016 | // with strip_components = 1 |
| 1012 | { | 1017 | { |
| ... | @@ -1015,7 +1020,7 @@ test "pipeToFileSystem root_dir" { | ... | @@ -1015,7 +1020,7 @@ test "pipeToFileSystem root_dir" { |
| 1015 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1020 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1016 | defer diagnostics.deinit(); | 1021 | defer diagnostics.deinit(); |
| 1017 | 1022 | ||
| 1018 | pipeToFileSystem(tmp.dir, &reader, .{ | 1023 | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1019 | .strip_components = 1, | 1024 | .strip_components = 1, |
| 1020 | .diagnostics = &diagnostics, | 1025 | .diagnostics = &diagnostics, |
| 1021 | }) catch |err| { | 1026 | }) catch |err| { |
| ... | @@ -1037,7 +1042,7 @@ test "pipeToFileSystem root_dir" { | ... | @@ -1037,7 +1042,7 @@ test "pipeToFileSystem root_dir" { |
| 1037 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1042 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1038 | defer diagnostics.deinit(); | 1043 | defer diagnostics.deinit(); |
| 1039 | 1044 | ||
| 1040 | pipeToFileSystem(tmp.dir, &reader, .{ | 1045 | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1041 | .strip_components = 0, | 1046 | .strip_components = 0, |
| 1042 | .diagnostics = &diagnostics, | 1047 | .diagnostics = &diagnostics, |
| 1043 | }) catch |err| { | 1048 | }) catch |err| { |
| ... | @@ -1053,43 +1058,46 @@ test "pipeToFileSystem root_dir" { | ... | @@ -1053,43 +1058,46 @@ test "pipeToFileSystem root_dir" { |
| 1053 | } | 1058 | } |
| 1054 | 1059 | ||
| 1055 | test "findRoot with single file archive" { | 1060 | test "findRoot with single file archive" { |
| 1061 | const io = testing.io; | ||
| 1056 | const data = @embedFile("tar/testdata/22752.tar"); | 1062 | const data = @embedFile("tar/testdata/22752.tar"); |
| 1057 | var reader: std.Io.Reader = .fixed(data); | 1063 | var reader: Io.Reader = .fixed(data); |
| 1058 | 1064 | ||
| 1059 | var tmp = testing.tmpDir(.{}); | 1065 | var tmp = testing.tmpDir(.{}); |
| 1060 | defer tmp.cleanup(); | 1066 | defer tmp.cleanup(); |
| 1061 | 1067 | ||
| 1062 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1068 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1063 | defer diagnostics.deinit(); | 1069 | defer diagnostics.deinit(); |
| 1064 | try pipeToFileSystem(tmp.dir, &reader, .{ .diagnostics = &diagnostics }); | 1070 | try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1065 | 1071 | ||
| 1066 | try testing.expectEqualStrings("", diagnostics.root_dir); | 1072 | try testing.expectEqualStrings("", diagnostics.root_dir); |
| 1067 | } | 1073 | } |
| 1068 | 1074 | ||
| 1069 | test "findRoot without explicit root dir" { | 1075 | test "findRoot without explicit root dir" { |
| 1076 | const io = testing.io; | ||
| 1070 | const data = @embedFile("tar/testdata/19820.tar"); | 1077 | const data = @embedFile("tar/testdata/19820.tar"); |
| 1071 | var reader: std.Io.Reader = .fixed(data); | 1078 | var reader: Io.Reader = .fixed(data); |
| 1072 | 1079 | ||
| 1073 | var tmp = testing.tmpDir(.{}); | 1080 | var tmp = testing.tmpDir(.{}); |
| 1074 | defer tmp.cleanup(); | 1081 | defer tmp.cleanup(); |
| 1075 | 1082 | ||
| 1076 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1083 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1077 | defer diagnostics.deinit(); | 1084 | defer diagnostics.deinit(); |
| 1078 | try pipeToFileSystem(tmp.dir, &reader, .{ .diagnostics = &diagnostics }); | 1085 | try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics }); |
| 1079 | 1086 | ||
| 1080 | try testing.expectEqualStrings("root", diagnostics.root_dir); | 1087 | try testing.expectEqualStrings("root", diagnostics.root_dir); |
| 1081 | } | 1088 | } |
| 1082 | 1089 | ||
| 1083 | test "pipeToFileSystem strip_components" { | 1090 | test "pipeToFileSystem strip_components" { |
| 1091 | const io = testing.io; | ||
| 1084 | const data = @embedFile("tar/testdata/example.tar"); | 1092 | const data = @embedFile("tar/testdata/example.tar"); |
| 1085 | var reader: std.Io.Reader = .fixed(data); | 1093 | var reader: Io.Reader = .fixed(data); |
| 1086 | 1094 | ||
| 1087 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); | 1095 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1088 | defer tmp.cleanup(); | 1096 | defer tmp.cleanup(); |
| 1089 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1097 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1090 | defer diagnostics.deinit(); | 1098 | defer diagnostics.deinit(); |
| 1091 | 1099 | ||
| 1092 | pipeToFileSystem(tmp.dir, &reader, .{ | 1100 | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1093 | .strip_components = 3, | 1101 | .strip_components = 3, |
| 1094 | .diagnostics = &diagnostics, | 1102 | .diagnostics = &diagnostics, |
| 1095 | }) catch |err| { | 1103 | }) catch |err| { |
| ... | @@ -1110,10 +1118,10 @@ fn normalizePath(bytes: []u8) []u8 { | ... | @@ -1110,10 +1118,10 @@ fn normalizePath(bytes: []u8) []u8 { |
| 1110 | return bytes; | 1118 | return bytes; |
| 1111 | } | 1119 | } |
| 1112 | 1120 | ||
| 1113 | const default_mode = std.fs.File.default_mode; | 1121 | const default_mode = Io.File.default_mode; |
| 1114 | 1122 | ||
| 1115 | // File system mode based on tar header mode and mode_mode options. | 1123 | // File system mode based on tar header mode and mode_mode options. |
| 1116 | fn fileMode(mode: u32, options: PipeOptions) std.fs.File.Mode { | 1124 | fn fileMode(mode: u32, options: PipeOptions) Io.File.Mode { |
| 1117 | if (!std.fs.has_executable_bit or options.mode_mode == .ignore) | 1125 | if (!std.fs.has_executable_bit or options.mode_mode == .ignore) |
| 1118 | return default_mode; | 1126 | return default_mode; |
| 1119 | 1127 | ||
| ... | @@ -1139,16 +1147,17 @@ test fileMode { | ... | @@ -1139,16 +1147,17 @@ test fileMode { |
| 1139 | test "executable bit" { | 1147 | test "executable bit" { |
| 1140 | if (!std.fs.has_executable_bit) return error.SkipZigTest; | 1148 | if (!std.fs.has_executable_bit) return error.SkipZigTest; |
| 1141 | 1149 | ||
| 1150 | const io = testing.io; | ||
| 1142 | const S = std.posix.S; | 1151 | const S = std.posix.S; |
| 1143 | const data = @embedFile("tar/testdata/example.tar"); | 1152 | const data = @embedFile("tar/testdata/example.tar"); |
| 1144 | 1153 | ||
| 1145 | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { | 1154 | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { |
| 1146 | var reader: std.Io.Reader = .fixed(data); | 1155 | var reader: Io.Reader = .fixed(data); |
| 1147 | 1156 | ||
| 1148 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); | 1157 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1149 | //defer tmp.cleanup(); | 1158 | //defer tmp.cleanup(); |
| 1150 | 1159 | ||
| 1151 | pipeToFileSystem(tmp.dir, &reader, .{ | 1160 | pipeToFileSystem(io, tmp.dir, &reader, .{ |
| 1152 | .strip_components = 1, | 1161 | .strip_components = 1, |
| 1153 | .exclude_empty_directories = true, | 1162 | .exclude_empty_directories = true, |
| 1154 | .mode_mode = opt, | 1163 | .mode_mode = opt, |
lib/std/tar/test.zig+5-3| ... | @@ -424,6 +424,7 @@ test "insufficient buffer in Header name filed" { | ... | @@ -424,6 +424,7 @@ test "insufficient buffer in Header name filed" { |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | test "should not overwrite existing file" { | 426 | test "should not overwrite existing file" { |
| 427 | const io = testing.io; | ||
| 427 | // Starting from this folder structure: | 428 | // Starting from this folder structure: |
| 428 | // $ tree root | 429 | // $ tree root |
| 429 | // root | 430 | // root |
| ... | @@ -469,17 +470,18 @@ test "should not overwrite existing file" { | ... | @@ -469,17 +470,18 @@ test "should not overwrite existing file" { |
| 469 | defer root.cleanup(); | 470 | defer root.cleanup(); |
| 470 | try testing.expectError( | 471 | try testing.expectError( |
| 471 | error.PathAlreadyExists, | 472 | error.PathAlreadyExists, |
| 472 | tar.pipeToFileSystem(root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }), | 473 | tar.pipeToFileSystem(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }), |
| 473 | ); | 474 | ); |
| 474 | 475 | ||
| 475 | // Unpack with strip_components = 0 should pass | 476 | // Unpack with strip_components = 0 should pass |
| 476 | r = .fixed(data); | 477 | r = .fixed(data); |
| 477 | var root2 = std.testing.tmpDir(.{}); | 478 | var root2 = std.testing.tmpDir(.{}); |
| 478 | defer root2.cleanup(); | 479 | defer root2.cleanup(); |
| 479 | try tar.pipeToFileSystem(root2.dir, &r, .{ .mode_mode = .ignore, .strip_components = 0 }); | 480 | try tar.pipeToFileSystem(io, root2.dir, &r, .{ .mode_mode = .ignore, .strip_components = 0 }); |
| 480 | } | 481 | } |
| 481 | 482 | ||
| 482 | test "case sensitivity" { | 483 | test "case sensitivity" { |
| 484 | const io = testing.io; | ||
| 483 | // Mimicking issue #18089, this tar contains, same file name in two case | 485 | // Mimicking issue #18089, this tar contains, same file name in two case |
| 484 | // sensitive name version. Should fail on case insensitive file systems. | 486 | // sensitive name version. Should fail on case insensitive file systems. |
| 485 | // | 487 | // |
| ... | @@ -495,7 +497,7 @@ test "case sensitivity" { | ... | @@ -495,7 +497,7 @@ test "case sensitivity" { |
| 495 | var root = std.testing.tmpDir(.{}); | 497 | var root = std.testing.tmpDir(.{}); |
| 496 | defer root.cleanup(); | 498 | defer root.cleanup(); |
| 497 | 499 | ||
| 498 | tar.pipeToFileSystem(root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }) catch |err| { | 500 | tar.pipeToFileSystem(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }) catch |err| { |
| 499 | // on case insensitive fs we fail on overwrite existing file | 501 | // on case insensitive fs we fail on overwrite existing file |
| 500 | try testing.expectEqual(error.PathAlreadyExists, err); | 502 | try testing.expectEqual(error.PathAlreadyExists, err); |
| 501 | return; | 503 | return; |
lib/std/testing.zig+3-3| ... | @@ -613,9 +613,9 @@ pub const TmpDir = struct { | ... | @@ -613,9 +613,9 @@ pub const TmpDir = struct { |
| 613 | const sub_path_len = std.fs.base64_encoder.calcSize(random_bytes_count); | 613 | const sub_path_len = std.fs.base64_encoder.calcSize(random_bytes_count); |
| 614 | 614 | ||
| 615 | pub fn cleanup(self: *TmpDir) void { | 615 | pub fn cleanup(self: *TmpDir) void { |
| 616 | self.dir.close(); | 616 | self.dir.close(io); |
| 617 | self.parent_dir.deleteTree(&self.sub_path) catch {}; | 617 | self.parent_dir.deleteTree(&self.sub_path) catch {}; |
| 618 | self.parent_dir.close(); | 618 | self.parent_dir.close(io); |
| 619 | self.* = undefined; | 619 | self.* = undefined; |
| 620 | } | 620 | } |
| 621 | }; | 621 | }; |
| ... | @@ -629,7 +629,7 @@ pub fn tmpDir(opts: std.fs.Dir.OpenOptions) TmpDir { | ... | @@ -629,7 +629,7 @@ pub fn tmpDir(opts: std.fs.Dir.OpenOptions) TmpDir { |
| 629 | const cwd = std.fs.cwd(); | 629 | const cwd = std.fs.cwd(); |
| 630 | var cache_dir = cwd.makeOpenPath(".zig-cache", .{}) catch | 630 | var cache_dir = cwd.makeOpenPath(".zig-cache", .{}) catch |
| 631 | @panic("unable to make tmp dir for testing: unable to make and open .zig-cache dir"); | 631 | @panic("unable to make tmp dir for testing: unable to make and open .zig-cache dir"); |
| 632 | defer cache_dir.close(); | 632 | defer cache_dir.close(io); |
| 633 | const parent_dir = cache_dir.makeOpenPath("tmp", .{}) catch | 633 | const parent_dir = cache_dir.makeOpenPath("tmp", .{}) catch |
| 634 | @panic("unable to make tmp dir for testing: unable to make and open .zig-cache/tmp dir"); | 634 | @panic("unable to make tmp dir for testing: unable to make and open .zig-cache/tmp dir"); |
| 635 | const dir = parent_dir.makeOpenPath(&sub_path, opts) catch | 635 | const dir = parent_dir.makeOpenPath(&sub_path, opts) catch |
lib/std/zig/LibCInstallation.zig+40-31| ... | @@ -1,4 +1,18 @@ | ... | @@ -1,4 +1,18 @@ |
| 1 | //! See the render function implementation for documentation of the fields. | 1 | //! See the render function implementation for documentation of the fields. |
| 2 | const LibCInstallation = @This(); | ||
| 3 | |||
| 4 | const builtin = @import("builtin"); | ||
| 5 | const is_darwin = builtin.target.os.tag.isDarwin(); | ||
| 6 | const is_windows = builtin.target.os.tag == .windows; | ||
| 7 | const is_haiku = builtin.target.os.tag == .haiku; | ||
| 8 | |||
| 9 | const std = @import("std"); | ||
| 10 | const Io = std.Io; | ||
| 11 | const Target = std.Target; | ||
| 12 | const fs = std.fs; | ||
| 13 | const Allocator = std.mem.Allocator; | ||
| 14 | const Path = std.Build.Cache.Path; | ||
| 15 | const log = std.log.scoped(.libc_installation); | ||
| 2 | 16 | ||
| 3 | include_dir: ?[]const u8 = null, | 17 | include_dir: ?[]const u8 = null, |
| 4 | sys_include_dir: ?[]const u8 = null, | 18 | sys_include_dir: ?[]const u8 = null, |
| ... | @@ -157,6 +171,7 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { | ... | @@ -157,6 +171,7 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { |
| 157 | 171 | ||
| 158 | pub const FindNativeOptions = struct { | 172 | pub const FindNativeOptions = struct { |
| 159 | allocator: Allocator, | 173 | allocator: Allocator, |
| 174 | io: Io, | ||
| 160 | target: *const std.Target, | 175 | target: *const std.Target, |
| 161 | 176 | ||
| 162 | /// If enabled, will print human-friendly errors to stderr. | 177 | /// If enabled, will print human-friendly errors to stderr. |
| ... | @@ -165,29 +180,32 @@ pub const FindNativeOptions = struct { | ... | @@ -165,29 +180,32 @@ pub const FindNativeOptions = struct { |
| 165 | 180 | ||
| 166 | /// Finds the default, native libc. | 181 | /// Finds the default, native libc. |
| 167 | pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { | 182 | pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { |
| 183 | const gpa = args.allocator; | ||
| 184 | const io = args.io; | ||
| 185 | |||
| 168 | var self: LibCInstallation = .{}; | 186 | var self: LibCInstallation = .{}; |
| 169 | 187 | ||
| 170 | if (is_darwin and args.target.os.tag.isDarwin()) { | 188 | if (is_darwin and args.target.os.tag.isDarwin()) { |
| 171 | if (!std.zig.system.darwin.isSdkInstalled(args.allocator)) | 189 | if (!std.zig.system.darwin.isSdkInstalled(gpa)) |
| 172 | return error.DarwinSdkNotFound; | 190 | return error.DarwinSdkNotFound; |
| 173 | const sdk = std.zig.system.darwin.getSdk(args.allocator, args.target) orelse | 191 | const sdk = std.zig.system.darwin.getSdk(gpa, args.target) orelse |
| 174 | return error.DarwinSdkNotFound; | 192 | return error.DarwinSdkNotFound; |
| 175 | defer args.allocator.free(sdk); | 193 | defer gpa.free(sdk); |
| 176 | 194 | ||
| 177 | self.include_dir = try fs.path.join(args.allocator, &.{ | 195 | self.include_dir = try fs.path.join(gpa, &.{ |
| 178 | sdk, "usr/include", | 196 | sdk, "usr/include", |
| 179 | }); | 197 | }); |
| 180 | self.sys_include_dir = try fs.path.join(args.allocator, &.{ | 198 | self.sys_include_dir = try fs.path.join(gpa, &.{ |
| 181 | sdk, "usr/include", | 199 | sdk, "usr/include", |
| 182 | }); | 200 | }); |
| 183 | return self; | 201 | return self; |
| 184 | } else if (is_windows) { | 202 | } else if (is_windows) { |
| 185 | const sdk = std.zig.WindowsSdk.find(args.allocator, args.target.cpu.arch) catch |err| switch (err) { | 203 | const sdk = std.zig.WindowsSdk.find(gpa, io, args.target.cpu.arch) catch |err| switch (err) { |
| 186 | error.NotFound => return error.WindowsSdkNotFound, | 204 | error.NotFound => return error.WindowsSdkNotFound, |
| 187 | error.PathTooLong => return error.WindowsSdkNotFound, | 205 | error.PathTooLong => return error.WindowsSdkNotFound, |
| 188 | error.OutOfMemory => return error.OutOfMemory, | 206 | error.OutOfMemory => return error.OutOfMemory, |
| 189 | }; | 207 | }; |
| 190 | defer sdk.free(args.allocator); | 208 | defer sdk.free(gpa); |
| 191 | 209 | ||
| 192 | try self.findNativeMsvcIncludeDir(args, sdk); | 210 | try self.findNativeMsvcIncludeDir(args, sdk); |
| 193 | try self.findNativeMsvcLibDir(args, sdk); | 211 | try self.findNativeMsvcLibDir(args, sdk); |
| ... | @@ -197,16 +215,16 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { | ... | @@ -197,16 +215,16 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { |
| 197 | } else if (is_haiku) { | 215 | } else if (is_haiku) { |
| 198 | try self.findNativeIncludeDirPosix(args); | 216 | try self.findNativeIncludeDirPosix(args); |
| 199 | try self.findNativeGccDirHaiku(args); | 217 | try self.findNativeGccDirHaiku(args); |
| 200 | self.crt_dir = try args.allocator.dupeZ(u8, "/system/develop/lib"); | 218 | self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib"); |
| 201 | } else if (builtin.target.os.tag == .illumos) { | 219 | } else if (builtin.target.os.tag == .illumos) { |
| 202 | // There is only one libc, and its headers/libraries are always in the same spot. | 220 | // There is only one libc, and its headers/libraries are always in the same spot. |
| 203 | self.include_dir = try args.allocator.dupeZ(u8, "/usr/include"); | 221 | self.include_dir = try gpa.dupeZ(u8, "/usr/include"); |
| 204 | self.sys_include_dir = try args.allocator.dupeZ(u8, "/usr/include"); | 222 | self.sys_include_dir = try gpa.dupeZ(u8, "/usr/include"); |
| 205 | self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib/64"); | 223 | self.crt_dir = try gpa.dupeZ(u8, "/usr/lib/64"); |
| 206 | } else if (std.process.can_spawn) { | 224 | } else if (std.process.can_spawn) { |
| 207 | try self.findNativeIncludeDirPosix(args); | 225 | try self.findNativeIncludeDirPosix(args); |
| 208 | switch (builtin.target.os.tag) { | 226 | switch (builtin.target.os.tag) { |
| 209 | .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib"), | 227 | .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"), |
| 210 | .linux => try self.findNativeCrtDirPosix(args), | 228 | .linux => try self.findNativeCrtDirPosix(args), |
| 211 | else => {}, | 229 | else => {}, |
| 212 | } | 230 | } |
| ... | @@ -229,6 +247,7 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void { | ... | @@ -229,6 +247,7 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void { |
| 229 | 247 | ||
| 230 | fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void { | 248 | fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void { |
| 231 | const allocator = args.allocator; | 249 | const allocator = args.allocator; |
| 250 | const io = args.io; | ||
| 232 | 251 | ||
| 233 | // Detect infinite loops. | 252 | // Detect infinite loops. |
| 234 | var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { | 253 | var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { |
| ... | @@ -326,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F | ... | @@ -326,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F |
| 326 | 345 | ||
| 327 | else => return error.FileSystem, | 346 | else => return error.FileSystem, |
| 328 | }; | 347 | }; |
| 329 | defer search_dir.close(); | 348 | defer search_dir.close(io); |
| 330 | 349 | ||
| 331 | if (self.include_dir == null) { | 350 | if (self.include_dir == null) { |
| 332 | if (search_dir.access(include_dir_example_file, .{})) |_| { | 351 | if (search_dir.access(include_dir_example_file, .{})) |_| { |
| ... | @@ -361,6 +380,7 @@ fn findNativeIncludeDirWindows( | ... | @@ -361,6 +380,7 @@ fn findNativeIncludeDirWindows( |
| 361 | sdk: std.zig.WindowsSdk, | 380 | sdk: std.zig.WindowsSdk, |
| 362 | ) FindError!void { | 381 | ) FindError!void { |
| 363 | const allocator = args.allocator; | 382 | const allocator = args.allocator; |
| 383 | const io = args.io; | ||
| 364 | 384 | ||
| 365 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; | 385 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; |
| 366 | const installs = fillInstallations(&install_buf, sdk); | 386 | const installs = fillInstallations(&install_buf, sdk); |
| ... | @@ -380,7 +400,7 @@ fn findNativeIncludeDirWindows( | ... | @@ -380,7 +400,7 @@ fn findNativeIncludeDirWindows( |
| 380 | 400 | ||
| 381 | else => return error.FileSystem, | 401 | else => return error.FileSystem, |
| 382 | }; | 402 | }; |
| 383 | defer dir.close(); | 403 | defer dir.close(io); |
| 384 | 404 | ||
| 385 | dir.access("stdlib.h", .{}) catch |err| switch (err) { | 405 | dir.access("stdlib.h", .{}) catch |err| switch (err) { |
| 386 | error.FileNotFound => continue, | 406 | error.FileNotFound => continue, |
| ... | @@ -400,6 +420,7 @@ fn findNativeCrtDirWindows( | ... | @@ -400,6 +420,7 @@ fn findNativeCrtDirWindows( |
| 400 | sdk: std.zig.WindowsSdk, | 420 | sdk: std.zig.WindowsSdk, |
| 401 | ) FindError!void { | 421 | ) FindError!void { |
| 402 | const allocator = args.allocator; | 422 | const allocator = args.allocator; |
| 423 | const io = args.io; | ||
| 403 | 424 | ||
| 404 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; | 425 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; |
| 405 | const installs = fillInstallations(&install_buf, sdk); | 426 | const installs = fillInstallations(&install_buf, sdk); |
| ... | @@ -427,7 +448,7 @@ fn findNativeCrtDirWindows( | ... | @@ -427,7 +448,7 @@ fn findNativeCrtDirWindows( |
| 427 | 448 | ||
| 428 | else => return error.FileSystem, | 449 | else => return error.FileSystem, |
| 429 | }; | 450 | }; |
| 430 | defer dir.close(); | 451 | defer dir.close(io); |
| 431 | 452 | ||
| 432 | dir.access("ucrt.lib", .{}) catch |err| switch (err) { | 453 | dir.access("ucrt.lib", .{}) catch |err| switch (err) { |
| 433 | error.FileNotFound => continue, | 454 | error.FileNotFound => continue, |
| ... | @@ -467,6 +488,7 @@ fn findNativeKernel32LibDir( | ... | @@ -467,6 +488,7 @@ fn findNativeKernel32LibDir( |
| 467 | sdk: std.zig.WindowsSdk, | 488 | sdk: std.zig.WindowsSdk, |
| 468 | ) FindError!void { | 489 | ) FindError!void { |
| 469 | const allocator = args.allocator; | 490 | const allocator = args.allocator; |
| 491 | const io = args.io; | ||
| 470 | 492 | ||
| 471 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; | 493 | var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; |
| 472 | const installs = fillInstallations(&install_buf, sdk); | 494 | const installs = fillInstallations(&install_buf, sdk); |
| ... | @@ -494,7 +516,7 @@ fn findNativeKernel32LibDir( | ... | @@ -494,7 +516,7 @@ fn findNativeKernel32LibDir( |
| 494 | 516 | ||
| 495 | else => return error.FileSystem, | 517 | else => return error.FileSystem, |
| 496 | }; | 518 | }; |
| 497 | defer dir.close(); | 519 | defer dir.close(io); |
| 498 | 520 | ||
| 499 | dir.access("kernel32.lib", .{}) catch |err| switch (err) { | 521 | dir.access("kernel32.lib", .{}) catch |err| switch (err) { |
| 500 | error.FileNotFound => continue, | 522 | error.FileNotFound => continue, |
| ... | @@ -513,6 +535,7 @@ fn findNativeMsvcIncludeDir( | ... | @@ -513,6 +535,7 @@ fn findNativeMsvcIncludeDir( |
| 513 | sdk: std.zig.WindowsSdk, | 535 | sdk: std.zig.WindowsSdk, |
| 514 | ) FindError!void { | 536 | ) FindError!void { |
| 515 | const allocator = args.allocator; | 537 | const allocator = args.allocator; |
| 538 | const io = args.io; | ||
| 516 | 539 | ||
| 517 | const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound; | 540 | const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound; |
| 518 | const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound; | 541 | const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound; |
| ... | @@ -529,7 +552,7 @@ fn findNativeMsvcIncludeDir( | ... | @@ -529,7 +552,7 @@ fn findNativeMsvcIncludeDir( |
| 529 | 552 | ||
| 530 | else => return error.FileSystem, | 553 | else => return error.FileSystem, |
| 531 | }; | 554 | }; |
| 532 | defer dir.close(); | 555 | defer dir.close(io); |
| 533 | 556 | ||
| 534 | dir.access("vcruntime.h", .{}) catch |err| switch (err) { | 557 | dir.access("vcruntime.h", .{}) catch |err| switch (err) { |
| 535 | error.FileNotFound => return error.LibCStdLibHeaderNotFound, | 558 | error.FileNotFound => return error.LibCStdLibHeaderNotFound, |
| ... | @@ -1015,17 +1038,3 @@ pub fn resolveCrtPaths( | ... | @@ -1015,17 +1038,3 @@ pub fn resolveCrtPaths( |
| 1015 | }, | 1038 | }, |
| 1016 | } | 1039 | } |
| 1017 | } | 1040 | } |
| 1018 | |||
| 1019 | const LibCInstallation = @This(); | ||
| 1020 | const std = @import("std"); | ||
| 1021 | const builtin = @import("builtin"); | ||
| 1022 | const Target = std.Target; | ||
| 1023 | const fs = std.fs; | ||
| 1024 | const Allocator = std.mem.Allocator; | ||
| 1025 | const Path = std.Build.Cache.Path; | ||
| 1026 | |||
| 1027 | const is_darwin = builtin.target.os.tag.isDarwin(); | ||
| 1028 | const is_windows = builtin.target.os.tag == .windows; | ||
| 1029 | const is_haiku = builtin.target.os.tag == .haiku; | ||
| 1030 | |||
| 1031 | const log = std.log.scoped(.libc_installation); |
lib/std/zig/WindowsSdk.zig+38-29| ... | @@ -1,7 +1,10 @@ | ... | @@ -1,7 +1,10 @@ |
| 1 | const WindowsSdk = @This(); | 1 | const WindowsSdk = @This(); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | |||
| 3 | const std = @import("std"); | 4 | const std = @import("std"); |
| 5 | const Io = std.Io; | ||
| 4 | const Writer = std.Io.Writer; | 6 | const Writer = std.Io.Writer; |
| 7 | const Allocator = std.mem.Allocator; | ||
| 5 | 8 | ||
| 6 | windows10sdk: ?Installation, | 9 | windows10sdk: ?Installation, |
| 7 | windows81sdk: ?Installation, | 10 | windows81sdk: ?Installation, |
| ... | @@ -20,7 +23,7 @@ const product_version_max_length = version_major_minor_max_length + ".65535".len | ... | @@ -20,7 +23,7 @@ const product_version_max_length = version_major_minor_max_length + ".65535".len |
| 20 | /// Find path and version of Windows 10 SDK and Windows 8.1 SDK, and find path to MSVC's `lib/` directory. | 23 | /// Find path and version of Windows 10 SDK and Windows 8.1 SDK, and find path to MSVC's `lib/` directory. |
| 21 | /// Caller owns the result's fields. | 24 | /// Caller owns the result's fields. |
| 22 | /// After finishing work, call `free(allocator)`. | 25 | /// After finishing work, call `free(allocator)`. |
| 23 | pub fn find(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, NotFound, PathTooLong }!WindowsSdk { | 26 | pub fn find(allocator: Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, NotFound, PathTooLong }!WindowsSdk { |
| 24 | if (builtin.os.tag != .windows) return error.NotFound; | 27 | if (builtin.os.tag != .windows) return error.NotFound; |
| 25 | 28 | ||
| 26 | //note(dimenus): If this key doesn't exist, neither the Win 8 SDK nor the Win 10 SDK is installed | 29 | //note(dimenus): If this key doesn't exist, neither the Win 8 SDK nor the Win 10 SDK is installed |
| ... | @@ -58,7 +61,7 @@ pub fn find(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutO | ... | @@ -58,7 +61,7 @@ pub fn find(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutO |
| 58 | }; | 61 | }; |
| 59 | } | 62 | } |
| 60 | 63 | ||
| 61 | pub fn free(sdk: WindowsSdk, allocator: std.mem.Allocator) void { | 64 | pub fn free(sdk: WindowsSdk, allocator: Allocator) void { |
| 62 | if (sdk.windows10sdk) |*w10sdk| { | 65 | if (sdk.windows10sdk) |*w10sdk| { |
| 63 | w10sdk.free(allocator); | 66 | w10sdk.free(allocator); |
| 64 | } | 67 | } |
| ... | @@ -75,7 +78,7 @@ pub fn free(sdk: WindowsSdk, allocator: std.mem.Allocator) void { | ... | @@ -75,7 +78,7 @@ pub fn free(sdk: WindowsSdk, allocator: std.mem.Allocator) void { |
| 75 | /// Caller owns result. | 78 | /// Caller owns result. |
| 76 | fn iterateAndFilterByVersion( | 79 | fn iterateAndFilterByVersion( |
| 77 | iterator: *std.fs.Dir.Iterator, | 80 | iterator: *std.fs.Dir.Iterator, |
| 78 | allocator: std.mem.Allocator, | 81 | allocator: Allocator, |
| 79 | prefix: []const u8, | 82 | prefix: []const u8, |
| 80 | ) error{OutOfMemory}![][]const u8 { | 83 | ) error{OutOfMemory}![][]const u8 { |
| 81 | const Version = struct { | 84 | const Version = struct { |
| ... | @@ -174,7 +177,7 @@ const RegistryWtf8 = struct { | ... | @@ -174,7 +177,7 @@ const RegistryWtf8 = struct { |
| 174 | 177 | ||
| 175 | /// Get string from registry. | 178 | /// Get string from registry. |
| 176 | /// Caller owns result. | 179 | /// Caller owns result. |
| 177 | pub fn getString(reg: RegistryWtf8, allocator: std.mem.Allocator, subkey: []const u8, value_name: []const u8) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]u8 { | 180 | pub fn getString(reg: RegistryWtf8, allocator: Allocator, subkey: []const u8, value_name: []const u8) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]u8 { |
| 178 | const subkey_wtf16le: [:0]const u16 = subkey_wtf16le: { | 181 | const subkey_wtf16le: [:0]const u16 = subkey_wtf16le: { |
| 179 | var subkey_wtf16le_buf: [RegistryWtf16Le.key_name_max_len]u16 = undefined; | 182 | var subkey_wtf16le_buf: [RegistryWtf16Le.key_name_max_len]u16 = undefined; |
| 180 | const subkey_wtf16le_len: usize = std.unicode.wtf8ToWtf16Le(subkey_wtf16le_buf[0..], subkey) catch unreachable; | 183 | const subkey_wtf16le_len: usize = std.unicode.wtf8ToWtf16Le(subkey_wtf16le_buf[0..], subkey) catch unreachable; |
| ... | @@ -282,7 +285,7 @@ const RegistryWtf16Le = struct { | ... | @@ -282,7 +285,7 @@ const RegistryWtf16Le = struct { |
| 282 | } | 285 | } |
| 283 | 286 | ||
| 284 | /// Get string ([:0]const u16) from registry. | 287 | /// Get string ([:0]const u16) from registry. |
| 285 | fn getString(reg: RegistryWtf16Le, allocator: std.mem.Allocator, subkey_wtf16le: [:0]const u16, value_name_wtf16le: [:0]const u16) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]const u16 { | 288 | fn getString(reg: RegistryWtf16Le, allocator: Allocator, subkey_wtf16le: [:0]const u16, value_name_wtf16le: [:0]const u16) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]const u16 { |
| 286 | var actual_type: windows.ULONG = undefined; | 289 | var actual_type: windows.ULONG = undefined; |
| 287 | 290 | ||
| 288 | // Calculating length to allocate | 291 | // Calculating length to allocate |
| ... | @@ -416,7 +419,7 @@ pub const Installation = struct { | ... | @@ -416,7 +419,7 @@ pub const Installation = struct { |
| 416 | /// Caller owns the result's fields. | 419 | /// Caller owns the result's fields. |
| 417 | /// After finishing work, call `free(allocator)`. | 420 | /// After finishing work, call `free(allocator)`. |
| 418 | fn find( | 421 | fn find( |
| 419 | allocator: std.mem.Allocator, | 422 | allocator: Allocator, |
| 420 | roots_key: RegistryWtf8, | 423 | roots_key: RegistryWtf8, |
| 421 | roots_subkey: []const u8, | 424 | roots_subkey: []const u8, |
| 422 | prefix: []const u8, | 425 | prefix: []const u8, |
| ... | @@ -437,7 +440,8 @@ pub const Installation = struct { | ... | @@ -437,7 +440,8 @@ pub const Installation = struct { |
| 437 | } | 440 | } |
| 438 | 441 | ||
| 439 | fn findFromRoot( | 442 | fn findFromRoot( |
| 440 | allocator: std.mem.Allocator, | 443 | allocator: Allocator, |
| 444 | io: Io, | ||
| 441 | roots_key: RegistryWtf8, | 445 | roots_key: RegistryWtf8, |
| 442 | roots_subkey: []const u8, | 446 | roots_subkey: []const u8, |
| 443 | prefix: []const u8, | 447 | prefix: []const u8, |
| ... | @@ -478,7 +482,7 @@ pub const Installation = struct { | ... | @@ -478,7 +482,7 @@ pub const Installation = struct { |
| 478 | error.NameTooLong => return error.PathTooLong, | 482 | error.NameTooLong => return error.PathTooLong, |
| 479 | else => return error.InstallationNotFound, | 483 | else => return error.InstallationNotFound, |
| 480 | }; | 484 | }; |
| 481 | defer sdk_lib_dir.close(); | 485 | defer sdk_lib_dir.close(io); |
| 482 | 486 | ||
| 483 | var iterator = sdk_lib_dir.iterate(); | 487 | var iterator = sdk_lib_dir.iterate(); |
| 484 | const versions = try iterateAndFilterByVersion(&iterator, allocator, prefix); | 488 | const versions = try iterateAndFilterByVersion(&iterator, allocator, prefix); |
| ... | @@ -495,7 +499,7 @@ pub const Installation = struct { | ... | @@ -495,7 +499,7 @@ pub const Installation = struct { |
| 495 | } | 499 | } |
| 496 | 500 | ||
| 497 | fn findFromInstallationFolder( | 501 | fn findFromInstallationFolder( |
| 498 | allocator: std.mem.Allocator, | 502 | allocator: Allocator, |
| 499 | version_key_name: []const u8, | 503 | version_key_name: []const u8, |
| 500 | ) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation { | 504 | ) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation { |
| 501 | var key_name_buf: [RegistryWtf16Le.key_name_max_len]u8 = undefined; | 505 | var key_name_buf: [RegistryWtf16Le.key_name_max_len]u8 = undefined; |
| ... | @@ -597,14 +601,14 @@ pub const Installation = struct { | ... | @@ -597,14 +601,14 @@ pub const Installation = struct { |
| 597 | return (reg_value == 1); | 601 | return (reg_value == 1); |
| 598 | } | 602 | } |
| 599 | 603 | ||
| 600 | fn free(install: Installation, allocator: std.mem.Allocator) void { | 604 | fn free(install: Installation, allocator: Allocator) void { |
| 601 | allocator.free(install.path); | 605 | allocator.free(install.path); |
| 602 | allocator.free(install.version); | 606 | allocator.free(install.version); |
| 603 | } | 607 | } |
| 604 | }; | 608 | }; |
| 605 | 609 | ||
| 606 | const MsvcLibDir = struct { | 610 | const MsvcLibDir = struct { |
| 607 | fn findInstancesDirViaSetup(allocator: std.mem.Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { | 611 | fn findInstancesDirViaSetup(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { |
| 608 | const vs_setup_key_path = "SOFTWARE\\Microsoft\\VisualStudio\\Setup"; | 612 | const vs_setup_key_path = "SOFTWARE\\Microsoft\\VisualStudio\\Setup"; |
| 609 | const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path, .{}) catch |err| switch (err) { | 613 | const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path, .{}) catch |err| switch (err) { |
| 610 | error.KeyNotFound => return error.PathNotFound, | 614 | error.KeyNotFound => return error.PathNotFound, |
| ... | @@ -629,7 +633,7 @@ const MsvcLibDir = struct { | ... | @@ -629,7 +633,7 @@ const MsvcLibDir = struct { |
| 629 | return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; | 633 | return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; |
| 630 | } | 634 | } |
| 631 | 635 | ||
| 632 | fn findInstancesDirViaCLSID(allocator: std.mem.Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { | 636 | fn findInstancesDirViaCLSID(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { |
| 633 | const setup_configuration_clsid = "{177f0c4a-1cd3-4de7-a32c-71dbbb9fa36d}"; | 637 | const setup_configuration_clsid = "{177f0c4a-1cd3-4de7-a32c-71dbbb9fa36d}"; |
| 634 | const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid, .{}) catch |err| switch (err) { | 638 | const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid, .{}) catch |err| switch (err) { |
| 635 | error.KeyNotFound => return error.PathNotFound, | 639 | error.KeyNotFound => return error.PathNotFound, |
| ... | @@ -665,7 +669,7 @@ const MsvcLibDir = struct { | ... | @@ -665,7 +669,7 @@ const MsvcLibDir = struct { |
| 665 | return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; | 669 | return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound; |
| 666 | } | 670 | } |
| 667 | 671 | ||
| 668 | fn findInstancesDir(allocator: std.mem.Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { | 672 | fn findInstancesDir(allocator: Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir { |
| 669 | // First, try getting the packages cache path from the registry. | 673 | // First, try getting the packages cache path from the registry. |
| 670 | // This only seems to exist when the path is different from the default. | 674 | // This only seems to exist when the path is different from the default. |
| 671 | method1: { | 675 | method1: { |
| ... | @@ -748,13 +752,13 @@ const MsvcLibDir = struct { | ... | @@ -748,13 +752,13 @@ const MsvcLibDir = struct { |
| 748 | /// | 752 | /// |
| 749 | /// The logic in this function is intended to match what ISetupConfiguration does | 753 | /// The logic in this function is intended to match what ISetupConfiguration does |
| 750 | /// under-the-hood, as verified using Procmon. | 754 | /// under-the-hood, as verified using Procmon. |
| 751 | fn findViaCOM(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { | 755 | fn findViaCOM(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { |
| 752 | // Typically `%PROGRAMDATA%\Microsoft\VisualStudio\Packages\_Instances` | 756 | // Typically `%PROGRAMDATA%\Microsoft\VisualStudio\Packages\_Instances` |
| 753 | // This will contain directories with names of instance IDs like 80a758ca, | 757 | // This will contain directories with names of instance IDs like 80a758ca, |
| 754 | // which will contain `state.json` files that have the version and | 758 | // which will contain `state.json` files that have the version and |
| 755 | // installation directory. | 759 | // installation directory. |
| 756 | var instances_dir = try findInstancesDir(allocator); | 760 | var instances_dir = try findInstancesDir(allocator); |
| 757 | defer instances_dir.close(); | 761 | defer instances_dir.close(io); |
| 758 | 762 | ||
| 759 | var state_subpath_buf: [std.fs.max_name_bytes + 32]u8 = undefined; | 763 | var state_subpath_buf: [std.fs.max_name_bytes + 32]u8 = undefined; |
| 760 | var latest_version_lib_dir: std.ArrayList(u8) = .empty; | 764 | var latest_version_lib_dir: std.ArrayList(u8) = .empty; |
| ... | @@ -791,7 +795,7 @@ const MsvcLibDir = struct { | ... | @@ -791,7 +795,7 @@ const MsvcLibDir = struct { |
| 791 | const installation_path = parsed.value.object.get("installationPath") orelse continue; | 795 | const installation_path = parsed.value.object.get("installationPath") orelse continue; |
| 792 | if (installation_path != .string) continue; | 796 | if (installation_path != .string) continue; |
| 793 | 797 | ||
| 794 | const lib_dir_path = libDirFromInstallationPath(allocator, installation_path.string, arch) catch |err| switch (err) { | 798 | const lib_dir_path = libDirFromInstallationPath(allocator, io, installation_path.string, arch) catch |err| switch (err) { |
| 795 | error.OutOfMemory => |e| return e, | 799 | error.OutOfMemory => |e| return e, |
| 796 | error.PathNotFound => continue, | 800 | error.PathNotFound => continue, |
| 797 | }; | 801 | }; |
| ... | @@ -806,7 +810,12 @@ const MsvcLibDir = struct { | ... | @@ -806,7 +810,12 @@ const MsvcLibDir = struct { |
| 806 | return latest_version_lib_dir.toOwnedSlice(allocator); | 810 | return latest_version_lib_dir.toOwnedSlice(allocator); |
| 807 | } | 811 | } |
| 808 | 812 | ||
| 809 | fn libDirFromInstallationPath(allocator: std.mem.Allocator, installation_path: []const u8, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { | 813 | fn libDirFromInstallationPath( |
| 814 | allocator: Allocator, | ||
| 815 | io: Io, | ||
| 816 | installation_path: []const u8, | ||
| 817 | arch: std.Target.Cpu.Arch, | ||
| 818 | ) error{ OutOfMemory, PathNotFound }![]const u8 { | ||
| 810 | var lib_dir_buf = try std.array_list.Managed(u8).initCapacity(allocator, installation_path.len + 64); | 819 | var lib_dir_buf = try std.array_list.Managed(u8).initCapacity(allocator, installation_path.len + 64); |
| 811 | errdefer lib_dir_buf.deinit(); | 820 | errdefer lib_dir_buf.deinit(); |
| 812 | 821 | ||
| ... | @@ -837,7 +846,7 @@ const MsvcLibDir = struct { | ... | @@ -837,7 +846,7 @@ const MsvcLibDir = struct { |
| 837 | else => unreachable, | 846 | else => unreachable, |
| 838 | }); | 847 | }); |
| 839 | 848 | ||
| 840 | if (!verifyLibDir(lib_dir_buf.items)) { | 849 | if (!verifyLibDir(io, lib_dir_buf.items)) { |
| 841 | return error.PathNotFound; | 850 | return error.PathNotFound; |
| 842 | } | 851 | } |
| 843 | 852 | ||
| ... | @@ -845,7 +854,7 @@ const MsvcLibDir = struct { | ... | @@ -845,7 +854,7 @@ const MsvcLibDir = struct { |
| 845 | } | 854 | } |
| 846 | 855 | ||
| 847 | // https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2022#editing-the-registry-for-a-visual-studio-instance | 856 | // https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2022#editing-the-registry-for-a-visual-studio-instance |
| 848 | fn findViaRegistry(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { | 857 | fn findViaRegistry(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { |
| 849 | 858 | ||
| 850 | // %localappdata%\Microsoft\VisualStudio\ | 859 | // %localappdata%\Microsoft\VisualStudio\ |
| 851 | // %appdata%\Local\Microsoft\VisualStudio\ | 860 | // %appdata%\Local\Microsoft\VisualStudio\ |
| ... | @@ -859,7 +868,7 @@ const MsvcLibDir = struct { | ... | @@ -859,7 +868,7 @@ const MsvcLibDir = struct { |
| 859 | var visualstudio_folder = std.fs.openDirAbsolute(visualstudio_folder_path, .{ | 868 | var visualstudio_folder = std.fs.openDirAbsolute(visualstudio_folder_path, .{ |
| 860 | .iterate = true, | 869 | .iterate = true, |
| 861 | }) catch return error.PathNotFound; | 870 | }) catch return error.PathNotFound; |
| 862 | defer visualstudio_folder.close(); | 871 | defer visualstudio_folder.close(io); |
| 863 | 872 | ||
| 864 | var iterator = visualstudio_folder.iterate(); | 873 | var iterator = visualstudio_folder.iterate(); |
| 865 | break :vs_versions try iterateAndFilterByVersion(&iterator, allocator, ""); | 874 | break :vs_versions try iterateAndFilterByVersion(&iterator, allocator, ""); |
| ... | @@ -926,14 +935,14 @@ const MsvcLibDir = struct { | ... | @@ -926,14 +935,14 @@ const MsvcLibDir = struct { |
| 926 | }; | 935 | }; |
| 927 | errdefer allocator.free(msvc_dir); | 936 | errdefer allocator.free(msvc_dir); |
| 928 | 937 | ||
| 929 | if (!verifyLibDir(msvc_dir)) { | 938 | if (!verifyLibDir(io, msvc_dir)) { |
| 930 | return error.PathNotFound; | 939 | return error.PathNotFound; |
| 931 | } | 940 | } |
| 932 | 941 | ||
| 933 | return msvc_dir; | 942 | return msvc_dir; |
| 934 | } | 943 | } |
| 935 | 944 | ||
| 936 | fn findViaVs7Key(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { | 945 | fn findViaVs7Key(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 { |
| 937 | var base_path: std.array_list.Managed(u8) = base_path: { | 946 | var base_path: std.array_list.Managed(u8) = base_path: { |
| 938 | try_env: { | 947 | try_env: { |
| 939 | var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { | 948 | var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { |
| ... | @@ -989,7 +998,7 @@ const MsvcLibDir = struct { | ... | @@ -989,7 +998,7 @@ const MsvcLibDir = struct { |
| 989 | else => unreachable, | 998 | else => unreachable, |
| 990 | }); | 999 | }); |
| 991 | 1000 | ||
| 992 | if (!verifyLibDir(base_path.items)) { | 1001 | if (!verifyLibDir(io, base_path.items)) { |
| 993 | return error.PathNotFound; | 1002 | return error.PathNotFound; |
| 994 | } | 1003 | } |
| 995 | 1004 | ||
| ... | @@ -997,11 +1006,11 @@ const MsvcLibDir = struct { | ... | @@ -997,11 +1006,11 @@ const MsvcLibDir = struct { |
| 997 | return full_path; | 1006 | return full_path; |
| 998 | } | 1007 | } |
| 999 | 1008 | ||
| 1000 | fn verifyLibDir(lib_dir_path: []const u8) bool { | 1009 | fn verifyLibDir(io: Io, lib_dir_path: []const u8) bool { |
| 1001 | std.debug.assert(std.fs.path.isAbsolute(lib_dir_path)); // should be already handled in `findVia*` | 1010 | std.debug.assert(std.fs.path.isAbsolute(lib_dir_path)); // should be already handled in `findVia*` |
| 1002 | 1011 | ||
| 1003 | var dir = std.fs.openDirAbsolute(lib_dir_path, .{}) catch return false; | 1012 | var dir = std.fs.openDirAbsolute(lib_dir_path, .{}) catch return false; |
| 1004 | defer dir.close(); | 1013 | defer dir.close(io); |
| 1005 | 1014 | ||
| 1006 | const stat = dir.statFile("vcruntime.lib") catch return false; | 1015 | const stat = dir.statFile("vcruntime.lib") catch return false; |
| 1007 | if (stat.kind != .file) | 1016 | if (stat.kind != .file) |
| ... | @@ -1012,12 +1021,12 @@ const MsvcLibDir = struct { | ... | @@ -1012,12 +1021,12 @@ const MsvcLibDir = struct { |
| 1012 | 1021 | ||
| 1013 | /// Find path to MSVC's `lib/` directory. | 1022 | /// Find path to MSVC's `lib/` directory. |
| 1014 | /// Caller owns the result. | 1023 | /// Caller owns the result. |
| 1015 | pub fn find(allocator: std.mem.Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, MsvcLibDirNotFound }![]const u8 { | 1024 | pub fn find(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, MsvcLibDirNotFound }![]const u8 { |
| 1016 | const full_path = MsvcLibDir.findViaCOM(allocator, arch) catch |err1| switch (err1) { | 1025 | const full_path = MsvcLibDir.findViaCOM(allocator, io, arch) catch |err1| switch (err1) { |
| 1017 | error.OutOfMemory => return error.OutOfMemory, | 1026 | error.OutOfMemory => return error.OutOfMemory, |
| 1018 | error.PathNotFound => MsvcLibDir.findViaRegistry(allocator, arch) catch |err2| switch (err2) { | 1027 | error.PathNotFound => MsvcLibDir.findViaRegistry(allocator, io, arch) catch |err2| switch (err2) { |
| 1019 | error.OutOfMemory => return error.OutOfMemory, | 1028 | error.OutOfMemory => return error.OutOfMemory, |
| 1020 | error.PathNotFound => MsvcLibDir.findViaVs7Key(allocator, arch) catch |err3| switch (err3) { | 1029 | error.PathNotFound => MsvcLibDir.findViaVs7Key(allocator, io, arch) catch |err3| switch (err3) { |
| 1021 | error.OutOfMemory => return error.OutOfMemory, | 1030 | error.OutOfMemory => return error.OutOfMemory, |
| 1022 | error.PathNotFound => return error.MsvcLibDirNotFound, | 1031 | error.PathNotFound => return error.MsvcLibDirNotFound, |
| 1023 | }, | 1032 | }, |
lib/std/zig/llvm/Builder.zig+11-8| ... | @@ -1,14 +1,17 @@ | ... | @@ -1,14 +1,17 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const Builder = @This(); | ||
| 3 | |||
| 1 | const std = @import("../../std.zig"); | 4 | const std = @import("../../std.zig"); |
| 5 | const Io = std.Io; | ||
| 2 | const Allocator = std.mem.Allocator; | 6 | const Allocator = std.mem.Allocator; |
| 3 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 4 | const bitcode_writer = @import("bitcode_writer.zig"); | ||
| 5 | const Builder = @This(); | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | const DW = std.dwarf; | 8 | const DW = std.dwarf; |
| 8 | const ir = @import("ir.zig"); | ||
| 9 | const log = std.log.scoped(.llvm); | 9 | const log = std.log.scoped(.llvm); |
| 10 | const Writer = std.Io.Writer; | 10 | const Writer = std.Io.Writer; |
| 11 | 11 | ||
| 12 | const bitcode_writer = @import("bitcode_writer.zig"); | ||
| 13 | const ir = @import("ir.zig"); | ||
| 14 | |||
| 12 | gpa: Allocator, | 15 | gpa: Allocator, |
| 13 | strip: bool, | 16 | strip: bool, |
| 14 | 17 | ||
| ... | @@ -9579,11 +9582,11 @@ pub fn dump(b: *Builder) void { | ... | @@ -9579,11 +9582,11 @@ pub fn dump(b: *Builder) void { |
| 9579 | b.printToFile(stderr, &buffer) catch {}; | 9582 | b.printToFile(stderr, &buffer) catch {}; |
| 9580 | } | 9583 | } |
| 9581 | 9584 | ||
| 9582 | pub fn printToFilePath(b: *Builder, dir: std.fs.Dir, path: []const u8) !void { | 9585 | pub fn printToFilePath(b: *Builder, io: Io, dir: std.fs.Dir, path: []const u8) !void { |
| 9583 | var buffer: [4000]u8 = undefined; | 9586 | var buffer: [4000]u8 = undefined; |
| 9584 | const file = try dir.createFile(path, .{}); | 9587 | const file = try dir.createFile(io, path, .{}); |
| 9585 | defer file.close(); | 9588 | defer file.close(io); |
| 9586 | try b.printToFile(file, &buffer); | 9589 | try b.printToFile(io, file, &buffer); |
| 9587 | } | 9590 | } |
| 9588 | 9591 | ||
| 9589 | pub fn printToFile(b: *Builder, file: std.fs.File, buffer: []u8) !void { | 9592 | pub fn printToFile(b: *Builder, file: std.fs.File, buffer: []u8) !void { |
lib/std/zig/system.zig+2-2| ... | @@ -847,7 +847,7 @@ fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion { | ... | @@ -847,7 +847,7 @@ fn glibcVerFromRPath(io: Io, rpath: []const u8) !std.SemanticVersion { |
| 847 | error.Unexpected => |e| return e, | 847 | error.Unexpected => |e| return e, |
| 848 | error.Canceled => |e| return e, | 848 | error.Canceled => |e| return e, |
| 849 | }; | 849 | }; |
| 850 | defer file.close(); | 850 | defer file.close(io); |
| 851 | 851 | ||
| 852 | // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system. | 852 | // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system. |
| 853 | var buffer: [8000]u8 = undefined; | 853 | var buffer: [8000]u8 = undefined; |
| ... | @@ -1051,7 +1051,7 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ | ... | @@ -1051,7 +1051,7 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ |
| 1051 | else => |e| return e, | 1051 | else => |e| return e, |
| 1052 | }; | 1052 | }; |
| 1053 | var is_elf_file = false; | 1053 | var is_elf_file = false; |
| 1054 | defer if (!is_elf_file) file.close(); | 1054 | defer if (!is_elf_file) file.close(io); |
| 1055 | 1055 | ||
| 1056 | file_reader = .initAdapted(file, io, &file_reader_buffer); | 1056 | file_reader = .initAdapted(file, io, &file_reader_buffer); |
| 1057 | file_name = undefined; // it aliases file_reader_buffer | 1057 | file_name = undefined; // it aliases file_reader_buffer |
lib/std/zig/system/linux.zig+1-1| ... | @@ -447,7 +447,7 @@ pub fn detectNativeCpuAndFeatures(io: Io) ?Target.Cpu { | ... | @@ -447,7 +447,7 @@ pub fn detectNativeCpuAndFeatures(io: Io) ?Target.Cpu { |
| 447 | var file = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { | 447 | var file = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { |
| 448 | else => return null, | 448 | else => return null, |
| 449 | }; | 449 | }; |
| 450 | defer file.close(); | 450 | defer file.close(io); |
| 451 | 451 | ||
| 452 | var buffer: [4096]u8 = undefined; // "flags" lines can get pretty long. | 452 | var buffer: [4096]u8 = undefined; // "flags" lines can get pretty long. |
| 453 | var file_reader = file.reader(io, &buffer); | 453 | var file_reader = file.reader(io, &buffer); |
lib/std/zip.zig+4-2| ... | @@ -554,17 +554,19 @@ pub const Iterator = struct { | ... | @@ -554,17 +554,19 @@ pub const Iterator = struct { |
| 554 | return; | 554 | return; |
| 555 | } | 555 | } |
| 556 | 556 | ||
| 557 | const io = stream.io; | ||
| 558 | |||
| 557 | const out_file = blk: { | 559 | const out_file = blk: { |
| 558 | if (std.fs.path.dirname(filename)) |dirname| { | 560 | if (std.fs.path.dirname(filename)) |dirname| { |
| 559 | var parent_dir = try dest.makeOpenPath(dirname, .{}); | 561 | var parent_dir = try dest.makeOpenPath(dirname, .{}); |
| 560 | defer parent_dir.close(); | 562 | defer parent_dir.close(io); |
| 561 | 563 | ||
| 562 | const basename = std.fs.path.basename(filename); | 564 | const basename = std.fs.path.basename(filename); |
| 563 | break :blk try parent_dir.createFile(basename, .{ .exclusive = true }); | 565 | break :blk try parent_dir.createFile(basename, .{ .exclusive = true }); |
| 564 | } | 566 | } |
| 565 | break :blk try dest.createFile(filename, .{ .exclusive = true }); | 567 | break :blk try dest.createFile(filename, .{ .exclusive = true }); |
| 566 | }; | 568 | }; |
| 567 | defer out_file.close(); | 569 | defer out_file.close(io); |
| 568 | var out_file_buffer: [1024]u8 = undefined; | 570 | var out_file_buffer: [1024]u8 = undefined; |
| 569 | var file_writer = out_file.writer(&out_file_buffer); | 571 | var file_writer = out_file.writer(&out_file_buffer); |
| 570 | const local_data_file_offset: u64 = | 572 | const local_data_file_offset: u64 = |
src/Compilation.zig+34-30| ... | @@ -721,13 +721,13 @@ pub const Directories = struct { | ... | @@ -721,13 +721,13 @@ pub const Directories = struct { |
| 721 | /// This may be the same as `global_cache`. | 721 | /// This may be the same as `global_cache`. |
| 722 | local_cache: Cache.Directory, | 722 | local_cache: Cache.Directory, |
| 723 | 723 | ||
| 724 | pub fn deinit(dirs: *Directories) void { | 724 | pub fn deinit(dirs: *Directories, io: Io) void { |
| 725 | // The local and global caches could be the same. | 725 | // The local and global caches could be the same. |
| 726 | const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; | 726 | const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; |
| 727 | 727 | ||
| 728 | dirs.global_cache.handle.close(); | 728 | dirs.global_cache.handle.close(io); |
| 729 | if (close_local) dirs.local_cache.handle.close(); | 729 | if (close_local) dirs.local_cache.handle.close(io); |
| 730 | dirs.zig_lib.handle.close(); | 730 | dirs.zig_lib.handle.close(io); |
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | /// Returns a `Directories` where `local_cache` is replaced with `global_cache`, intended for | 733 | /// Returns a `Directories` where `local_cache` is replaced with `global_cache`, intended for |
| ... | @@ -1105,7 +1105,7 @@ pub const CObject = struct { | ... | @@ -1105,7 +1105,7 @@ pub const CObject = struct { |
| 1105 | if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; | 1105 | if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; |
| 1106 | 1106 | ||
| 1107 | const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; | 1107 | const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; |
| 1108 | defer file.close(); | 1108 | defer file.close(io); |
| 1109 | var buffer: [1024]u8 = undefined; | 1109 | var buffer: [1024]u8 = undefined; |
| 1110 | var file_reader = file.reader(io, &buffer); | 1110 | var file_reader = file.reader(io, &buffer); |
| 1111 | file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | 1111 | 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 { | ... | @@ -1180,7 +1180,7 @@ pub const CObject = struct { |
| 1180 | 1180 | ||
| 1181 | var buffer: [1024]u8 = undefined; | 1181 | var buffer: [1024]u8 = undefined; |
| 1182 | const file = try fs.cwd().openFile(path, .{}); | 1182 | const file = try fs.cwd().openFile(path, .{}); |
| 1183 | defer file.close(); | 1183 | defer file.close(io); |
| 1184 | var file_reader = file.reader(io, &buffer); | 1184 | var file_reader = file.reader(io, &buffer); |
| 1185 | var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); | 1185 | var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); |
| 1186 | defer bc.deinit(); | 1186 | defer bc.deinit(); |
| ... | @@ -1617,13 +1617,13 @@ const CacheUse = union(CacheMode) { | ... | @@ -1617,13 +1617,13 @@ const CacheUse = union(CacheMode) { |
| 1617 | } | 1617 | } |
| 1618 | }; | 1618 | }; |
| 1619 | 1619 | ||
| 1620 | fn deinit(cu: CacheUse) void { | 1620 | fn deinit(cu: CacheUse, io: Io) void { |
| 1621 | switch (cu) { | 1621 | switch (cu) { |
| 1622 | .none => |none| { | 1622 | .none => |none| { |
| 1623 | assert(none.tmp_artifact_directory == null); | 1623 | assert(none.tmp_artifact_directory == null); |
| 1624 | }, | 1624 | }, |
| 1625 | .incremental => |incremental| { | 1625 | .incremental => |incremental| { |
| 1626 | incremental.artifact_directory.handle.close(); | 1626 | incremental.artifact_directory.handle.close(io); |
| 1627 | }, | 1627 | }, |
| 1628 | .whole => |whole| { | 1628 | .whole => |whole| { |
| 1629 | assert(whole.tmp_artifact_directory == null); | 1629 | assert(whole.tmp_artifact_directory == null); |
| ... | @@ -2113,7 +2113,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, | ... | @@ -2113,7 +2113,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2113 | cache.addPrefix(options.dirs.zig_lib); | 2113 | cache.addPrefix(options.dirs.zig_lib); |
| 2114 | cache.addPrefix(options.dirs.local_cache); | 2114 | cache.addPrefix(options.dirs.local_cache); |
| 2115 | cache.addPrefix(options.dirs.global_cache); | 2115 | cache.addPrefix(options.dirs.global_cache); |
| 2116 | errdefer cache.manifest_dir.close(); | 2116 | errdefer cache.manifest_dir.close(io); |
| 2117 | 2117 | ||
| 2118 | // This is shared hasher state common to zig source and all C source files. | 2118 | // This is shared hasher state common to zig source and all C source files. |
| 2119 | cache.hash.addBytes(build_options.version); | 2119 | cache.hash.addBytes(build_options.version); |
| ... | @@ -2157,7 +2157,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, | ... | @@ -2157,7 +2157,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2157 | var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { | 2157 | var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { |
| 2158 | return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } }); | 2158 | return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } }); |
| 2159 | }; | 2159 | }; |
| 2160 | errdefer local_zir_dir.close(); | 2160 | errdefer local_zir_dir.close(io); |
| 2161 | const local_zir_cache: Cache.Directory = .{ | 2161 | const local_zir_cache: Cache.Directory = .{ |
| 2162 | .handle = local_zir_dir, | 2162 | .handle = local_zir_dir, |
| 2163 | .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), | 2163 | .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, | ... | @@ -2165,7 +2165,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2165 | var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { | 2165 | var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| { |
| 2166 | return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } }); | 2166 | return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } }); |
| 2167 | }; | 2167 | }; |
| 2168 | errdefer global_zir_dir.close(); | 2168 | errdefer global_zir_dir.close(io); |
| 2169 | const global_zir_cache: Cache.Directory = .{ | 2169 | const global_zir_cache: Cache.Directory = .{ |
| 2170 | .handle = global_zir_dir, | 2170 | .handle = global_zir_dir, |
| 2171 | .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}), | 2171 | .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, | ... | @@ -2436,7 +2436,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2436 | var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}) catch |err| { | 2436 | var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}) catch |err| { |
| 2437 | return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } }); | 2437 | return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } }); |
| 2438 | }; | 2438 | }; |
| 2439 | errdefer artifact_dir.close(); | 2439 | errdefer artifact_dir.close(io); |
| 2440 | const artifact_directory: Cache.Directory = .{ | 2440 | const artifact_directory: Cache.Directory = .{ |
| 2441 | .handle = artifact_dir, | 2441 | .handle = artifact_dir, |
| 2442 | .path = try options.dirs.local_cache.join(arena, &.{artifact_sub_dir}), | 2442 | .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, | ... | @@ -2689,6 +2689,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2689 | 2689 | ||
| 2690 | pub fn destroy(comp: *Compilation) void { | 2690 | pub fn destroy(comp: *Compilation) void { |
| 2691 | const gpa = comp.gpa; | 2691 | const gpa = comp.gpa; |
| 2692 | const io = comp.io; | ||
| 2692 | 2693 | ||
| 2693 | if (comp.bin_file) |lf| lf.destroy(); | 2694 | if (comp.bin_file) |lf| lf.destroy(); |
| 2694 | if (comp.zcu) |zcu| zcu.deinit(); | 2695 | if (comp.zcu) |zcu| zcu.deinit(); |
| ... | @@ -2760,7 +2761,7 @@ pub fn destroy(comp: *Compilation) void { | ... | @@ -2760,7 +2761,7 @@ pub fn destroy(comp: *Compilation) void { |
| 2760 | 2761 | ||
| 2761 | comp.clearMiscFailures(); | 2762 | comp.clearMiscFailures(); |
| 2762 | 2763 | ||
| 2763 | comp.cache_parent.manifest_dir.close(); | 2764 | comp.cache_parent.manifest_dir.close(io); |
| 2764 | } | 2765 | } |
| 2765 | 2766 | ||
| 2766 | pub fn clearMiscFailures(comp: *Compilation) void { | 2767 | pub fn clearMiscFailures(comp: *Compilation) void { |
| ... | @@ -2791,10 +2792,12 @@ pub fn hotCodeSwap( | ... | @@ -2791,10 +2792,12 @@ pub fn hotCodeSwap( |
| 2791 | } | 2792 | } |
| 2792 | 2793 | ||
| 2793 | fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { | 2794 | fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { |
| 2795 | const io = comp.io; | ||
| 2796 | |||
| 2794 | switch (comp.cache_use) { | 2797 | switch (comp.cache_use) { |
| 2795 | .none => |none| { | 2798 | .none => |none| { |
| 2796 | if (none.tmp_artifact_directory) |*tmp_dir| { | 2799 | if (none.tmp_artifact_directory) |*tmp_dir| { |
| 2797 | tmp_dir.handle.close(); | 2800 | tmp_dir.handle.close(io); |
| 2798 | none.tmp_artifact_directory = null; | 2801 | none.tmp_artifact_directory = null; |
| 2799 | if (dev.env == .bootstrap) { | 2802 | if (dev.env == .bootstrap) { |
| 2800 | // zig1 uses `CacheMode.none`, but it doesn't need to know how to delete | 2803 | // 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 { | ... | @@ -2834,7 +2837,7 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { |
| 2834 | comp.bin_file = null; | 2837 | comp.bin_file = null; |
| 2835 | } | 2838 | } |
| 2836 | if (whole.tmp_artifact_directory) |*tmp_dir| { | 2839 | if (whole.tmp_artifact_directory) |*tmp_dir| { |
| 2837 | tmp_dir.handle.close(); | 2840 | tmp_dir.handle.close(io); |
| 2838 | whole.tmp_artifact_directory = null; | 2841 | whole.tmp_artifact_directory = null; |
| 2839 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); | 2842 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); |
| 2840 | comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| { | 2843 | 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 | ... | @@ -3152,7 +3155,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE |
| 3152 | // the file handle and re-open it in the follow up call to | 3155 | // the file handle and re-open it in the follow up call to |
| 3153 | // `makeWritable`. | 3156 | // `makeWritable`. |
| 3154 | if (lf.file) |f| { | 3157 | if (lf.file) |f| { |
| 3155 | f.close(); | 3158 | f.close(io); |
| 3156 | lf.file = null; | 3159 | lf.file = null; |
| 3157 | 3160 | ||
| 3158 | if (lf.closeDebugInfo()) break :w .lf_and_debug; | 3161 | if (lf.closeDebugInfo()) break :w .lf_and_debug; |
| ... | @@ -3165,7 +3168,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE | ... | @@ -3165,7 +3168,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE |
| 3165 | 3168 | ||
| 3166 | // Rename the temporary directory into place. | 3169 | // Rename the temporary directory into place. |
| 3167 | // Close tmp dir and link.File to avoid open handle during rename. | 3170 | // Close tmp dir and link.File to avoid open handle during rename. |
| 3168 | whole.tmp_artifact_directory.?.handle.close(); | 3171 | whole.tmp_artifact_directory.?.handle.close(io); |
| 3169 | whole.tmp_artifact_directory = null; | 3172 | whole.tmp_artifact_directory = null; |
| 3170 | const s = fs.path.sep_str; | 3173 | const s = fs.path.sep_str; |
| 3171 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); | 3174 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); |
| ... | @@ -5258,6 +5261,7 @@ fn workerDocsCopy(comp: *Compilation) void { | ... | @@ -5258,6 +5261,7 @@ fn workerDocsCopy(comp: *Compilation) void { |
| 5258 | 5261 | ||
| 5259 | fn docsCopyFallible(comp: *Compilation) anyerror!void { | 5262 | fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 5260 | const zcu = comp.zcu orelse return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{}); | 5263 | const zcu = comp.zcu orelse return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{}); |
| 5264 | const io = comp.io; | ||
| 5261 | 5265 | ||
| 5262 | const docs_path = comp.resolveEmitPath(comp.emit_docs.?); | 5266 | const docs_path = comp.resolveEmitPath(comp.emit_docs.?); |
| 5263 | var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| { | 5267 | 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 { | ... | @@ -5267,7 +5271,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 5267 | .{ docs_path, @errorName(err) }, | 5271 | .{ docs_path, @errorName(err) }, |
| 5268 | ); | 5272 | ); |
| 5269 | }; | 5273 | }; |
| 5270 | defer out_dir.close(); | 5274 | defer out_dir.close(io); |
| 5271 | 5275 | ||
| 5272 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { | 5276 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { |
| 5273 | const basename = fs.path.basename(sub_path); | 5277 | const basename = fs.path.basename(sub_path); |
| ... | @@ -5287,7 +5291,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -5287,7 +5291,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 5287 | .{ docs_path, @errorName(err) }, | 5291 | .{ docs_path, @errorName(err) }, |
| 5288 | ); | 5292 | ); |
| 5289 | }; | 5293 | }; |
| 5290 | defer tar_file.close(); | 5294 | defer tar_file.close(io); |
| 5291 | 5295 | ||
| 5292 | var buffer: [1024]u8 = undefined; | 5296 | var buffer: [1024]u8 = undefined; |
| 5293 | var tar_file_writer = tar_file.writer(&buffer); | 5297 | var tar_file_writer = tar_file.writer(&buffer); |
| ... | @@ -5331,7 +5335,7 @@ fn docsCopyModule( | ... | @@ -5331,7 +5335,7 @@ fn docsCopyModule( |
| 5331 | } catch |err| { | 5335 | } catch |err| { |
| 5332 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err }); | 5336 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {t}", .{ root.fmt(comp), err }); |
| 5333 | }; | 5337 | }; |
| 5334 | defer mod_dir.close(); | 5338 | defer mod_dir.close(io); |
| 5335 | 5339 | ||
| 5336 | var walker = try mod_dir.walk(comp.gpa); | 5340 | var walker = try mod_dir.walk(comp.gpa); |
| 5337 | defer walker.deinit(); | 5341 | defer walker.deinit(); |
| ... | @@ -5355,7 +5359,7 @@ fn docsCopyModule( | ... | @@ -5355,7 +5359,7 @@ fn docsCopyModule( |
| 5355 | root.fmt(comp), entry.path, err, | 5359 | root.fmt(comp), entry.path, err, |
| 5356 | }); | 5360 | }); |
| 5357 | }; | 5361 | }; |
| 5358 | defer file.close(); | 5362 | defer file.close(io); |
| 5359 | const stat = try file.stat(); | 5363 | const stat = try file.stat(); |
| 5360 | var file_reader: fs.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); | 5364 | var file_reader: fs.File.Reader = .initSize(file.adaptToNewApi(), io, &buffer, stat.size); |
| 5361 | 5365 | ||
| ... | @@ -5510,7 +5514,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU | ... | @@ -5510,7 +5514,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU |
| 5510 | ); | 5514 | ); |
| 5511 | return error.AlreadyReported; | 5515 | return error.AlreadyReported; |
| 5512 | }; | 5516 | }; |
| 5513 | defer out_dir.close(); | 5517 | defer out_dir.close(io); |
| 5514 | 5518 | ||
| 5515 | crt_file.full_object_path.root_dir.handle.copyFile( | 5519 | crt_file.full_object_path.root_dir.handle.copyFile( |
| 5516 | crt_file.full_object_path.sub_path, | 5520 | crt_file.full_object_path.sub_path, |
| ... | @@ -5693,7 +5697,7 @@ pub fn translateC( | ... | @@ -5693,7 +5697,7 @@ pub fn translateC( |
| 5693 | const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename; | 5697 | const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ tmp_basename; |
| 5694 | const cache_dir = comp.dirs.local_cache.handle; | 5698 | const cache_dir = comp.dirs.local_cache.handle; |
| 5695 | var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{}); | 5699 | var cache_tmp_dir = try cache_dir.makeOpenPath(tmp_sub_path, .{}); |
| 5696 | defer cache_tmp_dir.close(); | 5700 | defer cache_tmp_dir.close(io); |
| 5697 | 5701 | ||
| 5698 | const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename }); | 5702 | const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename }); |
| 5699 | const source_path = switch (source) { | 5703 | const source_path = switch (source) { |
| ... | @@ -6268,7 +6272,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -6268,7 +6272,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 6268 | // so we need a temporary filename. | 6272 | // so we need a temporary filename. |
| 6269 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); | 6273 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); |
| 6270 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); | 6274 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 6271 | defer zig_cache_tmp_dir.close(); | 6275 | defer zig_cache_tmp_dir.close(io); |
| 6272 | 6276 | ||
| 6273 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) | 6277 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) |
| 6274 | null | 6278 | null |
| ... | @@ -6433,7 +6437,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -6433,7 +6437,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 6433 | const digest = man.final(); | 6437 | const digest = man.final(); |
| 6434 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 6438 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 6435 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); | 6439 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 6436 | defer o_dir.close(); | 6440 | defer o_dir.close(io); |
| 6437 | const tmp_basename = fs.path.basename(out_obj_path); | 6441 | const tmp_basename = fs.path.basename(out_obj_path); |
| 6438 | try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); | 6442 | try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); |
| 6439 | break :blk digest; | 6443 | break :blk digest; |
| ... | @@ -6477,8 +6481,6 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -6477,8 +6481,6 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6477 | const tracy_trace = trace(@src()); | 6481 | const tracy_trace = trace(@src()); |
| 6478 | defer tracy_trace.end(); | 6482 | defer tracy_trace.end(); |
| 6479 | 6483 | ||
| 6480 | const io = comp.io; | ||
| 6481 | |||
| 6482 | const src_path = switch (win32_resource.src) { | 6484 | const src_path = switch (win32_resource.src) { |
| 6483 | .rc => |rc_src| rc_src.src_path, | 6485 | .rc => |rc_src| rc_src.src_path, |
| 6484 | .manifest => |src_path| src_path, | 6486 | .manifest => |src_path| src_path, |
| ... | @@ -6487,6 +6489,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -6487,6 +6489,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6487 | 6489 | ||
| 6488 | log.debug("updating win32 resource: {s}", .{src_path}); | 6490 | log.debug("updating win32 resource: {s}", .{src_path}); |
| 6489 | 6491 | ||
| 6492 | const io = comp.io; | ||
| 6493 | |||
| 6490 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); | 6494 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
| 6491 | defer arena_allocator.deinit(); | 6495 | defer arena_allocator.deinit(); |
| 6492 | const arena = arena_allocator.allocator(); | 6496 | const arena = arena_allocator.allocator(); |
| ... | @@ -6522,7 +6526,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -6522,7 +6526,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6522 | 6526 | ||
| 6523 | const o_sub_path = try fs.path.join(arena, &.{ "o", &digest }); | 6527 | const o_sub_path = try fs.path.join(arena, &.{ "o", &digest }); |
| 6524 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); | 6528 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 6525 | defer o_dir.close(); | 6529 | defer o_dir.close(io); |
| 6526 | 6530 | ||
| 6527 | const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ | 6531 | const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ |
| 6528 | o_sub_path, rc_basename, | 6532 | o_sub_path, rc_basename, |
| ... | @@ -6610,7 +6614,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -6610,7 +6614,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6610 | 6614 | ||
| 6611 | const digest = if (try man.hit()) man.final() else blk: { | 6615 | const digest = if (try man.hit()) man.final() else blk: { |
| 6612 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); | 6616 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 6613 | defer zig_cache_tmp_dir.close(); | 6617 | defer zig_cache_tmp_dir.close(io); |
| 6614 | 6618 | ||
| 6615 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); | 6619 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); |
| 6616 | 6620 | ||
| ... | @@ -6681,7 +6685,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -6681,7 +6685,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6681 | const digest = man.final(); | 6685 | const digest = man.final(); |
| 6682 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 6686 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 6683 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); | 6687 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 6684 | defer o_dir.close(); | 6688 | defer o_dir.close(io); |
| 6685 | const tmp_basename = fs.path.basename(out_res_path); | 6689 | const tmp_basename = fs.path.basename(out_res_path); |
| 6686 | try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); | 6690 | try fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); |
| 6687 | break :blk digest; | 6691 | break :blk digest; |
src/Package/Fetch.zig+38-34| ... | @@ -513,7 +513,7 @@ fn runResource( | ... | @@ -513,7 +513,7 @@ fn runResource( |
| 513 | break :handle dir; | 513 | break :handle dir; |
| 514 | }, | 514 | }, |
| 515 | }; | 515 | }; |
| 516 | defer tmp_directory.handle.close(); | 516 | defer tmp_directory.handle.close(io); |
| 517 | 517 | ||
| 518 | // Fetch and unpack a resource into a temporary directory. | 518 | // Fetch and unpack a resource into a temporary directory. |
| 519 | var unpack_result = try unpackResource(f, resource, uri_path, tmp_directory); | 519 | var unpack_result = try unpackResource(f, resource, uri_path, tmp_directory); |
| ... | @@ -523,7 +523,7 @@ fn runResource( | ... | @@ -523,7 +523,7 @@ fn runResource( |
| 523 | // Apply btrfs workaround if needed. Reopen tmp_directory. | 523 | // Apply btrfs workaround if needed. Reopen tmp_directory. |
| 524 | if (native_os == .linux and f.job_queue.work_around_btrfs_bug) { | 524 | if (native_os == .linux and f.job_queue.work_around_btrfs_bug) { |
| 525 | // https://github.com/ziglang/zig/issues/17095 | 525 | // https://github.com/ziglang/zig/issues/17095 |
| 526 | pkg_path.root_dir.handle.close(); | 526 | pkg_path.root_dir.handle.close(io); |
| 527 | pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(tmp_dir_sub_path, .{ | 527 | pkg_path.root_dir.handle = cache_root.handle.makeOpenPath(tmp_dir_sub_path, .{ |
| 528 | .iterate = true, | 528 | .iterate = true, |
| 529 | }) catch @panic("btrfs workaround failed"); | 529 | }) catch @panic("btrfs workaround failed"); |
| ... | @@ -885,7 +885,7 @@ const Resource = union(enum) { | ... | @@ -885,7 +885,7 @@ const Resource = union(enum) { |
| 885 | file: fs.File.Reader, | 885 | file: fs.File.Reader, |
| 886 | http_request: HttpRequest, | 886 | http_request: HttpRequest, |
| 887 | git: Git, | 887 | git: Git, |
| 888 | dir: fs.Dir, | 888 | dir: Io.Dir, |
| 889 | 889 | ||
| 890 | const Git = struct { | 890 | const Git = struct { |
| 891 | session: git.Session, | 891 | session: git.Session, |
| ... | @@ -908,7 +908,7 @@ const Resource = union(enum) { | ... | @@ -908,7 +908,7 @@ const Resource = union(enum) { |
| 908 | .git => |*git_resource| { | 908 | .git => |*git_resource| { |
| 909 | git_resource.fetch_stream.deinit(); | 909 | git_resource.fetch_stream.deinit(); |
| 910 | }, | 910 | }, |
| 911 | .dir => |*dir| dir.close(), | 911 | .dir => |*dir| dir.close(io), |
| 912 | } | 912 | } |
| 913 | resource.* = undefined; | 913 | resource.* = undefined; |
| 914 | } | 914 | } |
| ... | @@ -1247,13 +1247,14 @@ fn unpackResource( | ... | @@ -1247,13 +1247,14 @@ fn unpackResource( |
| 1247 | } | 1247 | } |
| 1248 | } | 1248 | } |
| 1249 | 1249 | ||
| 1250 | fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: *Io.Reader) RunError!UnpackResult { | 1250 | fn unpackTarball(f: *Fetch, out_dir: Io.Dir, reader: *Io.Reader) RunError!UnpackResult { |
| 1251 | const eb = &f.error_bundle; | 1251 | const eb = &f.error_bundle; |
| 1252 | const arena = f.arena.allocator(); | 1252 | const arena = f.arena.allocator(); |
| 1253 | const io = f.job_queue.io; | ||
| 1253 | 1254 | ||
| 1254 | var diagnostics: std.tar.Diagnostics = .{ .allocator = arena }; | 1255 | var diagnostics: std.tar.Diagnostics = .{ .allocator = arena }; |
| 1255 | 1256 | ||
| 1256 | std.tar.pipeToFileSystem(out_dir, reader, .{ | 1257 | std.tar.pipeToFileSystem(io, out_dir, reader, .{ |
| 1257 | .diagnostics = &diagnostics, | 1258 | .diagnostics = &diagnostics, |
| 1258 | .strip_components = 0, | 1259 | .strip_components = 0, |
| 1259 | .mode_mode = .ignore, | 1260 | .mode_mode = .ignore, |
| ... | @@ -1280,7 +1281,7 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: *Io.Reader) RunError!Unpack | ... | @@ -1280,7 +1281,7 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: *Io.Reader) RunError!Unpack |
| 1280 | 1281 | ||
| 1281 | fn unzip( | 1282 | fn unzip( |
| 1282 | f: *Fetch, | 1283 | f: *Fetch, |
| 1283 | out_dir: fs.Dir, | 1284 | out_dir: Io.Dir, |
| 1284 | reader: *Io.Reader, | 1285 | reader: *Io.Reader, |
| 1285 | ) error{ ReadFailed, OutOfMemory, Canceled, FetchFailed }!UnpackResult { | 1286 | ) error{ ReadFailed, OutOfMemory, Canceled, FetchFailed }!UnpackResult { |
| 1286 | // We write the entire contents to a file first because zip files | 1287 | // We write the entire contents to a file first because zip files |
| ... | @@ -1314,7 +1315,7 @@ fn unzip( | ... | @@ -1314,7 +1315,7 @@ fn unzip( |
| 1314 | ), | 1315 | ), |
| 1315 | }; | 1316 | }; |
| 1316 | }; | 1317 | }; |
| 1317 | defer zip_file.close(); | 1318 | defer zip_file.close(io); |
| 1318 | var zip_file_buffer: [4096]u8 = undefined; | 1319 | var zip_file_buffer: [4096]u8 = undefined; |
| 1319 | var zip_file_reader = b: { | 1320 | var zip_file_reader = b: { |
| 1320 | var zip_file_writer = zip_file.writer(&zip_file_buffer); | 1321 | var zip_file_writer = zip_file.writer(&zip_file_buffer); |
| ... | @@ -1349,7 +1350,7 @@ fn unzip( | ... | @@ -1349,7 +1350,7 @@ fn unzip( |
| 1349 | return .{ .root_dir = diagnostics.root_dir }; | 1350 | return .{ .root_dir = diagnostics.root_dir }; |
| 1350 | } | 1351 | } |
| 1351 | 1352 | ||
| 1352 | fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!UnpackResult { | 1353 | fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!UnpackResult { |
| 1353 | const io = f.job_queue.io; | 1354 | const io = f.job_queue.io; |
| 1354 | const arena = f.arena.allocator(); | 1355 | const arena = f.arena.allocator(); |
| 1355 | // TODO don't try to get a gpa from an arena. expose this dependency higher up | 1356 | // TODO don't try to get a gpa from an arena. expose this dependency higher up |
| ... | @@ -1363,9 +1364,9 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U | ... | @@ -1363,9 +1364,9 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1363 | // directory, since that isn't relevant for fetching a package. | 1364 | // directory, since that isn't relevant for fetching a package. |
| 1364 | { | 1365 | { |
| 1365 | var pack_dir = try out_dir.makeOpenPath(".git", .{}); | 1366 | var pack_dir = try out_dir.makeOpenPath(".git", .{}); |
| 1366 | defer pack_dir.close(); | 1367 | defer pack_dir.close(io); |
| 1367 | var pack_file = try pack_dir.createFile("pkg.pack", .{ .read = true }); | 1368 | var pack_file = try pack_dir.createFile("pkg.pack", .{ .read = true }); |
| 1368 | defer pack_file.close(); | 1369 | defer pack_file.close(io); |
| 1369 | var pack_file_buffer: [4096]u8 = undefined; | 1370 | var pack_file_buffer: [4096]u8 = undefined; |
| 1370 | var pack_file_reader = b: { | 1371 | var pack_file_reader = b: { |
| 1371 | var pack_file_writer = pack_file.writer(&pack_file_buffer); | 1372 | var pack_file_writer = pack_file.writer(&pack_file_buffer); |
| ... | @@ -1376,7 +1377,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U | ... | @@ -1376,7 +1377,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1376 | }; | 1377 | }; |
| 1377 | 1378 | ||
| 1378 | var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true }); | 1379 | var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true }); |
| 1379 | defer index_file.close(); | 1380 | defer index_file.close(io); |
| 1380 | var index_file_buffer: [2000]u8 = undefined; | 1381 | var index_file_buffer: [2000]u8 = undefined; |
| 1381 | var index_file_writer = index_file.writer(&index_file_buffer); | 1382 | var index_file_writer = index_file.writer(&index_file_buffer); |
| 1382 | { | 1383 | { |
| ... | @@ -1393,7 +1394,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U | ... | @@ -1393,7 +1394,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1393 | try repository.init(gpa, object_format, &pack_file_reader, &index_file_reader); | 1394 | try repository.init(gpa, object_format, &pack_file_reader, &index_file_reader); |
| 1394 | defer repository.deinit(); | 1395 | defer repository.deinit(); |
| 1395 | var diagnostics: git.Diagnostics = .{ .allocator = arena }; | 1396 | var diagnostics: git.Diagnostics = .{ .allocator = arena }; |
| 1396 | try repository.checkout(out_dir, resource.want_oid, &diagnostics); | 1397 | try repository.checkout(io, out_dir, resource.want_oid, &diagnostics); |
| 1397 | 1398 | ||
| 1398 | if (diagnostics.errors.items.len > 0) { | 1399 | if (diagnostics.errors.items.len > 0) { |
| 1399 | try res.allocErrors(arena, diagnostics.errors.items.len, "unable to unpack packfile"); | 1400 | try res.allocErrors(arena, diagnostics.errors.items.len, "unable to unpack packfile"); |
| ... | @@ -1411,7 +1412,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U | ... | @@ -1411,7 +1412,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1411 | return res; | 1412 | return res; |
| 1412 | } | 1413 | } |
| 1413 | 1414 | ||
| 1414 | fn recursiveDirectoryCopy(f: *Fetch, dir: fs.Dir, tmp_dir: fs.Dir) anyerror!void { | 1415 | fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void { |
| 1415 | const gpa = f.arena.child_allocator; | 1416 | const gpa = f.arena.child_allocator; |
| 1416 | // Recursive directory copy. | 1417 | // Recursive directory copy. |
| 1417 | var it = try dir.walk(gpa); | 1418 | var it = try dir.walk(gpa); |
| ... | @@ -1451,7 +1452,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: fs.Dir, tmp_dir: fs.Dir) anyerror!void | ... | @@ -1451,7 +1452,7 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: fs.Dir, tmp_dir: fs.Dir) anyerror!void |
| 1451 | } | 1452 | } |
| 1452 | } | 1453 | } |
| 1453 | 1454 | ||
| 1454 | pub fn renameTmpIntoCache(cache_dir: fs.Dir, tmp_dir_sub_path: []const u8, dest_dir_sub_path: []const u8) !void { | 1455 | pub fn renameTmpIntoCache(cache_dir: Io.Dir, tmp_dir_sub_path: []const u8, dest_dir_sub_path: []const u8) !void { |
| 1455 | assert(dest_dir_sub_path[1] == fs.path.sep); | 1456 | assert(dest_dir_sub_path[1] == fs.path.sep); |
| 1456 | var handled_missing_dir = false; | 1457 | var handled_missing_dir = false; |
| 1457 | while (true) { | 1458 | while (true) { |
| ... | @@ -1660,15 +1661,15 @@ fn dumpHashInfo(all_files: []const *const HashedFile) !void { | ... | @@ -1660,15 +1661,15 @@ fn dumpHashInfo(all_files: []const *const HashedFile) !void { |
| 1660 | try w.flush(); | 1661 | try w.flush(); |
| 1661 | } | 1662 | } |
| 1662 | 1663 | ||
| 1663 | fn workerHashFile(dir: fs.Dir, hashed_file: *HashedFile) void { | 1664 | fn workerHashFile(dir: Io.Dir, hashed_file: *HashedFile) void { |
| 1664 | hashed_file.failure = hashFileFallible(dir, hashed_file); | 1665 | hashed_file.failure = hashFileFallible(dir, hashed_file); |
| 1665 | } | 1666 | } |
| 1666 | 1667 | ||
| 1667 | fn workerDeleteFile(dir: fs.Dir, deleted_file: *DeletedFile) void { | 1668 | fn workerDeleteFile(dir: Io.Dir, deleted_file: *DeletedFile) void { |
| 1668 | deleted_file.failure = deleteFileFallible(dir, deleted_file); | 1669 | deleted_file.failure = deleteFileFallible(dir, deleted_file); |
| 1669 | } | 1670 | } |
| 1670 | 1671 | ||
| 1671 | fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void { | 1672 | fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Error!void { |
| 1672 | var buf: [8000]u8 = undefined; | 1673 | var buf: [8000]u8 = undefined; |
| 1673 | var hasher = Package.Hash.Algo.init(.{}); | 1674 | var hasher = Package.Hash.Algo.init(.{}); |
| 1674 | hasher.update(hashed_file.normalized_path); | 1675 | hasher.update(hashed_file.normalized_path); |
| ... | @@ -1677,7 +1678,7 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void | ... | @@ -1677,7 +1678,7 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void |
| 1677 | switch (hashed_file.kind) { | 1678 | switch (hashed_file.kind) { |
| 1678 | .file => { | 1679 | .file => { |
| 1679 | var file = try dir.openFile(hashed_file.fs_path, .{}); | 1680 | var file = try dir.openFile(hashed_file.fs_path, .{}); |
| 1680 | defer file.close(); | 1681 | defer file.close(io); |
| 1681 | // Hard-coded false executable bit: https://github.com/ziglang/zig/issues/17463 | 1682 | // Hard-coded false executable bit: https://github.com/ziglang/zig/issues/17463 |
| 1682 | hasher.update(&.{ 0, 0 }); | 1683 | hasher.update(&.{ 0, 0 }); |
| 1683 | var file_header: FileHeader = .{}; | 1684 | var file_header: FileHeader = .{}; |
| ... | @@ -1707,7 +1708,7 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void | ... | @@ -1707,7 +1708,7 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void |
| 1707 | hashed_file.size = file_size; | 1708 | hashed_file.size = file_size; |
| 1708 | } | 1709 | } |
| 1709 | 1710 | ||
| 1710 | fn deleteFileFallible(dir: fs.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { | 1711 | fn deleteFileFallible(dir: Io.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void { |
| 1711 | try dir.deleteFile(deleted_file.fs_path); | 1712 | try dir.deleteFile(deleted_file.fs_path); |
| 1712 | } | 1713 | } |
| 1713 | 1714 | ||
| ... | @@ -1724,8 +1725,8 @@ const DeletedFile = struct { | ... | @@ -1724,8 +1725,8 @@ const DeletedFile = struct { |
| 1724 | failure: Error!void, | 1725 | failure: Error!void, |
| 1725 | 1726 | ||
| 1726 | const Error = | 1727 | const Error = |
| 1727 | fs.Dir.DeleteFileError || | 1728 | Io.Dir.DeleteFileError || |
| 1728 | fs.Dir.DeleteDirError; | 1729 | Io.Dir.DeleteDirError; |
| 1729 | }; | 1730 | }; |
| 1730 | 1731 | ||
| 1731 | const HashedFile = struct { | 1732 | const HashedFile = struct { |
| ... | @@ -1741,7 +1742,7 @@ const HashedFile = struct { | ... | @@ -1741,7 +1742,7 @@ const HashedFile = struct { |
| 1741 | fs.File.ReadError || | 1742 | fs.File.ReadError || |
| 1742 | fs.File.StatError || | 1743 | fs.File.StatError || |
| 1743 | fs.File.ChmodError || | 1744 | fs.File.ChmodError || |
| 1744 | fs.Dir.ReadLinkError; | 1745 | Io.Dir.ReadLinkError; |
| 1745 | 1746 | ||
| 1746 | const Kind = enum { file, link }; | 1747 | const Kind = enum { file, link }; |
| 1747 | 1748 | ||
| ... | @@ -2074,7 +2075,7 @@ test "tarball with duplicate paths" { | ... | @@ -2074,7 +2075,7 @@ test "tarball with duplicate paths" { |
| 2074 | defer tmp.cleanup(); | 2075 | defer tmp.cleanup(); |
| 2075 | 2076 | ||
| 2076 | const tarball_name = "duplicate_paths.tar.gz"; | 2077 | const tarball_name = "duplicate_paths.tar.gz"; |
| 2077 | try saveEmbedFile(tarball_name, tmp.dir); | 2078 | try saveEmbedFile(io, tarball_name, tmp.dir); |
| 2078 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); | 2079 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); |
| 2079 | defer gpa.free(tarball_path); | 2080 | defer gpa.free(tarball_path); |
| 2080 | 2081 | ||
| ... | @@ -2107,7 +2108,7 @@ test "tarball with excluded duplicate paths" { | ... | @@ -2107,7 +2108,7 @@ test "tarball with excluded duplicate paths" { |
| 2107 | defer tmp.cleanup(); | 2108 | defer tmp.cleanup(); |
| 2108 | 2109 | ||
| 2109 | const tarball_name = "duplicate_paths_excluded.tar.gz"; | 2110 | const tarball_name = "duplicate_paths_excluded.tar.gz"; |
| 2110 | try saveEmbedFile(tarball_name, tmp.dir); | 2111 | try saveEmbedFile(io, tarball_name, tmp.dir); |
| 2111 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); | 2112 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); |
| 2112 | defer gpa.free(tarball_path); | 2113 | defer gpa.free(tarball_path); |
| 2113 | 2114 | ||
| ... | @@ -2153,7 +2154,7 @@ test "tarball without root folder" { | ... | @@ -2153,7 +2154,7 @@ test "tarball without root folder" { |
| 2153 | defer tmp.cleanup(); | 2154 | defer tmp.cleanup(); |
| 2154 | 2155 | ||
| 2155 | const tarball_name = "no_root.tar.gz"; | 2156 | const tarball_name = "no_root.tar.gz"; |
| 2156 | try saveEmbedFile(tarball_name, tmp.dir); | 2157 | try saveEmbedFile(io, tarball_name, tmp.dir); |
| 2157 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); | 2158 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); |
| 2158 | defer gpa.free(tarball_path); | 2159 | defer gpa.free(tarball_path); |
| 2159 | 2160 | ||
| ... | @@ -2186,7 +2187,7 @@ test "set executable bit based on file content" { | ... | @@ -2186,7 +2187,7 @@ test "set executable bit based on file content" { |
| 2186 | defer tmp.cleanup(); | 2187 | defer tmp.cleanup(); |
| 2187 | 2188 | ||
| 2188 | const tarball_name = "executables.tar.gz"; | 2189 | const tarball_name = "executables.tar.gz"; |
| 2189 | try saveEmbedFile(tarball_name, tmp.dir); | 2190 | try saveEmbedFile(io, tarball_name, tmp.dir); |
| 2190 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); | 2191 | const tarball_path = try std.fmt.allocPrint(gpa, ".zig-cache/tmp/{s}/{s}", .{ tmp.sub_path, tarball_name }); |
| 2191 | defer gpa.free(tarball_path); | 2192 | defer gpa.free(tarball_path); |
| 2192 | 2193 | ||
| ... | @@ -2210,7 +2211,7 @@ test "set executable bit based on file content" { | ... | @@ -2210,7 +2211,7 @@ test "set executable bit based on file content" { |
| 2210 | ); | 2211 | ); |
| 2211 | 2212 | ||
| 2212 | var out = try fb.packageDir(); | 2213 | var out = try fb.packageDir(); |
| 2213 | defer out.close(); | 2214 | defer out.close(io); |
| 2214 | const S = std.posix.S; | 2215 | const S = std.posix.S; |
| 2215 | // expect executable bit not set | 2216 | // expect executable bit not set |
| 2216 | try std.testing.expect((try out.statFile("file1")).mode & S.IXUSR == 0); | 2217 | try std.testing.expect((try out.statFile("file1")).mode & S.IXUSR == 0); |
| ... | @@ -2231,11 +2232,11 @@ test "set executable bit based on file content" { | ... | @@ -2231,11 +2232,11 @@ test "set executable bit based on file content" { |
| 2231 | // -rwxrwxr-x 1 17 Apr script_with_shebang_without_exec_bit | 2232 | // -rwxrwxr-x 1 17 Apr script_with_shebang_without_exec_bit |
| 2232 | } | 2233 | } |
| 2233 | 2234 | ||
| 2234 | fn saveEmbedFile(comptime tarball_name: []const u8, dir: fs.Dir) !void { | 2235 | fn saveEmbedFile(io: Io, comptime tarball_name: []const u8, dir: Io.Dir) !void { |
| 2235 | //const tarball_name = "duplicate_paths_excluded.tar.gz"; | 2236 | //const tarball_name = "duplicate_paths_excluded.tar.gz"; |
| 2236 | const tarball_content = @embedFile("Fetch/testdata/" ++ tarball_name); | 2237 | const tarball_content = @embedFile("Fetch/testdata/" ++ tarball_name); |
| 2237 | var tmp_file = try dir.createFile(tarball_name, .{}); | 2238 | var tmp_file = try dir.createFile(tarball_name, .{}); |
| 2238 | defer tmp_file.close(); | 2239 | defer tmp_file.close(io); |
| 2239 | try tmp_file.writeAll(tarball_content); | 2240 | try tmp_file.writeAll(tarball_content); |
| 2240 | } | 2241 | } |
| 2241 | 2242 | ||
| ... | @@ -2250,7 +2251,7 @@ const TestFetchBuilder = struct { | ... | @@ -2250,7 +2251,7 @@ const TestFetchBuilder = struct { |
| 2250 | self: *TestFetchBuilder, | 2251 | self: *TestFetchBuilder, |
| 2251 | allocator: std.mem.Allocator, | 2252 | allocator: std.mem.Allocator, |
| 2252 | io: Io, | 2253 | io: Io, |
| 2253 | cache_parent_dir: std.fs.Dir, | 2254 | cache_parent_dir: std.Io.Dir, |
| 2254 | path_or_url: []const u8, | 2255 | path_or_url: []const u8, |
| 2255 | ) !*Fetch { | 2256 | ) !*Fetch { |
| 2256 | const cache_dir = try cache_parent_dir.makeOpenPath("zig-global-cache", .{}); | 2257 | const cache_dir = try cache_parent_dir.makeOpenPath("zig-global-cache", .{}); |
| ... | @@ -2301,14 +2302,15 @@ const TestFetchBuilder = struct { | ... | @@ -2301,14 +2302,15 @@ const TestFetchBuilder = struct { |
| 2301 | } | 2302 | } |
| 2302 | 2303 | ||
| 2303 | fn deinit(self: *TestFetchBuilder) void { | 2304 | fn deinit(self: *TestFetchBuilder) void { |
| 2305 | const io = self.job_queue.io; | ||
| 2304 | self.fetch.deinit(); | 2306 | self.fetch.deinit(); |
| 2305 | self.job_queue.deinit(); | 2307 | self.job_queue.deinit(); |
| 2306 | self.fetch.prog_node.end(); | 2308 | self.fetch.prog_node.end(); |
| 2307 | self.global_cache_directory.handle.close(); | 2309 | self.global_cache_directory.handle.close(io); |
| 2308 | self.http_client.deinit(); | 2310 | self.http_client.deinit(); |
| 2309 | } | 2311 | } |
| 2310 | 2312 | ||
| 2311 | fn packageDir(self: *TestFetchBuilder) !fs.Dir { | 2313 | fn packageDir(self: *TestFetchBuilder) !Io.Dir { |
| 2312 | const root = self.fetch.package_root; | 2314 | const root = self.fetch.package_root; |
| 2313 | return try root.root_dir.handle.openDir(root.sub_path, .{ .iterate = true }); | 2315 | return try root.root_dir.handle.openDir(root.sub_path, .{ .iterate = true }); |
| 2314 | } | 2316 | } |
| ... | @@ -2316,8 +2318,10 @@ const TestFetchBuilder = struct { | ... | @@ -2316,8 +2318,10 @@ const TestFetchBuilder = struct { |
| 2316 | // Test helper, asserts thet package dir constains expected_files. | 2318 | // Test helper, asserts thet package dir constains expected_files. |
| 2317 | // expected_files must be sorted. | 2319 | // expected_files must be sorted. |
| 2318 | fn expectPackageFiles(self: *TestFetchBuilder, expected_files: []const []const u8) !void { | 2320 | fn expectPackageFiles(self: *TestFetchBuilder, expected_files: []const []const u8) !void { |
| 2321 | const io = self.job_queue.io; | ||
| 2322 | |||
| 2319 | var package_dir = try self.packageDir(); | 2323 | var package_dir = try self.packageDir(); |
| 2320 | defer package_dir.close(); | 2324 | defer package_dir.close(io); |
| 2321 | 2325 | ||
| 2322 | var actual_files: std.ArrayList([]u8) = .empty; | 2326 | var actual_files: std.ArrayList([]u8) = .empty; |
| 2323 | defer actual_files.deinit(std.testing.allocator); | 2327 | defer actual_files.deinit(std.testing.allocator); |
src/Package/Fetch/git.zig+14-12| ... | @@ -213,6 +213,7 @@ pub const Repository = struct { | ... | @@ -213,6 +213,7 @@ pub const Repository = struct { |
| 213 | /// Checks out the repository at `commit_oid` to `worktree`. | 213 | /// Checks out the repository at `commit_oid` to `worktree`. |
| 214 | pub fn checkout( | 214 | pub fn checkout( |
| 215 | repository: *Repository, | 215 | repository: *Repository, |
| 216 | io: Io, | ||
| 216 | worktree: std.fs.Dir, | 217 | worktree: std.fs.Dir, |
| 217 | commit_oid: Oid, | 218 | commit_oid: Oid, |
| 218 | diagnostics: *Diagnostics, | 219 | diagnostics: *Diagnostics, |
| ... | @@ -223,12 +224,13 @@ pub const Repository = struct { | ... | @@ -223,12 +224,13 @@ pub const Repository = struct { |
| 223 | if (commit_object.type != .commit) return error.NotACommit; | 224 | if (commit_object.type != .commit) return error.NotACommit; |
| 224 | break :tree_oid try getCommitTree(repository.odb.format, commit_object.data); | 225 | break :tree_oid try getCommitTree(repository.odb.format, commit_object.data); |
| 225 | }; | 226 | }; |
| 226 | try repository.checkoutTree(worktree, tree_oid, "", diagnostics); | 227 | try repository.checkoutTree(io, worktree, tree_oid, "", diagnostics); |
| 227 | } | 228 | } |
| 228 | 229 | ||
| 229 | /// Checks out the tree at `tree_oid` to `worktree`. | 230 | /// Checks out the tree at `tree_oid` to `worktree`. |
| 230 | fn checkoutTree( | 231 | fn checkoutTree( |
| 231 | repository: *Repository, | 232 | repository: *Repository, |
| 233 | io: Io, | ||
| 232 | dir: std.fs.Dir, | 234 | dir: std.fs.Dir, |
| 233 | tree_oid: Oid, | 235 | tree_oid: Oid, |
| 234 | current_path: []const u8, | 236 | current_path: []const u8, |
| ... | @@ -253,10 +255,10 @@ pub const Repository = struct { | ... | @@ -253,10 +255,10 @@ pub const Repository = struct { |
| 253 | .directory => { | 255 | .directory => { |
| 254 | try dir.makeDir(entry.name); | 256 | try dir.makeDir(entry.name); |
| 255 | var subdir = try dir.openDir(entry.name, .{}); | 257 | var subdir = try dir.openDir(entry.name, .{}); |
| 256 | defer subdir.close(); | 258 | defer subdir.close(io); |
| 257 | const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name }); | 259 | const sub_path = try std.fs.path.join(repository.odb.allocator, &.{ current_path, entry.name }); |
| 258 | defer repository.odb.allocator.free(sub_path); | 260 | defer repository.odb.allocator.free(sub_path); |
| 259 | try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics); | 261 | try repository.checkoutTree(io, subdir, entry.oid, sub_path, diagnostics); |
| 260 | }, | 262 | }, |
| 261 | .file => { | 263 | .file => { |
| 262 | try repository.odb.seekOid(entry.oid); | 264 | try repository.odb.seekOid(entry.oid); |
| ... | @@ -271,7 +273,7 @@ pub const Repository = struct { | ... | @@ -271,7 +273,7 @@ pub const Repository = struct { |
| 271 | } }); | 273 | } }); |
| 272 | continue; | 274 | continue; |
| 273 | }; | 275 | }; |
| 274 | defer file.close(); | 276 | defer file.close(io); |
| 275 | try file.writeAll(file_object.data); | 277 | try file.writeAll(file_object.data); |
| 276 | }, | 278 | }, |
| 277 | .symlink => { | 279 | .symlink => { |
| ... | @@ -1583,14 +1585,14 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u | ... | @@ -1583,14 +1585,14 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u |
| 1583 | var git_dir = testing.tmpDir(.{}); | 1585 | var git_dir = testing.tmpDir(.{}); |
| 1584 | defer git_dir.cleanup(); | 1586 | defer git_dir.cleanup(); |
| 1585 | var pack_file = try git_dir.dir.createFile("testrepo.pack", .{ .read = true }); | 1587 | var pack_file = try git_dir.dir.createFile("testrepo.pack", .{ .read = true }); |
| 1586 | defer pack_file.close(); | 1588 | defer pack_file.close(io); |
| 1587 | try pack_file.writeAll(testrepo_pack); | 1589 | try pack_file.writeAll(testrepo_pack); |
| 1588 | 1590 | ||
| 1589 | var pack_file_buffer: [2000]u8 = undefined; | 1591 | var pack_file_buffer: [2000]u8 = undefined; |
| 1590 | var pack_file_reader = pack_file.reader(io, &pack_file_buffer); | 1592 | var pack_file_reader = pack_file.reader(io, &pack_file_buffer); |
| 1591 | 1593 | ||
| 1592 | var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); | 1594 | var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); |
| 1593 | defer index_file.close(); | 1595 | defer index_file.close(io); |
| 1594 | var index_file_buffer: [2000]u8 = undefined; | 1596 | var index_file_buffer: [2000]u8 = undefined; |
| 1595 | var index_file_writer = index_file.writer(&index_file_buffer); | 1597 | var index_file_writer = index_file.writer(&index_file_buffer); |
| 1596 | try indexPack(testing.allocator, format, &pack_file_reader, &index_file_writer); | 1598 | try indexPack(testing.allocator, format, &pack_file_reader, &index_file_writer); |
| ... | @@ -1621,7 +1623,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u | ... | @@ -1621,7 +1623,7 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u |
| 1621 | 1623 | ||
| 1622 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1624 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1623 | defer diagnostics.deinit(); | 1625 | defer diagnostics.deinit(); |
| 1624 | try repository.checkout(worktree.dir, commit_id, &diagnostics); | 1626 | try repository.checkout(io, worktree.dir, commit_id, &diagnostics); |
| 1625 | try testing.expect(diagnostics.errors.items.len == 0); | 1627 | try testing.expect(diagnostics.errors.items.len == 0); |
| 1626 | 1628 | ||
| 1627 | const expected_files: []const []const u8 = &.{ | 1629 | const expected_files: []const []const u8 = &.{ |
| ... | @@ -1713,20 +1715,20 @@ pub fn main() !void { | ... | @@ -1713,20 +1715,20 @@ pub fn main() !void { |
| 1713 | const format = std.meta.stringToEnum(Oid.Format, args[1]) orelse return error.InvalidFormat; | 1715 | const format = std.meta.stringToEnum(Oid.Format, args[1]) orelse return error.InvalidFormat; |
| 1714 | 1716 | ||
| 1715 | var pack_file = try std.fs.cwd().openFile(args[2], .{}); | 1717 | var pack_file = try std.fs.cwd().openFile(args[2], .{}); |
| 1716 | defer pack_file.close(); | 1718 | defer pack_file.close(io); |
| 1717 | var pack_file_buffer: [4096]u8 = undefined; | 1719 | var pack_file_buffer: [4096]u8 = undefined; |
| 1718 | var pack_file_reader = pack_file.reader(io, &pack_file_buffer); | 1720 | var pack_file_reader = pack_file.reader(io, &pack_file_buffer); |
| 1719 | 1721 | ||
| 1720 | const commit = try Oid.parse(format, args[3]); | 1722 | const commit = try Oid.parse(format, args[3]); |
| 1721 | var worktree = try std.fs.cwd().makeOpenPath(args[4], .{}); | 1723 | var worktree = try std.fs.cwd().makeOpenPath(args[4], .{}); |
| 1722 | defer worktree.close(); | 1724 | defer worktree.close(io); |
| 1723 | 1725 | ||
| 1724 | var git_dir = try worktree.makeOpenPath(".git", .{}); | 1726 | var git_dir = try worktree.makeOpenPath(".git", .{}); |
| 1725 | defer git_dir.close(); | 1727 | defer git_dir.close(io); |
| 1726 | 1728 | ||
| 1727 | std.debug.print("Starting index...\n", .{}); | 1729 | std.debug.print("Starting index...\n", .{}); |
| 1728 | var index_file = try git_dir.createFile("idx", .{ .read = true }); | 1730 | var index_file = try git_dir.createFile("idx", .{ .read = true }); |
| 1729 | defer index_file.close(); | 1731 | defer index_file.close(io); |
| 1730 | var index_file_buffer: [4096]u8 = undefined; | 1732 | var index_file_buffer: [4096]u8 = undefined; |
| 1731 | var index_file_writer = index_file.writer(&index_file_buffer); | 1733 | var index_file_writer = index_file.writer(&index_file_buffer); |
| 1732 | try indexPack(allocator, format, &pack_file_reader, &index_file_writer); | 1734 | try indexPack(allocator, format, &pack_file_reader, &index_file_writer); |
| ... | @@ -1738,7 +1740,7 @@ pub fn main() !void { | ... | @@ -1738,7 +1740,7 @@ pub fn main() !void { |
| 1738 | defer repository.deinit(); | 1740 | defer repository.deinit(); |
| 1739 | var diagnostics: Diagnostics = .{ .allocator = allocator }; | 1741 | var diagnostics: Diagnostics = .{ .allocator = allocator }; |
| 1740 | defer diagnostics.deinit(); | 1742 | defer diagnostics.deinit(); |
| 1741 | try repository.checkout(worktree, commit, &diagnostics); | 1743 | try repository.checkout(io, worktree, commit, &diagnostics); |
| 1742 | 1744 | ||
| 1743 | for (diagnostics.errors.items) |err| { | 1745 | for (diagnostics.errors.items) |err| { |
| 1744 | std.debug.print("Diagnostic: {}\n", .{err}); | 1746 | std.debug.print("Diagnostic: {}\n", .{err}); |
src/Zcu.zig+5-5| ... | @@ -1078,7 +1078,7 @@ pub const File = struct { | ... | @@ -1078,7 +1078,7 @@ pub const File = struct { |
| 1078 | const dir, const sub_path = file.path.openInfo(zcu.comp.dirs); | 1078 | const dir, const sub_path = file.path.openInfo(zcu.comp.dirs); |
| 1079 | break :f try dir.openFile(sub_path, .{}); | 1079 | break :f try dir.openFile(sub_path, .{}); |
| 1080 | }; | 1080 | }; |
| 1081 | defer f.close(); | 1081 | defer f.close(io); |
| 1082 | 1082 | ||
| 1083 | const stat = f.stat() catch |err| switch (err) { | 1083 | const stat = f.stat() catch |err| switch (err) { |
| 1084 | error.Streaming => { | 1084 | error.Streaming => { |
| ... | @@ -2813,8 +2813,8 @@ pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void { | ... | @@ -2813,8 +2813,8 @@ pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void { |
| 2813 | 2813 | ||
| 2814 | pub fn deinit(zcu: *Zcu) void { | 2814 | pub fn deinit(zcu: *Zcu) void { |
| 2815 | const comp = zcu.comp; | 2815 | const comp = zcu.comp; |
| 2816 | const gpa = comp.gpa; | ||
| 2817 | const io = comp.io; | 2816 | const io = comp.io; |
| 2817 | const gpa = zcu.gpa; | ||
| 2818 | { | 2818 | { |
| 2819 | const pt: Zcu.PerThread = .activate(zcu, .main); | 2819 | const pt: Zcu.PerThread = .activate(zcu, .main); |
| 2820 | defer pt.deactivate(); | 2820 | defer pt.deactivate(); |
| ... | @@ -2835,8 +2835,8 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2835,8 +2835,8 @@ pub fn deinit(zcu: *Zcu) void { |
| 2835 | } | 2835 | } |
| 2836 | zcu.embed_table.deinit(gpa); | 2836 | zcu.embed_table.deinit(gpa); |
| 2837 | 2837 | ||
| 2838 | zcu.local_zir_cache.handle.close(); | 2838 | zcu.local_zir_cache.handle.close(io); |
| 2839 | zcu.global_zir_cache.handle.close(); | 2839 | zcu.global_zir_cache.handle.close(io); |
| 2840 | 2840 | ||
| 2841 | for (zcu.failed_analysis.values()) |value| value.destroy(gpa); | 2841 | for (zcu.failed_analysis.values()) |value| value.destroy(gpa); |
| 2842 | for (zcu.failed_codegen.values()) |value| value.destroy(gpa); | 2842 | for (zcu.failed_codegen.values()) |value| value.destroy(gpa); |
| ... | @@ -2900,7 +2900,7 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2900,7 +2900,7 @@ pub fn deinit(zcu: *Zcu) void { |
| 2900 | 2900 | ||
| 2901 | if (zcu.resolved_references) |*r| r.deinit(gpa); | 2901 | if (zcu.resolved_references) |*r| r.deinit(gpa); |
| 2902 | 2902 | ||
| 2903 | if (zcu.comp.debugIncremental()) { | 2903 | if (comp.debugIncremental()) { |
| 2904 | zcu.incremental_debug_state.deinit(gpa); | 2904 | zcu.incremental_debug_state.deinit(gpa); |
| 2905 | } | 2905 | } |
| 2906 | } | 2906 | } |
src/Zcu/PerThread.zig+3-3| ... | @@ -96,7 +96,7 @@ pub fn updateFile( | ... | @@ -96,7 +96,7 @@ pub fn updateFile( |
| 96 | const dir, const sub_path = file.path.openInfo(comp.dirs); | 96 | const dir, const sub_path = file.path.openInfo(comp.dirs); |
| 97 | break :f try dir.openFile(sub_path, .{}); | 97 | break :f try dir.openFile(sub_path, .{}); |
| 98 | }; | 98 | }; |
| 99 | defer source_file.close(); | 99 | defer source_file.close(io); |
| 100 | 100 | ||
| 101 | const stat = try source_file.stat(); | 101 | const stat = try source_file.stat(); |
| 102 | 102 | ||
| ... | @@ -215,7 +215,7 @@ pub fn updateFile( | ... | @@ -215,7 +215,7 @@ pub fn updateFile( |
| 215 | else => |e| return e, // Retryable errors are handled at callsite. | 215 | else => |e| return e, // Retryable errors are handled at callsite. |
| 216 | }; | 216 | }; |
| 217 | }; | 217 | }; |
| 218 | defer cache_file.close(); | 218 | defer cache_file.close(io); |
| 219 | 219 | ||
| 220 | // Under `--time-report`, ignore cache hits; do the work anyway for those juicy numbers. | 220 | // Under `--time-report`, ignore cache hits; do the work anyway for those juicy numbers. |
| 221 | const ignore_hit = comp.time_report != null; | 221 | const ignore_hit = comp.time_report != null; |
| ... | @@ -2468,7 +2468,7 @@ fn updateEmbedFileInner( | ... | @@ -2468,7 +2468,7 @@ fn updateEmbedFileInner( |
| 2468 | const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs); | 2468 | const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs); |
| 2469 | break :f try dir.openFile(sub_path, .{}); | 2469 | break :f try dir.openFile(sub_path, .{}); |
| 2470 | }; | 2470 | }; |
| 2471 | defer file.close(); | 2471 | defer file.close(io); |
| 2472 | 2472 | ||
| 2473 | const stat: Cache.File.Stat = .fromFs(try file.stat()); | 2473 | const stat: Cache.File.Stat = .fromFs(try file.stat()); |
| 2474 | 2474 |
src/codegen/llvm.zig+3-2| ... | @@ -799,6 +799,7 @@ pub const Object = struct { | ... | @@ -799,6 +799,7 @@ pub const Object = struct { |
| 799 | pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ LinkFailure, OutOfMemory }!void { | 799 | pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ LinkFailure, OutOfMemory }!void { |
| 800 | const zcu = pt.zcu; | 800 | const zcu = pt.zcu; |
| 801 | const comp = zcu.comp; | 801 | const comp = zcu.comp; |
| 802 | const io = comp.io; | ||
| 802 | const diags = &comp.link_diags; | 803 | const diags = &comp.link_diags; |
| 803 | 804 | ||
| 804 | { | 805 | { |
| ... | @@ -979,7 +980,7 @@ pub const Object = struct { | ... | @@ -979,7 +980,7 @@ pub const Object = struct { |
| 979 | if (options.pre_bc_path) |path| { | 980 | if (options.pre_bc_path) |path| { |
| 980 | var file = std.fs.cwd().createFile(path, .{}) catch |err| | 981 | var file = std.fs.cwd().createFile(path, .{}) catch |err| |
| 981 | return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); | 982 | return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); |
| 982 | defer file.close(); | 983 | defer file.close(io); |
| 983 | 984 | ||
| 984 | const ptr: [*]const u8 = @ptrCast(bitcode.ptr); | 985 | const ptr: [*]const u8 = @ptrCast(bitcode.ptr); |
| 985 | file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| | 986 | file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| |
| ... | @@ -992,7 +993,7 @@ pub const Object = struct { | ... | @@ -992,7 +993,7 @@ pub const Object = struct { |
| 992 | if (options.post_bc_path) |path| { | 993 | if (options.post_bc_path) |path| { |
| 993 | var file = std.fs.cwd().createFile(path, .{}) catch |err| | 994 | var file = std.fs.cwd().createFile(path, .{}) catch |err| |
| 994 | return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); | 995 | return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); |
| 995 | defer file.close(); | 996 | defer file.close(io); |
| 996 | 997 | ||
| 997 | const ptr: [*]const u8 = @ptrCast(bitcode.ptr); | 998 | const ptr: [*]const u8 = @ptrCast(bitcode.ptr); |
| 998 | file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| | 999 | file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| |
src/fmt.zig+6-4| ... | @@ -187,7 +187,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! | ... | @@ -187,7 +187,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 187 | // On Windows, statFile does not work for directories | 187 | // On Windows, statFile does not work for directories |
| 188 | error.IsDir => dir: { | 188 | error.IsDir => dir: { |
| 189 | var dir = try fs.cwd().openDir(file_path, .{}); | 189 | var dir = try fs.cwd().openDir(file_path, .{}); |
| 190 | defer dir.close(); | 190 | defer dir.close(io); |
| 191 | break :dir try dir.stat(); | 191 | break :dir try dir.stat(); |
| 192 | }, | 192 | }, |
| 193 | else => |e| return e, | 193 | else => |e| return e, |
| ... | @@ -222,8 +222,10 @@ fn fmtPathDir( | ... | @@ -222,8 +222,10 @@ fn fmtPathDir( |
| 222 | parent_dir: fs.Dir, | 222 | parent_dir: fs.Dir, |
| 223 | parent_sub_path: []const u8, | 223 | parent_sub_path: []const u8, |
| 224 | ) !void { | 224 | ) !void { |
| 225 | const io = fmt.io; | ||
| 226 | |||
| 225 | var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true }); | 227 | var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true }); |
| 226 | defer dir.close(); | 228 | defer dir.close(io); |
| 227 | 229 | ||
| 228 | const stat = try dir.stat(); | 230 | const stat = try dir.stat(); |
| 229 | if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; | 231 | if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; |
| ... | @@ -262,7 +264,7 @@ fn fmtPathFile( | ... | @@ -262,7 +264,7 @@ fn fmtPathFile( |
| 262 | 264 | ||
| 263 | const source_file = try dir.openFile(sub_path, .{}); | 265 | const source_file = try dir.openFile(sub_path, .{}); |
| 264 | var file_closed = false; | 266 | var file_closed = false; |
| 265 | errdefer if (!file_closed) source_file.close(); | 267 | errdefer if (!file_closed) source_file.close(io); |
| 266 | 268 | ||
| 267 | const stat = try source_file.stat(); | 269 | const stat = try source_file.stat(); |
| 268 | 270 | ||
| ... | @@ -280,7 +282,7 @@ fn fmtPathFile( | ... | @@ -280,7 +282,7 @@ fn fmtPathFile( |
| 280 | }; | 282 | }; |
| 281 | defer gpa.free(source_code); | 283 | defer gpa.free(source_code); |
| 282 | 284 | ||
| 283 | source_file.close(); | 285 | source_file.close(io); |
| 284 | file_closed = true; | 286 | file_closed = true; |
| 285 | 287 | ||
| 286 | // Add to set after no longer possible to get error.IsDir. | 288 | // Add to set after no longer possible to get error.IsDir. |
src/introspect.zig+16-12| ... | @@ -1,18 +1,21 @@ | ... | @@ -1,18 +1,21 @@ |
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const build_options = @import("build_options"); | ||
| 3 | |||
| 4 | const std = @import("std"); | ||
| 5 | const Io = std.Io; | ||
| 3 | const mem = std.mem; | 6 | const mem = std.mem; |
| 4 | const Allocator = mem.Allocator; | 7 | const Allocator = std.mem.Allocator; |
| 5 | const os = std.os; | 8 | const os = std.os; |
| 6 | const fs = std.fs; | 9 | const fs = std.fs; |
| 7 | const Cache = std.Build.Cache; | 10 | const Cache = std.Build.Cache; |
| 11 | |||
| 8 | const Compilation = @import("Compilation.zig"); | 12 | const Compilation = @import("Compilation.zig"); |
| 9 | const Package = @import("Package.zig"); | 13 | const Package = @import("Package.zig"); |
| 10 | const build_options = @import("build_options"); | ||
| 11 | 14 | ||
| 12 | /// Returns the sub_path that worked, or `null` if none did. | 15 | /// Returns the sub_path that worked, or `null` if none did. |
| 13 | /// The path of the returned Directory is relative to `base`. | 16 | /// The path of the returned Directory is relative to `base`. |
| 14 | /// The handle of the returned Directory is open. | 17 | /// The handle of the returned Directory is open. |
| 15 | fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory { | 18 | fn testZigInstallPrefix(io: Io, base_dir: Io.Dir) ?Cache.Directory { |
| 16 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; | 19 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; |
| 17 | 20 | ||
| 18 | zig_dir: { | 21 | zig_dir: { |
| ... | @@ -20,31 +23,31 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory { | ... | @@ -20,31 +23,31 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory { |
| 20 | const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; | 23 | const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; |
| 21 | var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir; | 24 | var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir; |
| 22 | const file = test_zig_dir.openFile(test_index_file, .{}) catch { | 25 | const file = test_zig_dir.openFile(test_index_file, .{}) catch { |
| 23 | test_zig_dir.close(); | 26 | test_zig_dir.close(io); |
| 24 | break :zig_dir; | 27 | break :zig_dir; |
| 25 | }; | 28 | }; |
| 26 | file.close(); | 29 | file.close(io); |
| 27 | return .{ .handle = test_zig_dir, .path = lib_zig }; | 30 | return .{ .handle = test_zig_dir, .path = lib_zig }; |
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | // Try lib/std/std.zig | 33 | // Try lib/std/std.zig |
| 31 | var test_zig_dir = base_dir.openDir("lib", .{}) catch return null; | 34 | var test_zig_dir = base_dir.openDir("lib", .{}) catch return null; |
| 32 | const file = test_zig_dir.openFile(test_index_file, .{}) catch { | 35 | const file = test_zig_dir.openFile(test_index_file, .{}) catch { |
| 33 | test_zig_dir.close(); | 36 | test_zig_dir.close(io); |
| 34 | return null; | 37 | return null; |
| 35 | }; | 38 | }; |
| 36 | file.close(); | 39 | file.close(io); |
| 37 | return .{ .handle = test_zig_dir, .path = "lib" }; | 40 | return .{ .handle = test_zig_dir, .path = "lib" }; |
| 38 | } | 41 | } |
| 39 | 42 | ||
| 40 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 43 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. |
| 41 | pub fn findZigLibDir(gpa: Allocator) !Cache.Directory { | 44 | pub fn findZigLibDir(gpa: Allocator, io: Io) !Cache.Directory { |
| 42 | const cwd_path = try getResolvedCwd(gpa); | 45 | const cwd_path = try getResolvedCwd(gpa); |
| 43 | defer gpa.free(cwd_path); | 46 | defer gpa.free(cwd_path); |
| 44 | const self_exe_path = try fs.selfExePathAlloc(gpa); | 47 | const self_exe_path = try fs.selfExePathAlloc(gpa); |
| 45 | defer gpa.free(self_exe_path); | 48 | defer gpa.free(self_exe_path); |
| 46 | 49 | ||
| 47 | return findZigLibDirFromSelfExe(gpa, cwd_path, self_exe_path); | 50 | return findZigLibDirFromSelfExe(gpa, io, cwd_path, self_exe_path); |
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | /// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This | 53 | /// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This |
| ... | @@ -73,6 +76,7 @@ pub fn getResolvedCwd(gpa: Allocator) error{ | ... | @@ -73,6 +76,7 @@ pub fn getResolvedCwd(gpa: Allocator) error{ |
| 73 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 76 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. |
| 74 | pub fn findZigLibDirFromSelfExe( | 77 | pub fn findZigLibDirFromSelfExe( |
| 75 | allocator: Allocator, | 78 | allocator: Allocator, |
| 79 | io: Io, | ||
| 76 | /// The return value of `getResolvedCwd`. | 80 | /// The return value of `getResolvedCwd`. |
| 77 | /// Passed as an argument to avoid pointlessly repeating the call. | 81 | /// Passed as an argument to avoid pointlessly repeating the call. |
| 78 | cwd_path: []const u8, | 82 | cwd_path: []const u8, |
| ... | @@ -82,9 +86,9 @@ pub fn findZigLibDirFromSelfExe( | ... | @@ -82,9 +86,9 @@ pub fn findZigLibDirFromSelfExe( |
| 82 | var cur_path: []const u8 = self_exe_path; | 86 | var cur_path: []const u8 = self_exe_path; |
| 83 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { | 87 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { |
| 84 | var base_dir = cwd.openDir(dirname, .{}) catch continue; | 88 | var base_dir = cwd.openDir(dirname, .{}) catch continue; |
| 85 | defer base_dir.close(); | 89 | defer base_dir.close(io); |
| 86 | 90 | ||
| 87 | const sub_directory = testZigInstallPrefix(base_dir) orelse continue; | 91 | const sub_directory = testZigInstallPrefix(io, base_dir) orelse continue; |
| 88 | const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? }); | 92 | const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? }); |
| 89 | defer allocator.free(p); | 93 | defer allocator.free(p); |
| 90 | 94 |
src/libs/freebsd.zig+2-2| ... | @@ -449,7 +449,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -449,7 +449,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 449 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 449 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 450 | cache.addPrefix(comp.dirs.zig_lib); | 450 | cache.addPrefix(comp.dirs.zig_lib); |
| 451 | cache.addPrefix(comp.dirs.global_cache); | 451 | cache.addPrefix(comp.dirs.global_cache); |
| 452 | defer cache.manifest_dir.close(); | 452 | defer cache.manifest_dir.close(io); |
| 453 | 453 | ||
| 454 | var man = cache.obtain(); | 454 | var man = cache.obtain(); |
| 455 | defer man.deinit(); | 455 | defer man.deinit(); |
| ... | @@ -480,7 +480,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -480,7 +480,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 480 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), | 480 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 481 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), | 481 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 482 | }; | 482 | }; |
| 483 | defer o_directory.handle.close(); | 483 | defer o_directory.handle.close(io); |
| 484 | 484 | ||
| 485 | const abilists_contents = man.files.keys()[abilists_index].contents.?; | 485 | const abilists_contents = man.files.keys()[abilists_index].contents.?; |
| 486 | const metadata = try loadMetaData(gpa, abilists_contents); | 486 | const metadata = try loadMetaData(gpa, abilists_contents); |
src/libs/glibc.zig+2-2| ... | @@ -684,7 +684,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -684,7 +684,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 684 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 684 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 685 | cache.addPrefix(comp.dirs.zig_lib); | 685 | cache.addPrefix(comp.dirs.zig_lib); |
| 686 | cache.addPrefix(comp.dirs.global_cache); | 686 | cache.addPrefix(comp.dirs.global_cache); |
| 687 | defer cache.manifest_dir.close(); | 687 | defer cache.manifest_dir.close(io); |
| 688 | 688 | ||
| 689 | var man = cache.obtain(); | 689 | var man = cache.obtain(); |
| 690 | defer man.deinit(); | 690 | defer man.deinit(); |
| ... | @@ -715,7 +715,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -715,7 +715,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 715 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), | 715 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 716 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), | 716 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 717 | }; | 717 | }; |
| 718 | defer o_directory.handle.close(); | 718 | defer o_directory.handle.close(io); |
| 719 | 719 | ||
| 720 | const abilists_contents = man.files.keys()[abilists_index].contents.?; | 720 | const abilists_contents = man.files.keys()[abilists_index].contents.?; |
| 721 | const metadata = try loadMetaData(gpa, abilists_contents); | 721 | const metadata = try loadMetaData(gpa, abilists_contents); |
src/libs/mingw.zig+3-3| ... | @@ -262,7 +262,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -262,7 +262,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 262 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); | 262 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); |
| 263 | cache.addPrefix(comp.dirs.zig_lib); | 263 | cache.addPrefix(comp.dirs.zig_lib); |
| 264 | cache.addPrefix(comp.dirs.global_cache); | 264 | cache.addPrefix(comp.dirs.global_cache); |
| 265 | defer cache.manifest_dir.close(); | 265 | defer cache.manifest_dir.close(io); |
| 266 | 266 | ||
| 267 | cache.hash.addBytes(build_options.version); | 267 | cache.hash.addBytes(build_options.version); |
| 268 | cache.hash.addOptionalBytes(comp.dirs.zig_lib.path); | 268 | cache.hash.addOptionalBytes(comp.dirs.zig_lib.path); |
| ... | @@ -297,7 +297,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -297,7 +297,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 297 | const digest = man.final(); | 297 | const digest = man.final(); |
| 298 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 298 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 299 | var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}); | 299 | var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 300 | defer o_dir.close(); | 300 | defer o_dir.close(io); |
| 301 | 301 | ||
| 302 | const aro = @import("aro"); | 302 | const aro = @import("aro"); |
| 303 | var diagnostics: aro.Diagnostics = .{ | 303 | var diagnostics: aro.Diagnostics = .{ |
| ... | @@ -377,7 +377,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -377,7 +377,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 377 | 377 | ||
| 378 | { | 378 | { |
| 379 | const lib_final_file = try o_dir.createFile(final_lib_basename, .{ .truncate = true }); | 379 | const lib_final_file = try o_dir.createFile(final_lib_basename, .{ .truncate = true }); |
| 380 | defer lib_final_file.close(); | 380 | defer lib_final_file.close(io); |
| 381 | var buffer: [1024]u8 = undefined; | 381 | var buffer: [1024]u8 = undefined; |
| 382 | var file_writer = lib_final_file.writer(&buffer); | 382 | var file_writer = lib_final_file.writer(&buffer); |
| 383 | try implib.writeCoffArchive(gpa, &file_writer.interface, members); | 383 | try implib.writeCoffArchive(gpa, &file_writer.interface, members); |
src/libs/netbsd.zig+2-2| ... | @@ -390,7 +390,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -390,7 +390,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 390 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 390 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 391 | cache.addPrefix(comp.dirs.zig_lib); | 391 | cache.addPrefix(comp.dirs.zig_lib); |
| 392 | cache.addPrefix(comp.dirs.global_cache); | 392 | cache.addPrefix(comp.dirs.global_cache); |
| 393 | defer cache.manifest_dir.close(); | 393 | defer cache.manifest_dir.close(io); |
| 394 | 394 | ||
| 395 | var man = cache.obtain(); | 395 | var man = cache.obtain(); |
| 396 | defer man.deinit(); | 396 | defer man.deinit(); |
| ... | @@ -421,7 +421,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -421,7 +421,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 421 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), | 421 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 422 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), | 422 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 423 | }; | 423 | }; |
| 424 | defer o_directory.handle.close(); | 424 | defer o_directory.handle.close(io); |
| 425 | 425 | ||
| 426 | const abilists_contents = man.files.keys()[abilists_index].contents.?; | 426 | const abilists_contents = man.files.keys()[abilists_index].contents.?; |
| 427 | const metadata = try loadMetaData(gpa, abilists_contents); | 427 | const metadata = try loadMetaData(gpa, abilists_contents); |
src/link.zig+49-34| ... | @@ -687,7 +687,7 @@ pub const File = struct { | ... | @@ -687,7 +687,7 @@ pub const File = struct { |
| 687 | .lld => assert(base.file == null), | 687 | .lld => assert(base.file == null), |
| 688 | .elf => if (base.file) |f| { | 688 | .elf => if (base.file) |f| { |
| 689 | dev.check(.elf_linker); | 689 | dev.check(.elf_linker); |
| 690 | f.close(); | 690 | f.close(io); |
| 691 | base.file = null; | 691 | base.file = null; |
| 692 | 692 | ||
| 693 | if (base.child_pid) |pid| { | 693 | if (base.child_pid) |pid| { |
| ... | @@ -701,7 +701,7 @@ pub const File = struct { | ... | @@ -701,7 +701,7 @@ pub const File = struct { |
| 701 | }, | 701 | }, |
| 702 | .macho, .wasm => if (base.file) |f| { | 702 | .macho, .wasm => if (base.file) |f| { |
| 703 | dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker }); | 703 | dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker }); |
| 704 | f.close(); | 704 | f.close(io); |
| 705 | base.file = null; | 705 | base.file = null; |
| 706 | 706 | ||
| 707 | if (base.child_pid) |pid| { | 707 | if (base.child_pid) |pid| { |
| ... | @@ -866,8 +866,9 @@ pub const File = struct { | ... | @@ -866,8 +866,9 @@ pub const File = struct { |
| 866 | } | 866 | } |
| 867 | 867 | ||
| 868 | pub fn destroy(base: *File) void { | 868 | pub fn destroy(base: *File) void { |
| 869 | const io = base.comp.io; | ||
| 869 | base.releaseLock(); | 870 | base.releaseLock(); |
| 870 | if (base.file) |f| f.close(); | 871 | if (base.file) |f| f.close(io); |
| 871 | switch (base.tag) { | 872 | switch (base.tag) { |
| 872 | .plan9 => unreachable, | 873 | .plan9 => unreachable, |
| 873 | inline else => |tag| { | 874 | inline else => |tag| { |
| ... | @@ -1060,9 +1061,10 @@ pub const File = struct { | ... | @@ -1060,9 +1061,10 @@ pub const File = struct { |
| 1060 | /// Opens a path as an object file and parses it into the linker. | 1061 | /// Opens a path as an object file and parses it into the linker. |
| 1061 | fn openLoadObject(base: *File, path: Path) anyerror!void { | 1062 | fn openLoadObject(base: *File, path: Path) anyerror!void { |
| 1062 | if (base.tag == .lld) return; | 1063 | if (base.tag == .lld) return; |
| 1064 | const io = base.comp.io; | ||
| 1063 | const diags = &base.comp.link_diags; | 1065 | const diags = &base.comp.link_diags; |
| 1064 | const input = try openObjectInput(diags, path); | 1066 | const input = try openObjectInput(io, diags, path); |
| 1065 | errdefer input.object.file.close(); | 1067 | errdefer input.object.file.close(io); |
| 1066 | try loadInput(base, input); | 1068 | try loadInput(base, input); |
| 1067 | } | 1069 | } |
| 1068 | 1070 | ||
| ... | @@ -1070,21 +1072,22 @@ pub const File = struct { | ... | @@ -1070,21 +1072,22 @@ pub const File = struct { |
| 1070 | /// If `query` is non-null, allows GNU ld scripts. | 1072 | /// If `query` is non-null, allows GNU ld scripts. |
| 1071 | fn openLoadArchive(base: *File, path: Path, opt_query: ?UnresolvedInput.Query) anyerror!void { | 1073 | fn openLoadArchive(base: *File, path: Path, opt_query: ?UnresolvedInput.Query) anyerror!void { |
| 1072 | if (base.tag == .lld) return; | 1074 | if (base.tag == .lld) return; |
| 1075 | const io = base.comp.io; | ||
| 1073 | if (opt_query) |query| { | 1076 | if (opt_query) |query| { |
| 1074 | const archive = try openObject(path, query.must_link, query.hidden); | 1077 | const archive = try openObject(io, path, query.must_link, query.hidden); |
| 1075 | errdefer archive.file.close(); | 1078 | errdefer archive.file.close(io); |
| 1076 | loadInput(base, .{ .archive = archive }) catch |err| switch (err) { | 1079 | loadInput(base, .{ .archive = archive }) catch |err| switch (err) { |
| 1077 | error.BadMagic, error.UnexpectedEndOfFile => { | 1080 | error.BadMagic, error.UnexpectedEndOfFile => { |
| 1078 | if (base.tag != .elf and base.tag != .elf2) return err; | 1081 | if (base.tag != .elf and base.tag != .elf2) return err; |
| 1079 | try loadGnuLdScript(base, path, query, archive.file); | 1082 | try loadGnuLdScript(base, path, query, archive.file); |
| 1080 | archive.file.close(); | 1083 | archive.file.close(io); |
| 1081 | return; | 1084 | return; |
| 1082 | }, | 1085 | }, |
| 1083 | else => return err, | 1086 | else => return err, |
| 1084 | }; | 1087 | }; |
| 1085 | } else { | 1088 | } else { |
| 1086 | const archive = try openObject(path, false, false); | 1089 | const archive = try openObject(io, path, false, false); |
| 1087 | errdefer archive.file.close(); | 1090 | errdefer archive.file.close(io); |
| 1088 | try loadInput(base, .{ .archive = archive }); | 1091 | try loadInput(base, .{ .archive = archive }); |
| 1089 | } | 1092 | } |
| 1090 | } | 1093 | } |
| ... | @@ -1093,13 +1096,14 @@ pub const File = struct { | ... | @@ -1093,13 +1096,14 @@ pub const File = struct { |
| 1093 | /// Handles GNU ld scripts. | 1096 | /// Handles GNU ld scripts. |
| 1094 | fn openLoadDso(base: *File, path: Path, query: UnresolvedInput.Query) anyerror!void { | 1097 | fn openLoadDso(base: *File, path: Path, query: UnresolvedInput.Query) anyerror!void { |
| 1095 | if (base.tag == .lld) return; | 1098 | if (base.tag == .lld) return; |
| 1096 | const dso = try openDso(path, query.needed, query.weak, query.reexport); | 1099 | const io = base.comp.io; |
| 1097 | errdefer dso.file.close(); | 1100 | const dso = try openDso(io, path, query.needed, query.weak, query.reexport); |
| 1101 | errdefer dso.file.close(io); | ||
| 1098 | loadInput(base, .{ .dso = dso }) catch |err| switch (err) { | 1102 | loadInput(base, .{ .dso = dso }) catch |err| switch (err) { |
| 1099 | error.BadMagic, error.UnexpectedEndOfFile => { | 1103 | error.BadMagic, error.UnexpectedEndOfFile => { |
| 1100 | if (base.tag != .elf and base.tag != .elf2) return err; | 1104 | if (base.tag != .elf and base.tag != .elf2) return err; |
| 1101 | try loadGnuLdScript(base, path, query, dso.file); | 1105 | try loadGnuLdScript(base, path, query, dso.file); |
| 1102 | dso.file.close(); | 1106 | dso.file.close(io); |
| 1103 | return; | 1107 | return; |
| 1104 | }, | 1108 | }, |
| 1105 | else => return err, | 1109 | else => return err, |
| ... | @@ -1735,6 +1739,7 @@ pub fn hashInputs(man: *Cache.Manifest, link_inputs: []const Input) !void { | ... | @@ -1735,6 +1739,7 @@ pub fn hashInputs(man: *Cache.Manifest, link_inputs: []const Input) !void { |
| 1735 | pub fn resolveInputs( | 1739 | pub fn resolveInputs( |
| 1736 | gpa: Allocator, | 1740 | gpa: Allocator, |
| 1737 | arena: Allocator, | 1741 | arena: Allocator, |
| 1742 | io: Io, | ||
| 1738 | target: *const std.Target, | 1743 | target: *const std.Target, |
| 1739 | /// This function mutates this array but does not take ownership. | 1744 | /// This function mutates this array but does not take ownership. |
| 1740 | /// Allocated with `gpa`. | 1745 | /// Allocated with `gpa`. |
| ... | @@ -1784,6 +1789,7 @@ pub fn resolveInputs( | ... | @@ -1784,6 +1789,7 @@ pub fn resolveInputs( |
| 1784 | for (lib_directories) |lib_directory| switch (try resolveLibInput( | 1789 | for (lib_directories) |lib_directory| switch (try resolveLibInput( |
| 1785 | gpa, | 1790 | gpa, |
| 1786 | arena, | 1791 | arena, |
| 1792 | io, | ||
| 1787 | unresolved_inputs, | 1793 | unresolved_inputs, |
| 1788 | resolved_inputs, | 1794 | resolved_inputs, |
| 1789 | &checked_paths, | 1795 | &checked_paths, |
| ... | @@ -1810,6 +1816,7 @@ pub fn resolveInputs( | ... | @@ -1810,6 +1816,7 @@ pub fn resolveInputs( |
| 1810 | for (lib_directories) |lib_directory| switch (try resolveLibInput( | 1816 | for (lib_directories) |lib_directory| switch (try resolveLibInput( |
| 1811 | gpa, | 1817 | gpa, |
| 1812 | arena, | 1818 | arena, |
| 1819 | io, | ||
| 1813 | unresolved_inputs, | 1820 | unresolved_inputs, |
| 1814 | resolved_inputs, | 1821 | resolved_inputs, |
| 1815 | &checked_paths, | 1822 | &checked_paths, |
| ... | @@ -1837,6 +1844,7 @@ pub fn resolveInputs( | ... | @@ -1837,6 +1844,7 @@ pub fn resolveInputs( |
| 1837 | switch (try resolveLibInput( | 1844 | switch (try resolveLibInput( |
| 1838 | gpa, | 1845 | gpa, |
| 1839 | arena, | 1846 | arena, |
| 1847 | io, | ||
| 1840 | unresolved_inputs, | 1848 | unresolved_inputs, |
| 1841 | resolved_inputs, | 1849 | resolved_inputs, |
| 1842 | &checked_paths, | 1850 | &checked_paths, |
| ... | @@ -1855,6 +1863,7 @@ pub fn resolveInputs( | ... | @@ -1855,6 +1863,7 @@ pub fn resolveInputs( |
| 1855 | switch (try resolveLibInput( | 1863 | switch (try resolveLibInput( |
| 1856 | gpa, | 1864 | gpa, |
| 1857 | arena, | 1865 | arena, |
| 1866 | io, | ||
| 1858 | unresolved_inputs, | 1867 | unresolved_inputs, |
| 1859 | resolved_inputs, | 1868 | resolved_inputs, |
| 1860 | &checked_paths, | 1869 | &checked_paths, |
| ... | @@ -1886,6 +1895,7 @@ pub fn resolveInputs( | ... | @@ -1886,6 +1895,7 @@ pub fn resolveInputs( |
| 1886 | if (try resolvePathInput( | 1895 | if (try resolvePathInput( |
| 1887 | gpa, | 1896 | gpa, |
| 1888 | arena, | 1897 | arena, |
| 1898 | io, | ||
| 1889 | unresolved_inputs, | 1899 | unresolved_inputs, |
| 1890 | resolved_inputs, | 1900 | resolved_inputs, |
| 1891 | &ld_script_bytes, | 1901 | &ld_script_bytes, |
| ... | @@ -1903,6 +1913,7 @@ pub fn resolveInputs( | ... | @@ -1903,6 +1913,7 @@ pub fn resolveInputs( |
| 1903 | switch ((try resolvePathInput( | 1913 | switch ((try resolvePathInput( |
| 1904 | gpa, | 1914 | gpa, |
| 1905 | arena, | 1915 | arena, |
| 1916 | io, | ||
| 1906 | unresolved_inputs, | 1917 | unresolved_inputs, |
| 1907 | resolved_inputs, | 1918 | resolved_inputs, |
| 1908 | &ld_script_bytes, | 1919 | &ld_script_bytes, |
| ... | @@ -1930,6 +1941,7 @@ pub fn resolveInputs( | ... | @@ -1930,6 +1941,7 @@ pub fn resolveInputs( |
| 1930 | if (try resolvePathInput( | 1941 | if (try resolvePathInput( |
| 1931 | gpa, | 1942 | gpa, |
| 1932 | arena, | 1943 | arena, |
| 1944 | io, | ||
| 1933 | unresolved_inputs, | 1945 | unresolved_inputs, |
| 1934 | resolved_inputs, | 1946 | resolved_inputs, |
| 1935 | &ld_script_bytes, | 1947 | &ld_script_bytes, |
| ... | @@ -1969,6 +1981,7 @@ const fatal = std.process.fatal; | ... | @@ -1969,6 +1981,7 @@ const fatal = std.process.fatal; |
| 1969 | fn resolveLibInput( | 1981 | fn resolveLibInput( |
| 1970 | gpa: Allocator, | 1982 | gpa: Allocator, |
| 1971 | arena: Allocator, | 1983 | arena: Allocator, |
| 1984 | io: Io, | ||
| 1972 | /// Allocated via `gpa`. | 1985 | /// Allocated via `gpa`. |
| 1973 | unresolved_inputs: *std.ArrayList(UnresolvedInput), | 1986 | unresolved_inputs: *std.ArrayList(UnresolvedInput), |
| 1974 | /// Allocated via `gpa`. | 1987 | /// Allocated via `gpa`. |
| ... | @@ -1998,7 +2011,7 @@ fn resolveLibInput( | ... | @@ -1998,7 +2011,7 @@ fn resolveLibInput( |
| 1998 | error.FileNotFound => break :tbd, | 2011 | error.FileNotFound => break :tbd, |
| 1999 | else => |e| fatal("unable to search for tbd library '{f}': {s}", .{ test_path, @errorName(e) }), | 2012 | else => |e| fatal("unable to search for tbd library '{f}': {s}", .{ test_path, @errorName(e) }), |
| 2000 | }; | 2013 | }; |
| 2001 | errdefer file.close(); | 2014 | errdefer file.close(io); |
| 2002 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); | 2015 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); |
| 2003 | } | 2016 | } |
| 2004 | 2017 | ||
| ... | @@ -2013,7 +2026,7 @@ fn resolveLibInput( | ... | @@ -2013,7 +2026,7 @@ fn resolveLibInput( |
| 2013 | }), | 2026 | }), |
| 2014 | }; | 2027 | }; |
| 2015 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | 2028 | try checked_paths.print(gpa, "\n {f}", .{test_path}); |
| 2016 | switch (try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, .{ | 2029 | switch (try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, .{ |
| 2017 | .path = test_path, | 2030 | .path = test_path, |
| 2018 | .query = name_query.query, | 2031 | .query = name_query.query, |
| 2019 | }, link_mode, color)) { | 2032 | }, link_mode, color)) { |
| ... | @@ -2036,7 +2049,7 @@ fn resolveLibInput( | ... | @@ -2036,7 +2049,7 @@ fn resolveLibInput( |
| 2036 | test_path, @errorName(e), | 2049 | test_path, @errorName(e), |
| 2037 | }), | 2050 | }), |
| 2038 | }; | 2051 | }; |
| 2039 | errdefer file.close(); | 2052 | errdefer file.close(io); |
| 2040 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); | 2053 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); |
| 2041 | } | 2054 | } |
| 2042 | 2055 | ||
| ... | @@ -2052,7 +2065,7 @@ fn resolveLibInput( | ... | @@ -2052,7 +2065,7 @@ fn resolveLibInput( |
| 2052 | error.FileNotFound => break :mingw, | 2065 | error.FileNotFound => break :mingw, |
| 2053 | else => |e| fatal("unable to search for static library '{f}': {s}", .{ test_path, @errorName(e) }), | 2066 | else => |e| fatal("unable to search for static library '{f}': {s}", .{ test_path, @errorName(e) }), |
| 2054 | }; | 2067 | }; |
| 2055 | errdefer file.close(); | 2068 | errdefer file.close(io); |
| 2056 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); | 2069 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); |
| 2057 | } | 2070 | } |
| 2058 | 2071 | ||
| ... | @@ -2087,6 +2100,7 @@ fn finishResolveLibInput( | ... | @@ -2087,6 +2100,7 @@ fn finishResolveLibInput( |
| 2087 | fn resolvePathInput( | 2100 | fn resolvePathInput( |
| 2088 | gpa: Allocator, | 2101 | gpa: Allocator, |
| 2089 | arena: Allocator, | 2102 | arena: Allocator, |
| 2103 | io: Io, | ||
| 2090 | /// Allocated with `gpa`. | 2104 | /// Allocated with `gpa`. |
| 2091 | unresolved_inputs: *std.ArrayList(UnresolvedInput), | 2105 | unresolved_inputs: *std.ArrayList(UnresolvedInput), |
| 2092 | /// Allocated with `gpa`. | 2106 | /// Allocated with `gpa`. |
| ... | @@ -2098,12 +2112,12 @@ fn resolvePathInput( | ... | @@ -2098,12 +2112,12 @@ fn resolvePathInput( |
| 2098 | color: std.zig.Color, | 2112 | color: std.zig.Color, |
| 2099 | ) Allocator.Error!?ResolveLibInputResult { | 2113 | ) Allocator.Error!?ResolveLibInputResult { |
| 2100 | switch (Compilation.classifyFileExt(pq.path.sub_path)) { | 2114 | switch (Compilation.classifyFileExt(pq.path.sub_path)) { |
| 2101 | .static_library => return try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .static, color), | 2115 | .static_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .static, color), |
| 2102 | .shared_library => return try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color), | 2116 | .shared_library => return try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color), |
| 2103 | .object => { | 2117 | .object => { |
| 2104 | var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| | 2118 | var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| |
| 2105 | fatal("failed to open object {f}: {s}", .{ pq.path, @errorName(err) }); | 2119 | fatal("failed to open object {f}: {s}", .{ pq.path, @errorName(err) }); |
| 2106 | errdefer file.close(); | 2120 | errdefer file.close(io); |
| 2107 | try resolved_inputs.append(gpa, .{ .object = .{ | 2121 | try resolved_inputs.append(gpa, .{ .object = .{ |
| 2108 | .path = pq.path, | 2122 | .path = pq.path, |
| 2109 | .file = file, | 2123 | .file = file, |
| ... | @@ -2115,7 +2129,7 @@ fn resolvePathInput( | ... | @@ -2115,7 +2129,7 @@ fn resolvePathInput( |
| 2115 | .res => { | 2129 | .res => { |
| 2116 | var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| | 2130 | var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err| |
| 2117 | fatal("failed to open windows resource {f}: {s}", .{ pq.path, @errorName(err) }); | 2131 | fatal("failed to open windows resource {f}: {s}", .{ pq.path, @errorName(err) }); |
| 2118 | errdefer file.close(); | 2132 | errdefer file.close(io); |
| 2119 | try resolved_inputs.append(gpa, .{ .res = .{ | 2133 | try resolved_inputs.append(gpa, .{ .res = .{ |
| 2120 | .path = pq.path, | 2134 | .path = pq.path, |
| 2121 | .file = file, | 2135 | .file = file, |
| ... | @@ -2129,6 +2143,7 @@ fn resolvePathInput( | ... | @@ -2129,6 +2143,7 @@ fn resolvePathInput( |
| 2129 | fn resolvePathInputLib( | 2143 | fn resolvePathInputLib( |
| 2130 | gpa: Allocator, | 2144 | gpa: Allocator, |
| 2131 | arena: Allocator, | 2145 | arena: Allocator, |
| 2146 | io: Io, | ||
| 2132 | /// Allocated with `gpa`. | 2147 | /// Allocated with `gpa`. |
| 2133 | unresolved_inputs: *std.ArrayList(UnresolvedInput), | 2148 | unresolved_inputs: *std.ArrayList(UnresolvedInput), |
| 2134 | /// Allocated with `gpa`. | 2149 | /// Allocated with `gpa`. |
| ... | @@ -2155,7 +2170,7 @@ fn resolvePathInputLib( | ... | @@ -2155,7 +2170,7 @@ fn resolvePathInputLib( |
| 2155 | @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e), | 2170 | @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e), |
| 2156 | }), | 2171 | }), |
| 2157 | }; | 2172 | }; |
| 2158 | errdefer file.close(); | 2173 | errdefer file.close(io); |
| 2159 | try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); | 2174 | try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); |
| 2160 | const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f}': {s}", .{ | 2175 | const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f}': {s}", .{ |
| 2161 | std.fmt.alt(test_path, .formatEscapeChar), @errorName(err), | 2176 | std.fmt.alt(test_path, .formatEscapeChar), @errorName(err), |
| ... | @@ -2223,7 +2238,7 @@ fn resolvePathInputLib( | ... | @@ -2223,7 +2238,7 @@ fn resolvePathInputLib( |
| 2223 | } }); | 2238 | } }); |
| 2224 | } | 2239 | } |
| 2225 | } | 2240 | } |
| 2226 | file.close(); | 2241 | file.close(io); |
| 2227 | return .ok; | 2242 | return .ok; |
| 2228 | } | 2243 | } |
| 2229 | 2244 | ||
| ... | @@ -2233,13 +2248,13 @@ fn resolvePathInputLib( | ... | @@ -2233,13 +2248,13 @@ fn resolvePathInputLib( |
| 2233 | @tagName(link_mode), test_path, @errorName(e), | 2248 | @tagName(link_mode), test_path, @errorName(e), |
| 2234 | }), | 2249 | }), |
| 2235 | }; | 2250 | }; |
| 2236 | errdefer file.close(); | 2251 | errdefer file.close(io); |
| 2237 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); | 2252 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); |
| 2238 | } | 2253 | } |
| 2239 | 2254 | ||
| 2240 | pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object { | 2255 | pub fn openObject(io: Io, path: Path, must_link: bool, hidden: bool) !Input.Object { |
| 2241 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); | 2256 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); |
| 2242 | errdefer file.close(); | 2257 | errdefer file.close(io); |
| 2243 | return .{ | 2258 | return .{ |
| 2244 | .path = path, | 2259 | .path = path, |
| 2245 | .file = file, | 2260 | .file = file, |
| ... | @@ -2248,9 +2263,9 @@ pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object { | ... | @@ -2248,9 +2263,9 @@ pub fn openObject(path: Path, must_link: bool, hidden: bool) !Input.Object { |
| 2248 | }; | 2263 | }; |
| 2249 | } | 2264 | } |
| 2250 | 2265 | ||
| 2251 | pub fn openDso(path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso { | 2266 | pub fn openDso(io: Io, path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso { |
| 2252 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); | 2267 | var file = try path.root_dir.handle.openFile(path.sub_path, .{}); |
| 2253 | errdefer file.close(); | 2268 | errdefer file.close(io); |
| 2254 | return .{ | 2269 | return .{ |
| 2255 | .path = path, | 2270 | .path = path, |
| 2256 | .file = file, | 2271 | .file = file, |
| ... | @@ -2260,20 +2275,20 @@ pub fn openDso(path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso | ... | @@ -2260,20 +2275,20 @@ pub fn openDso(path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso |
| 2260 | }; | 2275 | }; |
| 2261 | } | 2276 | } |
| 2262 | 2277 | ||
| 2263 | pub fn openObjectInput(diags: *Diags, path: Path) error{LinkFailure}!Input { | 2278 | pub fn openObjectInput(io: Io, diags: *Diags, path: Path) error{LinkFailure}!Input { |
| 2264 | return .{ .object = openObject(path, false, false) catch |err| { | 2279 | return .{ .object = openObject(io, path, false, false) catch |err| { |
| 2265 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 2280 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2266 | } }; | 2281 | } }; |
| 2267 | } | 2282 | } |
| 2268 | 2283 | ||
| 2269 | pub fn openArchiveInput(diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input { | 2284 | pub fn openArchiveInput(io: Io, diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input { |
| 2270 | return .{ .archive = openObject(path, must_link, hidden) catch |err| { | 2285 | return .{ .archive = openObject(io, path, must_link, hidden) catch |err| { |
| 2271 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 2286 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2272 | } }; | 2287 | } }; |
| 2273 | } | 2288 | } |
| 2274 | 2289 | ||
| 2275 | pub fn openDsoInput(diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input { | 2290 | pub fn openDsoInput(io: Io, diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input { |
| 2276 | return .{ .dso = openDso(path, needed, weak, reexport) catch |err| { | 2291 | return .{ .dso = openDso(io, path, needed, weak, reexport) catch |err| { |
| 2277 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 2292 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2278 | } }; | 2293 | } }; |
| 2279 | } | 2294 | } |
src/link/C.zig+4-2| ... | @@ -124,6 +124,7 @@ pub fn createEmpty( | ... | @@ -124,6 +124,7 @@ pub fn createEmpty( |
| 124 | emit: Path, | 124 | emit: Path, |
| 125 | options: link.File.OpenOptions, | 125 | options: link.File.OpenOptions, |
| 126 | ) !*C { | 126 | ) !*C { |
| 127 | const io = comp.io; | ||
| 127 | const target = &comp.root_mod.resolved_target.result; | 128 | const target = &comp.root_mod.resolved_target.result; |
| 128 | assert(target.ofmt == .c); | 129 | assert(target.ofmt == .c); |
| 129 | const optimize_mode = comp.root_mod.optimize_mode; | 130 | const optimize_mode = comp.root_mod.optimize_mode; |
| ... | @@ -139,7 +140,7 @@ pub fn createEmpty( | ... | @@ -139,7 +140,7 @@ pub fn createEmpty( |
| 139 | // Truncation is done on `flush`. | 140 | // Truncation is done on `flush`. |
| 140 | .truncate = false, | 141 | .truncate = false, |
| 141 | }); | 142 | }); |
| 142 | errdefer file.close(); | 143 | errdefer file.close(io); |
| 143 | 144 | ||
| 144 | const c_file = try arena.create(C); | 145 | const c_file = try arena.create(C); |
| 145 | 146 | ||
| ... | @@ -763,6 +764,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { | ... | @@ -763,6 +764,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { |
| 763 | if (true) return; // emit-h is regressed | 764 | if (true) return; // emit-h is regressed |
| 764 | 765 | ||
| 765 | const emit_h = zcu.emit_h orelse return; | 766 | const emit_h = zcu.emit_h orelse return; |
| 767 | const io = zcu.comp.io; | ||
| 766 | 768 | ||
| 767 | // We collect a list of buffers to write, and write them all at once with pwritev 😎 | 769 | // We collect a list of buffers to write, and write them all at once with pwritev 😎 |
| 768 | const num_buffers = emit_h.decl_table.count() + 1; | 770 | const num_buffers = emit_h.decl_table.count() + 1; |
| ... | @@ -795,7 +797,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { | ... | @@ -795,7 +797,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { |
| 795 | // make it easier on the file system by doing 1 reallocation instead of two. | 797 | // make it easier on the file system by doing 1 reallocation instead of two. |
| 796 | .truncate = false, | 798 | .truncate = false, |
| 797 | }); | 799 | }); |
| 798 | defer file.close(); | 800 | defer file.close(io); |
| 799 | 801 | ||
| 800 | try file.setEndPos(file_size); | 802 | try file.setEndPos(file_size); |
| 801 | try file.pwritevAll(all_buffers.items, 0); | 803 | try file.pwritevAll(all_buffers.items, 0); |
src/link/Elf.zig+4-2| ... | @@ -406,10 +406,12 @@ pub fn open( | ... | @@ -406,10 +406,12 @@ pub fn open( |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | pub fn deinit(self: *Elf) void { | 408 | pub fn deinit(self: *Elf) void { |
| 409 | const gpa = self.base.comp.gpa; | 409 | const comp = self.base.comp; |
| 410 | const gpa = comp.gpa; | ||
| 411 | const io = comp.io; | ||
| 410 | 412 | ||
| 411 | for (self.file_handles.items) |fh| { | 413 | for (self.file_handles.items) |fh| { |
| 412 | fh.close(); | 414 | fh.close(io); |
| 413 | } | 415 | } |
| 414 | self.file_handles.deinit(gpa); | 416 | self.file_handles.deinit(gpa); |
| 415 | 417 |
src/link/Lld.zig+1-1| ... | @@ -1628,7 +1628,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi | ... | @@ -1628,7 +1628,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1628 | defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| | 1628 | defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| |
| 1629 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); | 1629 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); |
| 1630 | { | 1630 | { |
| 1631 | defer rsp_file.close(); | 1631 | defer rsp_file.close(io); |
| 1632 | var rsp_file_buffer: [1024]u8 = undefined; | 1632 | var rsp_file_buffer: [1024]u8 = undefined; |
| 1633 | var rsp_file_writer = rsp_file.writer(&rsp_file_buffer); | 1633 | var rsp_file_writer = rsp_file.writer(&rsp_file_buffer); |
| 1634 | const rsp_writer = &rsp_file_writer.interface; | 1634 | const rsp_writer = &rsp_file_writer.interface; |
src/link/MachO.zig+11-5| ... | @@ -267,14 +267,16 @@ pub fn open( | ... | @@ -267,14 +267,16 @@ pub fn open( |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | pub fn deinit(self: *MachO) void { | 269 | pub fn deinit(self: *MachO) void { |
| 270 | const gpa = self.base.comp.gpa; | 270 | const comp = self.base.comp; |
| 271 | const gpa = comp.gpa; | ||
| 272 | const io = comp.io; | ||
| 271 | 273 | ||
| 272 | if (self.d_sym) |*d_sym| { | 274 | if (self.d_sym) |*d_sym| { |
| 273 | d_sym.deinit(); | 275 | d_sym.deinit(); |
| 274 | } | 276 | } |
| 275 | 277 | ||
| 276 | for (self.file_handles.items) |handle| { | 278 | for (self.file_handles.items) |handle| { |
| 277 | handle.close(); | 279 | handle.close(io); |
| 278 | } | 280 | } |
| 279 | self.file_handles.deinit(gpa); | 281 | self.file_handles.deinit(gpa); |
| 280 | 282 | ||
| ... | @@ -3257,8 +3259,10 @@ const InitMetadataOptions = struct { | ... | @@ -3257,8 +3259,10 @@ const InitMetadataOptions = struct { |
| 3257 | }; | 3259 | }; |
| 3258 | 3260 | ||
| 3259 | pub fn closeDebugInfo(self: *MachO) bool { | 3261 | pub fn closeDebugInfo(self: *MachO) bool { |
| 3262 | const comp = self.base.comp; | ||
| 3263 | const io = comp.io; | ||
| 3260 | const d_sym = &(self.d_sym orelse return false); | 3264 | const d_sym = &(self.d_sym orelse return false); |
| 3261 | d_sym.file.?.close(); | 3265 | d_sym.file.?.close(io); |
| 3262 | d_sym.file = null; | 3266 | d_sym.file = null; |
| 3263 | return true; | 3267 | return true; |
| 3264 | } | 3268 | } |
| ... | @@ -3269,7 +3273,9 @@ pub fn reopenDebugInfo(self: *MachO) !void { | ... | @@ -3269,7 +3273,9 @@ pub fn reopenDebugInfo(self: *MachO) !void { |
| 3269 | assert(!self.base.comp.config.use_llvm); | 3273 | assert(!self.base.comp.config.use_llvm); |
| 3270 | assert(self.base.comp.config.debug_format == .dwarf); | 3274 | assert(self.base.comp.config.debug_format == .dwarf); |
| 3271 | 3275 | ||
| 3272 | const gpa = self.base.comp.gpa; | 3276 | const comp = self.base.comp; |
| 3277 | const io = comp.io; | ||
| 3278 | const gpa = comp.gpa; | ||
| 3273 | const sep = fs.path.sep_str; | 3279 | const sep = fs.path.sep_str; |
| 3274 | const d_sym_path = try std.fmt.allocPrint( | 3280 | const d_sym_path = try std.fmt.allocPrint( |
| 3275 | gpa, | 3281 | gpa, |
| ... | @@ -3279,7 +3285,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { | ... | @@ -3279,7 +3285,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { |
| 3279 | defer gpa.free(d_sym_path); | 3285 | defer gpa.free(d_sym_path); |
| 3280 | 3286 | ||
| 3281 | var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{}); | 3287 | var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{}); |
| 3282 | defer d_sym_bundle.close(); | 3288 | defer d_sym_bundle.close(io); |
| 3283 | 3289 | ||
| 3284 | self.d_sym.?.file = try d_sym_bundle.createFile(fs.path.basename(self.base.emit.sub_path), .{ | 3290 | self.d_sym.?.file = try d_sym_bundle.createFile(fs.path.basename(self.base.emit.sub_path), .{ |
| 3285 | .truncate = false, | 3291 | .truncate = false, |
src/link/MachO/DebugSymbols.zig+26-24| ... | @@ -1,5 +1,28 @@ | ... | @@ -1,5 +1,28 @@ |
| 1 | const DebugSymbols = @This(); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const Io = std.Io; | ||
| 5 | const assert = std.debug.assert; | ||
| 6 | const fs = std.fs; | ||
| 7 | const log = std.log.scoped(.link_dsym); | ||
| 8 | const macho = std.macho; | ||
| 9 | const makeStaticString = MachO.makeStaticString; | ||
| 10 | const math = std.math; | ||
| 11 | const mem = std.mem; | ||
| 12 | const Writer = std.Io.Writer; | ||
| 13 | const Allocator = std.mem.Allocator; | ||
| 14 | |||
| 15 | const link = @import("../../link.zig"); | ||
| 16 | const MachO = @import("../MachO.zig"); | ||
| 17 | const StringTable = @import("../StringTable.zig"); | ||
| 18 | const Type = @import("../../Type.zig"); | ||
| 19 | const trace = @import("../../tracy.zig").trace; | ||
| 20 | const load_commands = @import("load_commands.zig"); | ||
| 21 | const padToIdeal = MachO.padToIdeal; | ||
| 22 | |||
| 23 | io: Io, | ||
| 1 | allocator: Allocator, | 24 | allocator: Allocator, |
| 2 | file: ?fs.File, | 25 | file: ?Io.File, |
| 3 | 26 | ||
| 4 | symtab_cmd: macho.symtab_command = .{}, | 27 | symtab_cmd: macho.symtab_command = .{}, |
| 5 | uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, | 28 | uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, |
| ... | @@ -208,7 +231,8 @@ pub fn flush(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -208,7 +231,8 @@ pub fn flush(self: *DebugSymbols, macho_file: *MachO) !void { |
| 208 | 231 | ||
| 209 | pub fn deinit(self: *DebugSymbols) void { | 232 | pub fn deinit(self: *DebugSymbols) void { |
| 210 | const gpa = self.allocator; | 233 | const gpa = self.allocator; |
| 211 | if (self.file) |file| file.close(); | 234 | const io = self.io; |
| 235 | if (self.file) |file| file.close(io); | ||
| 212 | self.segments.deinit(gpa); | 236 | self.segments.deinit(gpa); |
| 213 | self.sections.deinit(gpa); | 237 | self.sections.deinit(gpa); |
| 214 | self.relocs.deinit(gpa); | 238 | self.relocs.deinit(gpa); |
| ... | @@ -443,25 +467,3 @@ pub fn getSection(self: DebugSymbols, sect: u8) macho.section_64 { | ... | @@ -443,25 +467,3 @@ pub fn getSection(self: DebugSymbols, sect: u8) macho.section_64 { |
| 443 | assert(sect < self.sections.items.len); | 467 | assert(sect < self.sections.items.len); |
| 444 | return self.sections.items[sect]; | 468 | return self.sections.items[sect]; |
| 445 | } | 469 | } |
| 446 | |||
| 447 | const DebugSymbols = @This(); | ||
| 448 | |||
| 449 | const std = @import("std"); | ||
| 450 | const build_options = @import("build_options"); | ||
| 451 | const assert = std.debug.assert; | ||
| 452 | const fs = std.fs; | ||
| 453 | const link = @import("../../link.zig"); | ||
| 454 | const load_commands = @import("load_commands.zig"); | ||
| 455 | const log = std.log.scoped(.link_dsym); | ||
| 456 | const macho = std.macho; | ||
| 457 | const makeStaticString = MachO.makeStaticString; | ||
| 458 | const math = std.math; | ||
| 459 | const mem = std.mem; | ||
| 460 | const padToIdeal = MachO.padToIdeal; | ||
| 461 | const trace = @import("../../tracy.zig").trace; | ||
| 462 | const Writer = std.Io.Writer; | ||
| 463 | |||
| 464 | const Allocator = mem.Allocator; | ||
| 465 | const MachO = @import("../MachO.zig"); | ||
| 466 | const StringTable = @import("../StringTable.zig"); | ||
| 467 | const Type = @import("../../Type.zig"); |
src/link/Wasm.zig+2-2| ... | @@ -3032,7 +3032,7 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void { | ... | @@ -3032,7 +3032,7 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3032 | const io = wasm.base.comp.io; | 3032 | const io = wasm.base.comp.io; |
| 3033 | const gc_sections = wasm.base.gc_sections; | 3033 | const gc_sections = wasm.base.gc_sections; |
| 3034 | 3034 | ||
| 3035 | defer obj.file.close(); | 3035 | defer obj.file.close(io); |
| 3036 | 3036 | ||
| 3037 | var file_reader = obj.file.reader(io, &.{}); | 3037 | var file_reader = obj.file.reader(io, &.{}); |
| 3038 | 3038 | ||
| ... | @@ -3060,7 +3060,7 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { | ... | @@ -3060,7 +3060,7 @@ fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3060 | const io = wasm.base.comp.io; | 3060 | const io = wasm.base.comp.io; |
| 3061 | const gc_sections = wasm.base.gc_sections; | 3061 | const gc_sections = wasm.base.gc_sections; |
| 3062 | 3062 | ||
| 3063 | defer obj.file.close(); | 3063 | defer obj.file.close(io); |
| 3064 | 3064 | ||
| 3065 | var file_reader = obj.file.reader(io, &.{}); | 3065 | var file_reader = obj.file.reader(io, &.{}); |
| 3066 | 3066 |
src/main.zig+71-64| ... | @@ -328,21 +328,21 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -328,21 +328,21 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 328 | .prepend_global_cache_path = true, | 328 | .prepend_global_cache_path = true, |
| 329 | }); | 329 | }); |
| 330 | } else if (mem.eql(u8, cmd, "init")) { | 330 | } else if (mem.eql(u8, cmd, "init")) { |
| 331 | return cmdInit(gpa, arena, cmd_args); | 331 | return cmdInit(gpa, arena, io, cmd_args); |
| 332 | } else if (mem.eql(u8, cmd, "targets")) { | 332 | } else if (mem.eql(u8, cmd, "targets")) { |
| 333 | dev.check(.targets_command); | 333 | dev.check(.targets_command); |
| 334 | const host = std.zig.resolveTargetQueryOrFatal(io, .{}); | 334 | const host = std.zig.resolveTargetQueryOrFatal(io, .{}); |
| 335 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | 335 | var stdout_writer = Io.File.stdout().writer(&stdout_buffer); |
| 336 | try @import("print_targets.zig").cmdTargets(arena, cmd_args, &stdout_writer.interface, &host); | 336 | try @import("print_targets.zig").cmdTargets(arena, io, cmd_args, &stdout_writer.interface, &host); |
| 337 | return stdout_writer.interface.flush(); | 337 | return stdout_writer.interface.flush(); |
| 338 | } else if (mem.eql(u8, cmd, "version")) { | 338 | } else if (mem.eql(u8, cmd, "version")) { |
| 339 | dev.check(.version_command); | 339 | dev.check(.version_command); |
| 340 | try fs.File.stdout().writeAll(build_options.version ++ "\n"); | 340 | try Io.File.stdout().writeAll(build_options.version ++ "\n"); |
| 341 | return; | 341 | return; |
| 342 | } else if (mem.eql(u8, cmd, "env")) { | 342 | } else if (mem.eql(u8, cmd, "env")) { |
| 343 | dev.check(.env_command); | 343 | dev.check(.env_command); |
| 344 | const host = std.zig.resolveTargetQueryOrFatal(io, .{}); | 344 | const host = std.zig.resolveTargetQueryOrFatal(io, .{}); |
| 345 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | 345 | var stdout_writer = Io.File.stdout().writer(&stdout_buffer); |
| 346 | try @import("print_env.zig").cmdEnv( | 346 | try @import("print_env.zig").cmdEnv( |
| 347 | arena, | 347 | arena, |
| 348 | &stdout_writer.interface, | 348 | &stdout_writer.interface, |
| ... | @@ -358,10 +358,10 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -358,10 +358,10 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 358 | }); | 358 | }); |
| 359 | } else if (mem.eql(u8, cmd, "zen")) { | 359 | } else if (mem.eql(u8, cmd, "zen")) { |
| 360 | dev.check(.zen_command); | 360 | dev.check(.zen_command); |
| 361 | return fs.File.stdout().writeAll(info_zen); | 361 | return Io.File.stdout().writeAll(info_zen); |
| 362 | } else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) { | 362 | } else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) { |
| 363 | dev.check(.help_command); | 363 | dev.check(.help_command); |
| 364 | return fs.File.stdout().writeAll(usage); | 364 | return Io.File.stdout().writeAll(usage); |
| 365 | } else if (mem.eql(u8, cmd, "ast-check")) { | 365 | } else if (mem.eql(u8, cmd, "ast-check")) { |
| 366 | return cmdAstCheck(arena, io, cmd_args); | 366 | return cmdAstCheck(arena, io, cmd_args); |
| 367 | } else if (mem.eql(u8, cmd, "detect-cpu")) { | 367 | } else if (mem.eql(u8, cmd, "detect-cpu")) { |
| ... | @@ -698,7 +698,7 @@ const Emit = union(enum) { | ... | @@ -698,7 +698,7 @@ const Emit = union(enum) { |
| 698 | yes: []const u8, | 698 | yes: []const u8, |
| 699 | 699 | ||
| 700 | const OutputToCacheReason = enum { listen, @"zig run", @"zig test" }; | 700 | const OutputToCacheReason = enum { listen, @"zig run", @"zig test" }; |
| 701 | fn resolve(emit: Emit, default_basename: []const u8, output_to_cache: ?OutputToCacheReason) Compilation.CreateOptions.Emit { | 701 | fn resolve(io: Io, emit: Emit, default_basename: []const u8, output_to_cache: ?OutputToCacheReason) Compilation.CreateOptions.Emit { |
| 702 | return switch (emit) { | 702 | return switch (emit) { |
| 703 | .no => .no, | 703 | .no => .no, |
| 704 | .yes_default_path => if (output_to_cache != null) .yes_cache else .{ .yes_path = default_basename }, | 704 | .yes_default_path => if (output_to_cache != null) .yes_cache else .{ .yes_path = default_basename }, |
| ... | @@ -716,7 +716,7 @@ const Emit = union(enum) { | ... | @@ -716,7 +716,7 @@ const Emit = union(enum) { |
| 716 | var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { | 716 | var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { |
| 717 | fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); | 717 | fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); |
| 718 | }; | 718 | }; |
| 719 | dir.close(); | 719 | dir.close(io); |
| 720 | } | 720 | } |
| 721 | break :e .{ .yes_path = path }; | 721 | break :e .{ .yes_path = path }; |
| 722 | }, | 722 | }, |
| ... | @@ -1034,7 +1034,7 @@ fn buildOutputType( | ... | @@ -1034,7 +1034,7 @@ fn buildOutputType( |
| 1034 | }; | 1034 | }; |
| 1035 | } else if (mem.startsWith(u8, arg, "-")) { | 1035 | } else if (mem.startsWith(u8, arg, "-")) { |
| 1036 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 1036 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 1037 | try fs.File.stdout().writeAll(usage_build_generic); | 1037 | try Io.File.stdout().writeAll(usage_build_generic); |
| 1038 | return cleanExit(); | 1038 | return cleanExit(); |
| 1039 | } else if (mem.eql(u8, arg, "--")) { | 1039 | } else if (mem.eql(u8, arg, "--")) { |
| 1040 | if (arg_mode == .run) { | 1040 | if (arg_mode == .run) { |
| ... | @@ -2834,9 +2834,9 @@ fn buildOutputType( | ... | @@ -2834,9 +2834,9 @@ fn buildOutputType( |
| 2834 | } else if (mem.eql(u8, arg, "-V")) { | 2834 | } else if (mem.eql(u8, arg, "-V")) { |
| 2835 | warn("ignoring request for supported emulations: unimplemented", .{}); | 2835 | warn("ignoring request for supported emulations: unimplemented", .{}); |
| 2836 | } else if (mem.eql(u8, arg, "-v")) { | 2836 | } else if (mem.eql(u8, arg, "-v")) { |
| 2837 | try fs.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); | 2837 | try Io.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); |
| 2838 | } else if (mem.eql(u8, arg, "--version")) { | 2838 | } else if (mem.eql(u8, arg, "--version")) { |
| 2839 | try fs.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); | 2839 | try Io.File.stdout().writeAll("zig ld " ++ build_options.version ++ "\n"); |
| 2840 | process.exit(0); | 2840 | process.exit(0); |
| 2841 | } else { | 2841 | } else { |
| 2842 | fatal("unsupported linker arg: {s}", .{arg}); | 2842 | fatal("unsupported linker arg: {s}", .{arg}); |
| ... | @@ -3251,8 +3251,8 @@ fn buildOutputType( | ... | @@ -3251,8 +3251,8 @@ fn buildOutputType( |
| 3251 | } | 3251 | } |
| 3252 | } | 3252 | } |
| 3253 | 3253 | ||
| 3254 | var cleanup_emit_bin_dir: ?fs.Dir = null; | 3254 | var cleanup_emit_bin_dir: ?Io.Dir = null; |
| 3255 | defer if (cleanup_emit_bin_dir) |*dir| dir.close(); | 3255 | defer if (cleanup_emit_bin_dir) |*dir| dir.close(io); |
| 3256 | 3256 | ||
| 3257 | // For `zig run` and `zig test`, we don't want to put the binary in the cwd by default. So, if | 3257 | // For `zig run` and `zig test`, we don't want to put the binary in the cwd by default. So, if |
| 3258 | // the binary is requested with no explicit path (as is the default), we emit to the cache. | 3258 | // the binary is requested with no explicit path (as is the default), we emit to the cache. |
| ... | @@ -3307,7 +3307,7 @@ fn buildOutputType( | ... | @@ -3307,7 +3307,7 @@ fn buildOutputType( |
| 3307 | var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { | 3307 | var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { |
| 3308 | fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); | 3308 | fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); |
| 3309 | }; | 3309 | }; |
| 3310 | dir.close(); | 3310 | dir.close(io); |
| 3311 | } | 3311 | } |
| 3312 | break :emit .{ .yes_path = path }; | 3312 | break :emit .{ .yes_path = path }; |
| 3313 | }, | 3313 | }, |
| ... | @@ -3390,7 +3390,7 @@ fn buildOutputType( | ... | @@ -3390,7 +3390,7 @@ fn buildOutputType( |
| 3390 | // will be a hash of its contents — so multiple invocations of | 3390 | // will be a hash of its contents — so multiple invocations of |
| 3391 | // `zig cc -` will result in the same temp file name. | 3391 | // `zig cc -` will result in the same temp file name. |
| 3392 | var f = try dirs.local_cache.handle.createFile(dump_path, .{}); | 3392 | var f = try dirs.local_cache.handle.createFile(dump_path, .{}); |
| 3393 | defer f.close(); | 3393 | defer f.close(io); |
| 3394 | 3394 | ||
| 3395 | // Re-using the hasher from Cache, since the functional requirements | 3395 | // Re-using the hasher from Cache, since the functional requirements |
| 3396 | // for the hashing algorithm here and in the cache are the same. | 3396 | // for the hashing algorithm here and in the cache are the same. |
| ... | @@ -3399,7 +3399,7 @@ fn buildOutputType( | ... | @@ -3399,7 +3399,7 @@ fn buildOutputType( |
| 3399 | var file_writer = f.writer(&.{}); | 3399 | var file_writer = f.writer(&.{}); |
| 3400 | var buffer: [1000]u8 = undefined; | 3400 | var buffer: [1000]u8 = undefined; |
| 3401 | var hasher = file_writer.interface.hashed(Cache.Hasher.init("0123456789abcdef"), &buffer); | 3401 | var hasher = file_writer.interface.hashed(Cache.Hasher.init("0123456789abcdef"), &buffer); |
| 3402 | var stdin_reader = fs.File.stdin().readerStreaming(io, &.{}); | 3402 | var stdin_reader = Io.File.stdin().readerStreaming(io, &.{}); |
| 3403 | _ = hasher.writer.sendFileAll(&stdin_reader, .unlimited) catch |err| switch (err) { | 3403 | _ = hasher.writer.sendFileAll(&stdin_reader, .unlimited) catch |err| switch (err) { |
| 3404 | error.WriteFailed => fatal("failed to write {s}: {t}", .{ dump_path, file_writer.err.? }), | 3404 | error.WriteFailed => fatal("failed to write {s}: {t}", .{ dump_path, file_writer.err.? }), |
| 3405 | else => fatal("failed to pipe stdin to {s}: {t}", .{ dump_path, err }), | 3405 | else => fatal("failed to pipe stdin to {s}: {t}", .{ dump_path, err }), |
| ... | @@ -3630,13 +3630,13 @@ fn buildOutputType( | ... | @@ -3630,13 +3630,13 @@ fn buildOutputType( |
| 3630 | if (show_builtin) { | 3630 | if (show_builtin) { |
| 3631 | const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config); | 3631 | const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config); |
| 3632 | const source = try builtin_opts.generate(arena); | 3632 | const source = try builtin_opts.generate(arena); |
| 3633 | return fs.File.stdout().writeAll(source); | 3633 | return Io.File.stdout().writeAll(source); |
| 3634 | } | 3634 | } |
| 3635 | switch (listen) { | 3635 | switch (listen) { |
| 3636 | .none => {}, | 3636 | .none => {}, |
| 3637 | .stdio => { | 3637 | .stdio => { |
| 3638 | var stdin_reader = fs.File.stdin().reader(io, &stdin_buffer); | 3638 | var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); |
| 3639 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | 3639 | var stdout_writer = Io.File.stdout().writer(&stdout_buffer); |
| 3640 | try serve( | 3640 | try serve( |
| 3641 | comp, | 3641 | comp, |
| 3642 | &stdin_reader.interface, | 3642 | &stdin_reader.interface, |
| ... | @@ -4034,6 +4034,7 @@ fn createModule( | ... | @@ -4034,6 +4034,7 @@ fn createModule( |
| 4034 | link.resolveInputs( | 4034 | link.resolveInputs( |
| 4035 | gpa, | 4035 | gpa, |
| 4036 | arena, | 4036 | arena, |
| 4037 | io, | ||
| 4037 | target, | 4038 | target, |
| 4038 | &unresolved_link_inputs, | 4039 | &unresolved_link_inputs, |
| 4039 | &create_module.link_inputs, | 4040 | &create_module.link_inputs, |
| ... | @@ -4689,8 +4690,8 @@ fn cmdTranslateC( | ... | @@ -4689,8 +4690,8 @@ fn cmdTranslateC( |
| 4689 | @errorName(err), | 4690 | @errorName(err), |
| 4690 | }); | 4691 | }); |
| 4691 | }; | 4692 | }; |
| 4692 | defer zig_file.close(); | 4693 | defer zig_file.close(io); |
| 4693 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | 4694 | var stdout_writer = Io.File.stdout().writer(&stdout_buffer); |
| 4694 | var file_reader = zig_file.reader(io, &.{}); | 4695 | var file_reader = zig_file.reader(io, &.{}); |
| 4695 | _ = try stdout_writer.interface.sendFileAll(&file_reader, .unlimited); | 4696 | _ = try stdout_writer.interface.sendFileAll(&file_reader, .unlimited); |
| 4696 | try stdout_writer.interface.flush(); | 4697 | try stdout_writer.interface.flush(); |
| ... | @@ -4728,7 +4729,7 @@ const usage_init = | ... | @@ -4728,7 +4729,7 @@ const usage_init = |
| 4728 | \\ | 4729 | \\ |
| 4729 | ; | 4730 | ; |
| 4730 | 4731 | ||
| 4731 | fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | 4732 | fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !void { |
| 4732 | dev.check(.init_command); | 4733 | dev.check(.init_command); |
| 4733 | 4734 | ||
| 4734 | var template: enum { example, minimal } = .example; | 4735 | var template: enum { example, minimal } = .example; |
| ... | @@ -4740,7 +4741,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4740,7 +4741,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4740 | if (mem.eql(u8, arg, "-m") or mem.eql(u8, arg, "--minimal")) { | 4741 | if (mem.eql(u8, arg, "-m") or mem.eql(u8, arg, "--minimal")) { |
| 4741 | template = .minimal; | 4742 | template = .minimal; |
| 4742 | } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 4743 | } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 4743 | try fs.File.stdout().writeAll(usage_init); | 4744 | try Io.File.stdout().writeAll(usage_init); |
| 4744 | return cleanExit(); | 4745 | return cleanExit(); |
| 4745 | } else { | 4746 | } else { |
| 4746 | fatal("unrecognized parameter: '{s}'", .{arg}); | 4747 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| ... | @@ -4759,7 +4760,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4759,7 +4760,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4759 | 4760 | ||
| 4760 | switch (template) { | 4761 | switch (template) { |
| 4761 | .example => { | 4762 | .example => { |
| 4762 | var templates = findTemplates(gpa, arena); | 4763 | var templates = findTemplates(gpa, arena, io); |
| 4763 | defer templates.deinit(); | 4764 | defer templates.deinit(); |
| 4764 | 4765 | ||
| 4765 | const s = fs.path.sep_str; | 4766 | const s = fs.path.sep_str; |
| ... | @@ -4789,7 +4790,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4789,7 +4790,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4789 | return cleanExit(); | 4790 | return cleanExit(); |
| 4790 | }, | 4791 | }, |
| 4791 | .minimal => { | 4792 | .minimal => { |
| 4792 | writeSimpleTemplateFile(Package.Manifest.basename, | 4793 | writeSimpleTemplateFile(io, Package.Manifest.basename, |
| 4793 | \\.{{ | 4794 | \\.{{ |
| 4794 | \\ .name = .{s}, | 4795 | \\ .name = .{s}, |
| 4795 | \\ .version = "0.0.1", | 4796 | \\ .version = "0.0.1", |
| ... | @@ -4806,7 +4807,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4806,7 +4807,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4806 | else => fatal("failed to create '{s}': {s}", .{ Package.Manifest.basename, @errorName(err) }), | 4807 | else => fatal("failed to create '{s}': {s}", .{ Package.Manifest.basename, @errorName(err) }), |
| 4807 | error.PathAlreadyExists => fatal("refusing to overwrite '{s}'", .{Package.Manifest.basename}), | 4808 | error.PathAlreadyExists => fatal("refusing to overwrite '{s}'", .{Package.Manifest.basename}), |
| 4808 | }; | 4809 | }; |
| 4809 | writeSimpleTemplateFile(Package.build_zig_basename, | 4810 | writeSimpleTemplateFile(io, Package.build_zig_basename, |
| 4810 | \\const std = @import("std"); | 4811 | \\const std = @import("std"); |
| 4811 | \\ | 4812 | \\ |
| 4812 | \\pub fn build(b: *std.Build) void {{ | 4813 | \\pub fn build(b: *std.Build) void {{ |
| ... | @@ -5203,8 +5204,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) | ... | @@ -5203,8 +5204,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) |
| 5203 | .parent = root_mod, | 5204 | .parent = root_mod, |
| 5204 | }); | 5205 | }); |
| 5205 | 5206 | ||
| 5206 | var cleanup_build_dir: ?fs.Dir = null; | 5207 | var cleanup_build_dir: ?Io.Dir = null; |
| 5207 | defer if (cleanup_build_dir) |*dir| dir.close(); | 5208 | defer if (cleanup_build_dir) |*dir| dir.close(io); |
| 5208 | 5209 | ||
| 5209 | if (dev.env.supports(.fetch_command)) { | 5210 | if (dev.env.supports(.fetch_command)) { |
| 5210 | const fetch_prog_node = root_prog_node.start("Fetch Packages", 0); | 5211 | const fetch_prog_node = root_prog_node.start("Fetch Packages", 0); |
| ... | @@ -5296,6 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) | ... | @@ -5296,6 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) |
| 5296 | try job_queue.createDependenciesSource(&source_buf); | 5297 | try job_queue.createDependenciesSource(&source_buf); |
| 5297 | const deps_mod = try createDependenciesModule( | 5298 | const deps_mod = try createDependenciesModule( |
| 5298 | arena, | 5299 | arena, |
| 5300 | io, | ||
| 5299 | source_buf.items, | 5301 | source_buf.items, |
| 5300 | root_mod, | 5302 | root_mod, |
| 5301 | dirs, | 5303 | dirs, |
| ... | @@ -5357,6 +5359,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) | ... | @@ -5357,6 +5359,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) |
| 5357 | } | 5359 | } |
| 5358 | } else try createEmptyDependenciesModule( | 5360 | } else try createEmptyDependenciesModule( |
| 5359 | arena, | 5361 | arena, |
| 5362 | io, | ||
| 5360 | root_mod, | 5363 | root_mod, |
| 5361 | dirs, | 5364 | dirs, |
| 5362 | config, | 5365 | config, |
| ... | @@ -5623,7 +5626,7 @@ fn jitCmd( | ... | @@ -5623,7 +5626,7 @@ fn jitCmd( |
| 5623 | defer comp.destroy(); | 5626 | defer comp.destroy(); |
| 5624 | 5627 | ||
| 5625 | if (options.server) { | 5628 | if (options.server) { |
| 5626 | var stdout_writer = fs.File.stdout().writer(&stdout_buffer); | 5629 | var stdout_writer = Io.File.stdout().writer(&stdout_buffer); |
| 5627 | var server: std.zig.Server = .{ | 5630 | var server: std.zig.Server = .{ |
| 5628 | .out = &stdout_writer.interface, | 5631 | .out = &stdout_writer.interface, |
| 5629 | .in = undefined, // won't be receiving messages | 5632 | .in = undefined, // won't be receiving messages |
| ... | @@ -6156,7 +6159,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6156,7 +6159,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6156 | const arg = args[i]; | 6159 | const arg = args[i]; |
| 6157 | if (mem.startsWith(u8, arg, "-")) { | 6160 | if (mem.startsWith(u8, arg, "-")) { |
| 6158 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 6161 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 6159 | try fs.File.stdout().writeAll(usage_ast_check); | 6162 | try Io.File.stdout().writeAll(usage_ast_check); |
| 6160 | return cleanExit(); | 6163 | return cleanExit(); |
| 6161 | } else if (mem.eql(u8, arg, "-t")) { | 6164 | } else if (mem.eql(u8, arg, "-t")) { |
| 6162 | want_output_text = true; | 6165 | want_output_text = true; |
| ... | @@ -6187,9 +6190,9 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6187,9 +6190,9 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6187 | break :file fs.cwd().openFile(p, .{}) catch |err| { | 6190 | break :file fs.cwd().openFile(p, .{}) catch |err| { |
| 6188 | fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); | 6191 | fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6189 | }; | 6192 | }; |
| 6190 | } else fs.File.stdin(); | 6193 | } else Io.File.stdin(); |
| 6191 | defer if (zig_source_path != null) f.close(); | 6194 | defer if (zig_source_path != null) f.close(io); |
| 6192 | var file_reader: fs.File.Reader = f.reader(io, &stdin_buffer); | 6195 | var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); |
| 6193 | break :s std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| { | 6196 | break :s std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| { |
| 6194 | fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); | 6197 | fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6195 | }; | 6198 | }; |
| ... | @@ -6207,7 +6210,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6207,7 +6210,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6207 | 6210 | ||
| 6208 | const tree = try Ast.parse(arena, source, mode); | 6211 | const tree = try Ast.parse(arena, source, mode); |
| 6209 | 6212 | ||
| 6210 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | 6213 | var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 6211 | const stdout_bw = &stdout_writer.interface; | 6214 | const stdout_bw = &stdout_writer.interface; |
| 6212 | switch (mode) { | 6215 | switch (mode) { |
| 6213 | .zig => { | 6216 | .zig => { |
| ... | @@ -6330,7 +6333,7 @@ fn cmdDetectCpu(io: Io, args: []const []const u8) !void { | ... | @@ -6330,7 +6333,7 @@ fn cmdDetectCpu(io: Io, args: []const []const u8) !void { |
| 6330 | const arg = args[i]; | 6333 | const arg = args[i]; |
| 6331 | if (mem.startsWith(u8, arg, "-")) { | 6334 | if (mem.startsWith(u8, arg, "-")) { |
| 6332 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 6335 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 6333 | try fs.File.stdout().writeAll(detect_cpu_usage); | 6336 | try Io.File.stdout().writeAll(detect_cpu_usage); |
| 6334 | return cleanExit(); | 6337 | return cleanExit(); |
| 6335 | } else if (mem.eql(u8, arg, "--llvm")) { | 6338 | } else if (mem.eql(u8, arg, "--llvm")) { |
| 6336 | use_llvm = true; | 6339 | use_llvm = true; |
| ... | @@ -6422,7 +6425,7 @@ fn detectNativeCpuWithLLVM( | ... | @@ -6422,7 +6425,7 @@ fn detectNativeCpuWithLLVM( |
| 6422 | } | 6425 | } |
| 6423 | 6426 | ||
| 6424 | fn printCpu(cpu: std.Target.Cpu) !void { | 6427 | fn printCpu(cpu: std.Target.Cpu) !void { |
| 6425 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | 6428 | var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 6426 | const stdout_bw = &stdout_writer.interface; | 6429 | const stdout_bw = &stdout_writer.interface; |
| 6427 | 6430 | ||
| 6428 | if (cpu.model.llvm_name) |llvm_name| { | 6431 | if (cpu.model.llvm_name) |llvm_name| { |
| ... | @@ -6471,7 +6474,7 @@ fn cmdDumpLlvmInts( | ... | @@ -6471,7 +6474,7 @@ fn cmdDumpLlvmInts( |
| 6471 | const dl = tm.createTargetDataLayout(); | 6474 | const dl = tm.createTargetDataLayout(); |
| 6472 | const context = llvm.Context.create(); | 6475 | const context = llvm.Context.create(); |
| 6473 | 6476 | ||
| 6474 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | 6477 | var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 6475 | const stdout_bw = &stdout_writer.interface; | 6478 | const stdout_bw = &stdout_writer.interface; |
| 6476 | for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { | 6479 | for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { |
| 6477 | const int_type = context.intType(bits); | 6480 | const int_type = context.intType(bits); |
| ... | @@ -6494,10 +6497,10 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6494,10 +6497,10 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6494 | var f = fs.cwd().openFile(cache_file, .{}) catch |err| { | 6497 | var f = fs.cwd().openFile(cache_file, .{}) catch |err| { |
| 6495 | fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) }); | 6498 | fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) }); |
| 6496 | }; | 6499 | }; |
| 6497 | defer f.close(); | 6500 | defer f.close(io); |
| 6498 | 6501 | ||
| 6499 | const zir = try Zcu.loadZirCache(arena, io, f); | 6502 | const zir = try Zcu.loadZirCache(arena, io, f); |
| 6500 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | 6503 | var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 6501 | const stdout_bw = &stdout_writer.interface; | 6504 | const stdout_bw = &stdout_writer.interface; |
| 6502 | { | 6505 | { |
| 6503 | const instruction_bytes = zir.instructions.len * | 6506 | const instruction_bytes = zir.instructions.len * |
| ... | @@ -6540,16 +6543,16 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6540,16 +6543,16 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6540 | const old_source = source: { | 6543 | const old_source = source: { |
| 6541 | var f = fs.cwd().openFile(old_source_path, .{}) catch |err| | 6544 | var f = fs.cwd().openFile(old_source_path, .{}) catch |err| |
| 6542 | fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | 6545 | fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); |
| 6543 | defer f.close(); | 6546 | defer f.close(io); |
| 6544 | var file_reader: fs.File.Reader = f.reader(io, &stdin_buffer); | 6547 | var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); |
| 6545 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| | 6548 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| |
| 6546 | fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | 6549 | fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); |
| 6547 | }; | 6550 | }; |
| 6548 | const new_source = source: { | 6551 | const new_source = source: { |
| 6549 | var f = fs.cwd().openFile(new_source_path, .{}) catch |err| | 6552 | var f = fs.cwd().openFile(new_source_path, .{}) catch |err| |
| 6550 | fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); | 6553 | fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6551 | defer f.close(); | 6554 | defer f.close(io); |
| 6552 | var file_reader: fs.File.Reader = f.reader(io, &stdin_buffer); | 6555 | var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); |
| 6553 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| | 6556 | break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| |
| 6554 | fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); | 6557 | fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6555 | }; | 6558 | }; |
| ... | @@ -6581,7 +6584,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -6581,7 +6584,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 6581 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; | 6584 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; |
| 6582 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); | 6585 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); |
| 6583 | 6586 | ||
| 6584 | var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); | 6587 | var stdout_writer = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 6585 | const stdout_bw = &stdout_writer.interface; | 6588 | const stdout_bw = &stdout_writer.interface; |
| 6586 | { | 6589 | { |
| 6587 | try stdout_bw.print("Instruction mappings:\n", .{}); | 6590 | try stdout_bw.print("Instruction mappings:\n", .{}); |
| ... | @@ -6912,7 +6915,7 @@ fn cmdFetch( | ... | @@ -6912,7 +6915,7 @@ fn cmdFetch( |
| 6912 | const arg = args[i]; | 6915 | const arg = args[i]; |
| 6913 | if (mem.startsWith(u8, arg, "-")) { | 6916 | if (mem.startsWith(u8, arg, "-")) { |
| 6914 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 6917 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 6915 | try fs.File.stdout().writeAll(usage_fetch); | 6918 | try Io.File.stdout().writeAll(usage_fetch); |
| 6916 | return cleanExit(); | 6919 | return cleanExit(); |
| 6917 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { | 6920 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { |
| 6918 | if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); | 6921 | if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); |
| ... | @@ -6958,7 +6961,7 @@ fn cmdFetch( | ... | @@ -6958,7 +6961,7 @@ fn cmdFetch( |
| 6958 | .path = p, | 6961 | .path = p, |
| 6959 | }; | 6962 | }; |
| 6960 | }; | 6963 | }; |
| 6961 | defer global_cache_directory.handle.close(); | 6964 | defer global_cache_directory.handle.close(io); |
| 6962 | 6965 | ||
| 6963 | var job_queue: Package.Fetch.JobQueue = .{ | 6966 | var job_queue: Package.Fetch.JobQueue = .{ |
| 6964 | .io = io, | 6967 | .io = io, |
| ... | @@ -7021,7 +7024,7 @@ fn cmdFetch( | ... | @@ -7021,7 +7024,7 @@ fn cmdFetch( |
| 7021 | 7024 | ||
| 7022 | const name = switch (save) { | 7025 | const name = switch (save) { |
| 7023 | .no => { | 7026 | .no => { |
| 7024 | var stdout = fs.File.stdout().writerStreaming(&stdout_buffer); | 7027 | var stdout = Io.File.stdout().writerStreaming(&stdout_buffer); |
| 7025 | try stdout.interface.print("{s}\n", .{package_hash_slice}); | 7028 | try stdout.interface.print("{s}\n", .{package_hash_slice}); |
| 7026 | try stdout.interface.flush(); | 7029 | try stdout.interface.flush(); |
| 7027 | return cleanExit(); | 7030 | return cleanExit(); |
| ... | @@ -7043,7 +7046,7 @@ fn cmdFetch( | ... | @@ -7043,7 +7046,7 @@ fn cmdFetch( |
| 7043 | 7046 | ||
| 7044 | // The name to use in case the manifest file needs to be created now. | 7047 | // The name to use in case the manifest file needs to be created now. |
| 7045 | const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path); | 7048 | const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path); |
| 7046 | var manifest, var ast = try loadManifest(gpa, arena, .{ | 7049 | var manifest, var ast = try loadManifest(gpa, arena, io, .{ |
| 7047 | .root_name = try sanitizeExampleName(arena, init_root_name), | 7050 | .root_name = try sanitizeExampleName(arena, init_root_name), |
| 7048 | .dir = build_root.directory.handle, | 7051 | .dir = build_root.directory.handle, |
| 7049 | .color = color, | 7052 | .color = color, |
| ... | @@ -7168,6 +7171,7 @@ fn cmdFetch( | ... | @@ -7168,6 +7171,7 @@ fn cmdFetch( |
| 7168 | 7171 | ||
| 7169 | fn createEmptyDependenciesModule( | 7172 | fn createEmptyDependenciesModule( |
| 7170 | arena: Allocator, | 7173 | arena: Allocator, |
| 7174 | io: Io, | ||
| 7171 | main_mod: *Package.Module, | 7175 | main_mod: *Package.Module, |
| 7172 | dirs: Compilation.Directories, | 7176 | dirs: Compilation.Directories, |
| 7173 | global_options: Compilation.Config, | 7177 | global_options: Compilation.Config, |
| ... | @@ -7176,6 +7180,7 @@ fn createEmptyDependenciesModule( | ... | @@ -7176,6 +7180,7 @@ fn createEmptyDependenciesModule( |
| 7176 | try Package.Fetch.JobQueue.createEmptyDependenciesSource(&source); | 7180 | try Package.Fetch.JobQueue.createEmptyDependenciesSource(&source); |
| 7177 | _ = try createDependenciesModule( | 7181 | _ = try createDependenciesModule( |
| 7178 | arena, | 7182 | arena, |
| 7183 | io, | ||
| 7179 | source.items, | 7184 | source.items, |
| 7180 | main_mod, | 7185 | main_mod, |
| 7181 | dirs, | 7186 | dirs, |
| ... | @@ -7187,6 +7192,7 @@ fn createEmptyDependenciesModule( | ... | @@ -7187,6 +7192,7 @@ fn createEmptyDependenciesModule( |
| 7187 | /// build runner to obtain via `@import("@dependencies")`. | 7192 | /// build runner to obtain via `@import("@dependencies")`. |
| 7188 | fn createDependenciesModule( | 7193 | fn createDependenciesModule( |
| 7189 | arena: Allocator, | 7194 | arena: Allocator, |
| 7195 | io: Io, | ||
| 7190 | source: []const u8, | 7196 | source: []const u8, |
| 7191 | main_mod: *Package.Module, | 7197 | main_mod: *Package.Module, |
| 7192 | dirs: Compilation.Directories, | 7198 | dirs: Compilation.Directories, |
| ... | @@ -7198,7 +7204,7 @@ fn createDependenciesModule( | ... | @@ -7198,7 +7204,7 @@ fn createDependenciesModule( |
| 7198 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); | 7204 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); |
| 7199 | { | 7205 | { |
| 7200 | var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 7206 | var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 7201 | defer tmp_dir.close(); | 7207 | defer tmp_dir.close(io); |
| 7202 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); | 7208 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); |
| 7203 | } | 7209 | } |
| 7204 | 7210 | ||
| ... | @@ -7232,10 +7238,10 @@ fn createDependenciesModule( | ... | @@ -7232,10 +7238,10 @@ fn createDependenciesModule( |
| 7232 | const BuildRoot = struct { | 7238 | const BuildRoot = struct { |
| 7233 | directory: Cache.Directory, | 7239 | directory: Cache.Directory, |
| 7234 | build_zig_basename: []const u8, | 7240 | build_zig_basename: []const u8, |
| 7235 | cleanup_build_dir: ?fs.Dir, | 7241 | cleanup_build_dir: ?Io.Dir, |
| 7236 | 7242 | ||
| 7237 | fn deinit(br: *BuildRoot) void { | 7243 | fn deinit(br: *BuildRoot, io: Io) void { |
| 7238 | if (br.cleanup_build_dir) |*dir| dir.close(); | 7244 | if (br.cleanup_build_dir) |*dir| dir.close(io); |
| 7239 | br.* = undefined; | 7245 | br.* = undefined; |
| 7240 | } | 7246 | } |
| 7241 | }; | 7247 | }; |
| ... | @@ -7304,13 +7310,14 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { | ... | @@ -7304,13 +7310,14 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { |
| 7304 | 7310 | ||
| 7305 | const LoadManifestOptions = struct { | 7311 | const LoadManifestOptions = struct { |
| 7306 | root_name: []const u8, | 7312 | root_name: []const u8, |
| 7307 | dir: fs.Dir, | 7313 | dir: Io.Dir, |
| 7308 | color: Color, | 7314 | color: Color, |
| 7309 | }; | 7315 | }; |
| 7310 | 7316 | ||
| 7311 | fn loadManifest( | 7317 | fn loadManifest( |
| 7312 | gpa: Allocator, | 7318 | gpa: Allocator, |
| 7313 | arena: Allocator, | 7319 | arena: Allocator, |
| 7320 | io: Io, | ||
| 7314 | options: LoadManifestOptions, | 7321 | options: LoadManifestOptions, |
| 7315 | ) !struct { Package.Manifest, Ast } { | 7322 | ) !struct { Package.Manifest, Ast } { |
| 7316 | const manifest_bytes = while (true) { | 7323 | const manifest_bytes = while (true) { |
| ... | @@ -7322,7 +7329,7 @@ fn loadManifest( | ... | @@ -7322,7 +7329,7 @@ fn loadManifest( |
| 7322 | 0, | 7329 | 0, |
| 7323 | ) catch |err| switch (err) { | 7330 | ) catch |err| switch (err) { |
| 7324 | error.FileNotFound => { | 7331 | error.FileNotFound => { |
| 7325 | writeSimpleTemplateFile(Package.Manifest.basename, | 7332 | writeSimpleTemplateFile(io, Package.Manifest.basename, |
| 7326 | \\.{{ | 7333 | \\.{{ |
| 7327 | \\ .name = .{s}, | 7334 | \\ .name = .{s}, |
| 7328 | \\ .version = "{s}", | 7335 | \\ .version = "{s}", |
| ... | @@ -7374,12 +7381,12 @@ fn loadManifest( | ... | @@ -7374,12 +7381,12 @@ fn loadManifest( |
| 7374 | 7381 | ||
| 7375 | const Templates = struct { | 7382 | const Templates = struct { |
| 7376 | zig_lib_directory: Cache.Directory, | 7383 | zig_lib_directory: Cache.Directory, |
| 7377 | dir: fs.Dir, | 7384 | dir: Io.Dir, |
| 7378 | buffer: std.array_list.Managed(u8), | 7385 | buffer: std.array_list.Managed(u8), |
| 7379 | 7386 | ||
| 7380 | fn deinit(templates: *Templates) void { | 7387 | fn deinit(templates: *Templates, io: Io) void { |
| 7381 | templates.zig_lib_directory.handle.close(); | 7388 | templates.zig_lib_directory.handle.close(io); |
| 7382 | templates.dir.close(); | 7389 | templates.dir.close(io); |
| 7383 | templates.buffer.deinit(); | 7390 | templates.buffer.deinit(); |
| 7384 | templates.* = undefined; | 7391 | templates.* = undefined; |
| 7385 | } | 7392 | } |
| ... | @@ -7387,7 +7394,7 @@ const Templates = struct { | ... | @@ -7387,7 +7394,7 @@ const Templates = struct { |
| 7387 | fn write( | 7394 | fn write( |
| 7388 | templates: *Templates, | 7395 | templates: *Templates, |
| 7389 | arena: Allocator, | 7396 | arena: Allocator, |
| 7390 | out_dir: fs.Dir, | 7397 | out_dir: Io.Dir, |
| 7391 | root_name: []const u8, | 7398 | root_name: []const u8, |
| 7392 | template_path: []const u8, | 7399 | template_path: []const u8, |
| 7393 | fingerprint: Package.Fingerprint, | 7400 | fingerprint: Package.Fingerprint, |
| ... | @@ -7435,23 +7442,23 @@ const Templates = struct { | ... | @@ -7435,23 +7442,23 @@ const Templates = struct { |
| 7435 | }); | 7442 | }); |
| 7436 | } | 7443 | } |
| 7437 | }; | 7444 | }; |
| 7438 | fn writeSimpleTemplateFile(file_name: []const u8, comptime fmt: []const u8, args: anytype) !void { | 7445 | fn writeSimpleTemplateFile(io: Io, file_name: []const u8, comptime fmt: []const u8, args: anytype) !void { |
| 7439 | const f = try fs.cwd().createFile(file_name, .{ .exclusive = true }); | 7446 | const f = try fs.cwd().createFile(file_name, .{ .exclusive = true }); |
| 7440 | defer f.close(); | 7447 | defer f.close(io); |
| 7441 | var buf: [4096]u8 = undefined; | 7448 | var buf: [4096]u8 = undefined; |
| 7442 | var fw = f.writer(&buf); | 7449 | var fw = f.writer(&buf); |
| 7443 | try fw.interface.print(fmt, args); | 7450 | try fw.interface.print(fmt, args); |
| 7444 | try fw.interface.flush(); | 7451 | try fw.interface.flush(); |
| 7445 | } | 7452 | } |
| 7446 | 7453 | ||
| 7447 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { | 7454 | fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates { |
| 7448 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { | 7455 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { |
| 7449 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | 7456 | fatal("unable to get cwd: {s}", .{@errorName(err)}); |
| 7450 | }; | 7457 | }; |
| 7451 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { | 7458 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { |
| 7452 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); | 7459 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| 7453 | }; | 7460 | }; |
| 7454 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| { | 7461 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, io, cwd_path, self_exe_path) catch |err| { |
| 7455 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | 7462 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); |
| 7456 | }; | 7463 | }; |
| 7457 | 7464 |
src/print_targets.zig+2-1| ... | @@ -12,6 +12,7 @@ const introspect = @import("introspect.zig"); | ... | @@ -12,6 +12,7 @@ const introspect = @import("introspect.zig"); |
| 12 | 12 | ||
| 13 | pub fn cmdTargets( | 13 | pub fn cmdTargets( |
| 14 | allocator: Allocator, | 14 | allocator: Allocator, |
| 15 | io: Io, | ||
| 15 | args: []const []const u8, | 16 | args: []const []const u8, |
| 16 | out: *std.Io.Writer, | 17 | out: *std.Io.Writer, |
| 17 | native_target: *const Target, | 18 | native_target: *const Target, |
| ... | @@ -20,7 +21,7 @@ pub fn cmdTargets( | ... | @@ -20,7 +21,7 @@ pub fn cmdTargets( |
| 20 | var zig_lib_directory = introspect.findZigLibDir(allocator) catch |err| { | 21 | var zig_lib_directory = introspect.findZigLibDir(allocator) catch |err| { |
| 21 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); | 22 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); |
| 22 | }; | 23 | }; |
| 23 | defer zig_lib_directory.handle.close(); | 24 | defer zig_lib_directory.handle.close(io); |
| 24 | defer allocator.free(zig_lib_directory.path.?); | 25 | defer allocator.free(zig_lib_directory.path.?); |
| 25 | 26 | ||
| 26 | const abilists_contents = zig_lib_directory.handle.readFileAlloc( | 27 | const abilists_contents = zig_lib_directory.handle.readFileAlloc( |