diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index f7ac47961e28999ed44fdcfb7034e0f8aa5d2ff1..9042241b5539935956f79d86c1306764f428c8ad 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -684,7 +684,7 @@ const Os = switch (builtin.os.tag) { path.root_dir.handle.handle else posix.openat(path.root_dir.handle.handle, path.sub_path, dir_open_flags, 0) catch |err| { - fatal("failed to open directory {f}: {s}", .{ path, @errorName(err) }); + fatal("failed to open directory {f}: {t}", .{ path, err }); }; // Empirically the dir has to stay open or else no events are triggered. errdefer if (!skip_open_dir) posix.close(dir_fd); diff --git a/lib/std/Io/File/Reader.zig b/lib/std/Io/File/Reader.zig index 792b20a7163b769f2981a0261d918cea209078ec..2359fad72223a74af46e9bf02e4e8b910638100c 100644 --- a/lib/std/Io/File/Reader.zig +++ b/lib/std/Io/File/Reader.zig @@ -43,7 +43,9 @@ pub const Error = error{ /// In WASI, this error occurs when the file descriptor does /// not hold the required rights to read from it. AccessDenied, - /// Unable to read file due to lock. + /// Unable to read file due to lock. Depending on the `Io` implementation, + /// reading from a locked file may return this error, or may ignore the + /// lock. LockViolation, } || Io.Cancelable || Io.UnexpectedError; diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index fab40001a5c9c4d72081312fe0acd6c41a15ed89..49ca6056d48a5f26a9066fd5a677b230e2801153 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -2838,7 +2838,7 @@ test "discarding sendFile" { const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [256]u8 = undefined; - var file_writer: File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, io, &r_buffer); try file_writer.interface.writeByte('h'); try file_writer.interface.flush(); @@ -2860,7 +2860,7 @@ test "allocating sendFile" { const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; - var file_writer: File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, io, &r_buffer); try file_writer.interface.writeAll("abcd"); try file_writer.interface.flush(); @@ -2884,7 +2884,7 @@ test sendFileReading { const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; - var file_writer: File.Writer = .init(file, &r_buffer); + var file_writer: File.Writer = .init(file, io, &r_buffer); try file_writer.interface.writeAll("abcd"); try file_writer.interface.flush(); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index e33a2bd575694508b1d06cfaac839816f7a31b64..3850ec3e8c1ef026b6915f9e6f3e4f2593755726 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1610,14 +1610,8 @@ test "manage resources correctly" { var discarding: Writer.Discarding = .init(&.{}); var di: SelfInfo = .init; defer di.deinit(gpa); - try printSourceAtAddress( - gpa, - io, - &di, - &discarding.writer, - S.showMyTrace(), - .no_color, - ); + const t: Io.Terminal = .{ .writer = &discarding.writer, .mode = .no_color }; + try printSourceAtAddress(gpa, io, &di, t, S.showMyTrace()); } /// This API helps you track where a value originated and where it was mutated, diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index a52d64ac3ffbabb1b7d421b2330dbe22afbc1ca0..18db4ad8c6e4b224547321d5d01ab07cf5534c57 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -55,11 +55,11 @@ pub const DynLib = struct { // An iterator is provided in order to traverse the linked list in a idiomatic // fashion. const LinkMap = extern struct { - l_addr: usize, - l_name: [*:0]const u8, - l_ld: ?*elf.Dyn, - l_next: ?*LinkMap, - l_prev: ?*LinkMap, + addr: usize, + name: [*:0]const u8, + ld: ?*elf.Dyn, + next: ?*LinkMap, + prev: ?*LinkMap, pub const Iterator = struct { current: ?*LinkMap, @@ -70,7 +70,7 @@ const LinkMap = extern struct { pub fn next(self: *Iterator) ?*LinkMap { if (self.current) |it| { - self.current = it.l_next; + self.current = it.next; return it; } return null; @@ -79,10 +79,10 @@ const LinkMap = extern struct { }; const RDebug = extern struct { - r_version: i32, - r_map: ?*LinkMap, - r_brk: usize, - r_ldbase: usize, + version: i32, + map: ?*LinkMap, + brk: usize, + ldbase: usize, }; /// TODO fix comparisons of extern symbol pointers so we don't need this helper function. @@ -107,8 +107,8 @@ pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { elf.DT_DEBUG => { const ptr = @as(?*RDebug, @ptrFromInt(_DYNAMIC[i].d_val)); if (ptr) |r_debug| { - if (r_debug.r_version != 1) return error.InvalidExe; - break :init r_debug.r_map; + if (r_debug.version != 1) return error.InvalidExe; + break :init r_debug.map; } }, elf.DT_PLTGOT => { @@ -142,6 +142,8 @@ const ElfDynLibError = error{ Streaming, } || posix.OpenError || posix.MMapError; +var static_single_threaded_io: Io.Threaded = .init_single_threaded; + pub const ElfDynLib = struct { strings: [*:0]u8, syms: [*]elf.Sym, @@ -157,7 +159,7 @@ pub const ElfDynLib = struct { dt_gnu_hash: *elf.gnu_hash.Header, }; - fn openPath(path: []const u8, io: Io) !Io.Dir { + fn openPath(io: Io, path: []const u8) !Io.Dir { if (path.len == 0) return error.NotDir; var parts = std.mem.tokenizeScalar(u8, path, '/'); var parent = if (path[0] == '/') try Io.Dir.cwd().openDir(io, "/", .{}) else Io.Dir.cwd(); @@ -172,7 +174,7 @@ pub const ElfDynLib = struct { fn resolveFromSearchPath(io: Io, search_path: []const u8, file_name: []const u8, delim: u8) ?posix.fd_t { var paths = std.mem.tokenizeScalar(u8, search_path, delim); while (paths.next()) |p| { - var dir = openPath(p) catch continue; + var dir = openPath(io, p) catch continue; defer dir.close(io); const fd = posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, @@ -221,7 +223,9 @@ pub const ElfDynLib = struct { } /// Trusts the file. Malicious file will be able to execute arbitrary code. - pub fn open(io: Io, path: []const u8) Error!ElfDynLib { + pub fn open(path: []const u8) Error!ElfDynLib { + const io = static_single_threaded_io.ioBasic(); + const fd = try resolveFromName(io, path); defer posix.close(fd); @@ -551,11 +555,9 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: elf.Versym, vername: []const u8, str } test "ElfDynLib" { - if (native_os != .linux) { - return error.SkipZigTest; - } - + if (native_os != .linux) return error.SkipZigTest; try testing.expectError(error.FileNotFound, ElfDynLib.open("invalid_so.so")); + try testing.expectError(error.FileNotFound, ElfDynLib.openZ("invalid_so.so")); } /// Separated to avoid referencing `WindowsDynLib`, because its field types may not diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 92d3630ac7dcffb31fb90599a6db9cb16dada9e3..8c60ffc343b4b8b71f1a36d6e9e8ad5c7b9b8dd0 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1796,7 +1796,7 @@ test "read from locked file" { const f = try ctx.dir.createFile(io, filename, .{ .read = true }); defer f.close(io); var buffer: [1]u8 = undefined; - _ = try f.read(&buffer); + _ = try f.readPositional(io, &.{&buffer}, 0); } { const f = try ctx.dir.createFile(io, filename, .{ @@ -1806,11 +1806,13 @@ test "read from locked file" { defer f.close(io); const f2 = try ctx.dir.openFile(io, filename, .{}); defer f2.close(io); + // On POSIX locks may be ignored, however on Windows they cause + // LockViolation. var buffer: [1]u8 = undefined; if (builtin.os.tag == .windows) { - try expectError(error.LockViolation, f2.read(&buffer)); + try expectError(error.LockViolation, f2.readPositional(io, &.{&buffer}, 0)); } else { - try expectEqual(0, f2.read(&buffer)); + try expectEqual(0, f2.readPositional(io, &.{&buffer}, 0)); } } } diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 61ef8bb3af2e4a32da6e067daeb6ae4984683337..3997bc70cd5ee3bcc0141be8a3cb38cd8b34d263 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -777,7 +777,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -2759,16 +2759,16 @@ pub fn dl_iterate_phdr( // Last return value from the callback function. while (it.next()) |entry| { - const phdrs: []elf.ElfN.Phdr = if (entry.l_addr != 0) phdrs: { - const ehdr: *elf.ElfN.Ehdr = @ptrFromInt(entry.l_addr); + const phdrs: []elf.ElfN.Phdr = if (entry.addr != 0) phdrs: { + const ehdr: *elf.ElfN.Ehdr = @ptrFromInt(entry.addr); assert(mem.eql(u8, ehdr.ident[0..4], elf.MAGIC)); - const phdrs: [*]elf.ElfN.Phdr = @ptrFromInt(entry.l_addr + ehdr.phoff); + const phdrs: [*]elf.ElfN.Phdr = @ptrFromInt(entry.addr + ehdr.phoff); break :phdrs phdrs[0..ehdr.phnum]; } else getSelfPhdrs(); var info: dl_phdr_info = .{ - .addr = entry.l_addr, - .name = entry.l_name, + .addr = entry.addr, + .name = entry.name, .phdr = phdrs.ptr, .phnum = @intCast(phdrs.len), };