diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig index 81ad077667..046aec3054 100644 --- a/lib/std/Io/net.zig +++ b/lib/std/Io/net.zig @@ -447,7 +447,9 @@ pub const Ip6Address = struct { pub const Unresolved = struct { /// Big endian bytes: [16]u8, - interface_name: ?Interface.Name, + /// Has not been checked to be a valid native interface name. + /// Externally managed memory. + interface_name: ?[]const u8, pub const Parsed = union(enum) { success: Unresolved, @@ -536,7 +538,6 @@ pub const Ip6Address = struct { parts_i += 1; text_i += 1; const name = text[text_i..]; - if (name.len > Interface.Name.max_len) return .{ .interface_name_oversized = text_i }; if (name.len == 0) return .incomplete; interface_name_text = name; text_i = @intCast(text.len); @@ -563,7 +564,7 @@ pub const Ip6Address = struct { return .{ .success = .{ .bytes = @bitCast(parts), - .interface_name = if (interface_name_text) |t| .fromSliceUnchecked(t) else null, + .interface_name = interface_name_text, } }; }, } @@ -646,7 +647,7 @@ pub const Ip6Address = struct { } } } - if (u.interface_name) |n| try w.print("%{s}", .{n.toSlice()}); + if (u.interface_name) |n| try w.print("%{s}", .{n}); } }; @@ -678,6 +679,8 @@ pub const Ip6Address = struct { /// If this is returned, more detailed diagnostics can be obtained by /// calling the `Parsed.init` function. ParseFailed, + /// The interface name is longer than the host operating system supports. + NameTooLong, } || Interface.Name.ResolveError; /// This function requires an `Io` parameter because it must query the operating @@ -689,7 +692,11 @@ pub const Ip6Address = struct { .success => |p| return .{ .bytes = p.bytes, .port = port, - .interface = if (p.interface_name) |n| try n.resolve(io) else .none, + .interface = i: { + const text = p.interface_name orelse break :i .none; + const name: Interface.Name = try .fromSlice(text); + break :i try name.resolve(io); + }, }, else => return error.ParseFailed, }; @@ -946,7 +953,7 @@ pub const Interface = struct { pub const Name = struct { bytes: [max_len:0]u8, - pub const max_len = std.posix.IFNAMESIZE - 1; + pub const max_len = if (@TypeOf(std.posix.IFNAMESIZE) == void) 0 else std.posix.IFNAMESIZE - 1; pub fn toSlice(n: *const Name) []const u8 { return std.mem.sliceTo(&n.bytes, 0); diff --git a/lib/std/c.zig b/lib/std/c.zig index b96ca2e458..877b9ae4e3 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -6855,7 +6855,7 @@ pub const IFNAMESIZE = switch (native_os) { // https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L50 .openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 16, .illumos => 32, - else => void, + else => {}, }; pub const stack_t = switch (native_os) { diff --git a/lib/std/os.zig b/lib/std/os.zig index a3d659d4ca..b7122ca03b 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -201,10 +201,19 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix. } } +pub const FstatatError = error{ + SystemResources, + AccessDenied, + NameTooLong, + FileNotFound, + InvalidUtf8, + Unexpected, +}; + /// WASI-only. Same as `fstatat` but targeting WASI. /// `pathname` should be encoded as valid UTF-8. /// See also `fstatat`. -pub fn fstatat_wasi(dirfd: posix.fd_t, pathname: []const u8, flags: wasi.lookupflags_t) posix.FStatAtError!wasi.filestat_t { +pub fn fstatat_wasi(dirfd: posix.fd_t, pathname: []const u8, flags: wasi.lookupflags_t) FstatatError!wasi.filestat_t { var stat: wasi.filestat_t = undefined; switch (wasi.path_filestat_get(dirfd, flags, pathname.ptr, pathname.len, &stat)) { .SUCCESS => return stat, diff --git a/lib/std/posix.zig b/lib/std/posix.zig index f7b9a449ae..b27468617c 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -4945,6 +4945,7 @@ pub const AccessError = error{ /// Windows-only; file paths provided by the user must be valid WTF-8. /// https://wtf-8.codeberg.page/ InvalidWtf8, + Canceled, } || UnexpectedError; /// check user's permissions for a file