diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index ab130dca8e..5691c327a0 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -24,7 +24,7 @@ pub fn cwd() Dir { return switch (native_os) { .windows => .{ .handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle }, .wasi => .{ .handle = std.options.wasiCwd() }, - else => .{ .handle = std.posix.AT.FDCWD }, + else => .{ .handle = std.posix.At.fdcwd }, }; } diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 21f6840fbe..168378a1ce 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -1339,12 +1339,12 @@ fn dirStatPathPosix( var path_buffer: [posix.PATH_MAX]u8 = undefined; const sub_path_posix = try pathToPosix(sub_path, &path_buffer); - const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0; + const flags: posix.At = .{ .symlink_nofollow = if (!options.follow_symlinks) true else false }; while (true) { try t.checkCancel(); var stat = std.mem.zeroes(posix.Stat); - switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) { + switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, @bitCast(flags)))) { .SUCCESS => return statFromPosix(&stat), .INTR => continue, .CANCELED => return error.Canceled, @@ -1568,7 +1568,7 @@ fn dirAccessPosix( var path_buffer: [posix.PATH_MAX]u8 = undefined; const sub_path_posix = try pathToPosix(sub_path, &path_buffer); - const flags: u32 = @as(u32, if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0); + const flags: posix.At = .{ .symlink_nofollow = if (!options.follow_symlinks) true else false }; const mode: u32 = @as(u32, if (options.read) posix.R_OK else 0) | @@ -1577,7 +1577,7 @@ fn dirAccessPosix( while (true) { try t.checkCancel(); - switch (posix.errno(posix.system.faccessat(dir.handle, sub_path_posix, mode, flags))) { + switch (posix.errno(posix.system.faccessat(dir.handle, sub_path_posix, mode, @bitCast(flags)))) { .SUCCESS => return, .INTR => continue, .CANCELED => return error.Canceled, @@ -2837,7 +2837,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelfExeError!Io.File { const t: *Threaded = @ptrCast(@alignCast(userdata)); switch (native_os) { - .linux, .serenity => return dirOpenFilePosix(t, .{ .handle = posix.AT.FDCWD }, "/proc/self/exe", flags), + .linux, .serenity => return dirOpenFilePosix(t, .{ .handle = posix.At.fdcwd }, "/proc/self/exe", flags), .windows => { // If ImagePathName is a symlink, then it will contain the path of the symlink, // not the path that the symlink points to. However, because we are opening diff --git a/lib/std/c.zig b/lib/std/c.zig index f22112a086..f164702ebb 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -8375,128 +8375,267 @@ pub const port_event = switch (native_os) { else => void, }; -pub const AT = switch (native_os) { - .linux => linux.AT, - .windows => struct { +/// Deprecated Alias to `At` +pub const AT = At; + +pub const At = switch (native_os) { + .emscripten, .linux => linux.At, + .windows => packed struct(u32) { + _: u9 = 0, /// Remove directory instead of unlinking file - pub const REMOVEDIR = 0x200; + removedir: bool = false, + _11: u22 = 0, + + /// DEPRECATED aliase to `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); }, - .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { - pub const FDCWD = -2; + .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => packed struct(u32) { + _: u4 = 0, /// Use effective ids in access check - pub const EACCESS = 0x0010; + eaccess: bool = false, /// Act on the symlink itself not the target - pub const SYMLINK_NOFOLLOW = 0x0020; + symlink_nofollow: bool = false, /// Act on target of symlink - pub const SYMLINK_FOLLOW = 0x0040; + symlink_follow: bool = false, /// Path refers to directory - pub const REMOVEDIR = 0x0080; + removedir: bool = false, + _9: u24 = 0, + + pub const fdcwd: fd_t = -2; + + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; }, - .freebsd => struct { - /// Magic value that specify the use of the current working directory - /// to determine the target of relative file paths in the openat() and - /// similar syscalls. - pub const FDCWD = -100; + .freebsd => packed struct(u32) { + _: u8 = 0, /// Check access using effective user and group ID - pub const EACCESS = 0x0100; + eaccess: bool = false, /// Do not follow symbolic links - pub const SYMLINK_NOFOLLOW = 0x0200; + symlink_nofollow: bool = false, /// Follow symbolic link - pub const SYMLINK_FOLLOW = 0x0400; + symlink_follow: bool = false, /// Remove directory instead of file - pub const REMOVEDIR = 0x0800; + removedir: bool = false, /// Fail if not under dirfd - pub const BENEATH = 0x1000; - }, - .netbsd => struct { + beneath: bool = false, + _14: u19 = 0, + /// Magic value that specify the use of the current working directory /// to determine the target of relative file paths in the openat() and /// similar syscalls. - pub const FDCWD = -100; + pub const fdcwd: fd_t = -100; + + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `beneath` + pub const BENEATH: u32 = @bitCast(At{ .beneath = true }); + + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; + }, + .netbsd => packed struct(u32) { + _: u8 = 0, /// Check access using effective user and group ID - pub const EACCESS = 0x0100; + eaccess: bool = false, /// Do not follow symbolic links - pub const SYMLINK_NOFOLLOW = 0x0200; + symlink_nofollow: bool = false, /// Follow symbolic link - pub const SYMLINK_FOLLOW = 0x0400; + symlink_follow: bool = false, /// Remove directory instead of file - pub const REMOVEDIR = 0x0800; - }, - .dragonfly => struct { - pub const FDCWD = -328243; - pub const SYMLINK_NOFOLLOW = 1; - pub const REMOVEDIR = 2; - pub const EACCESS = 4; - pub const SYMLINK_FOLLOW = 8; - }, - .openbsd => struct { + removedir: bool = false, + _12: u20 = 0, + /// Magic value that specify the use of the current working directory /// to determine the target of relative file paths in the openat() and /// similar syscalls. - pub const FDCWD = -100; - /// Check access using effective user and group ID - pub const EACCESS = 0x01; + pub const fdcwd: fd_t = -100; + + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; + }, + .dragonfly => packed struct(u32) { /// Do not follow symbolic links - pub const SYMLINK_NOFOLLOW = 0x02; - /// Follow symbolic link - pub const SYMLINK_FOLLOW = 0x04; + symlink_nofollow: bool = false, /// Remove directory instead of file - pub const REMOVEDIR = 0x08; + removedir: bool = false, + /// Check access using effective user and group ID + eaccess: bool = false, + /// Follow symbolic link + symlink_follow: bool = false, + _: u28 = 0, + + pub const fdcwd: fd_t = -328243; + + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; }, - .haiku => struct { - pub const FDCWD = -1; - pub const SYMLINK_NOFOLLOW = 0x01; - pub const SYMLINK_FOLLOW = 0x02; - pub const REMOVEDIR = 0x04; - pub const EACCESS = 0x08; - }, - .illumos => struct { + .openbsd => packed struct(u32) { + /// Check access using effective user and group ID + eaccess: bool = false, + /// Do not follow symbolic links + symlink_nofollow: bool = false, + /// Follow symbolic link + symlink_follow: bool = false, + /// Remove directory instead of file + removedir: bool = false, + _: u28 = 0, + /// Magic value that specify the use of the current working directory /// to determine the target of relative file paths in the openat() and /// similar syscalls. - pub const FDCWD: fd_t = @bitCast(@as(u32, 0xffd19553)); + pub const fdcwd: fd_t = -100; + + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + + pub const FDCWD = fdcwd; + }, + .haiku => packed struct(u32) { /// Do not follow symbolic links - pub const SYMLINK_NOFOLLOW = 0x1000; + symlink_nofollow: bool = false, /// Follow symbolic link - pub const SYMLINK_FOLLOW = 0x2000; + symlink_follow: bool = false, /// Remove directory instead of file - pub const REMOVEDIR = 0x1; - pub const TRIGGER = 0x2; + removedir: bool = false, /// Check access using effective user and group ID - pub const EACCESS = 0x4; + eaccess: bool = false, + _: u28 = 0, + + pub const fdcwd: fd_t = -1; + + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; }, - .emscripten => struct { - pub const FDCWD = -100; - pub const SYMLINK_NOFOLLOW = 0x100; - pub const REMOVEDIR = 0x200; - pub const SYMLINK_FOLLOW = 0x400; - pub const NO_AUTOMOUNT = 0x800; - pub const EMPTY_PATH = 0x1000; - pub const STATX_SYNC_TYPE = 0x6000; - pub const STATX_SYNC_AS_STAT = 0x0000; - pub const STATX_FORCE_SYNC = 0x2000; - pub const STATX_DONT_SYNC = 0x4000; - pub const RECURSIVE = 0x8000; + .illumos => packed struct(u32) { + /// Remove directory instead of file + removedir: bool = false, + trigger: bool = false, + /// Check access using effective user and group ID + eaccess: bool = false, + _4: u9 = 0, + /// Do not follow symbolic links + symlink_nofollow: bool = false, + /// Follow symbolic link + symlink_follow: bool = false, + _15: u18 = 0, + + /// Magic value that specify the use of the current working directory + /// to determine the target of relative file paths in the openat() and + /// similar syscalls. + pub const fdcwd: fd_t = @bitCast(@as(u32, 0xffd19553)); + + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `trigger` + pub const TRIGGER: u32 = @bitCast(At{ .trigger = true }); + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; }, - .wasi => struct { - // Match `AT_*` constants in lib/libc/include/wasm-wasi-musl/__header_fcntl.h - pub const EACCESS = 0x0; - pub const SYMLINK_NOFOLLOW = 0x1; - pub const SYMLINK_FOLLOW = 0x2; - pub const REMOVEDIR = 0x4; - /// When linking libc, we follow their convention and use -2 for current working directory. - /// However, without libc, Zig does a different convention: it assumes the - /// current working directory is the first preopen. This behavior can be - /// overridden with a public function called `wasi_cwd` in the root source - /// file. - pub const FDCWD: fd_t = if (builtin.link_libc) -2 else 3; + // Match `AT_*` constants in lib/libc/include/wasm-wasi-musl/__header_fcntl.h + .wasi => packed struct(u32) { + /// Do not follow symbolic links + symlink_nofollow: bool = false, + /// Follow symbolic link + symlink_follow: bool = false, + /// Remove directory instead of file + removedir: bool = false, + _: u29 = 0, + + pub const eaccess: u32 = @bitCast(At{}); + + /// When linking libc, we follow their convention and use -2 for + /// current working directory. However, without libc, Zig does a + /// different convention: it assumes the current working directory is + /// the first preopen. This behavior can be overridden with a public + /// function called `wasi_cwd` in the root source file. + pub const fdcwd: fd_t = if (builtin.link_libc) -2 else 3; + + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `symlink_follow` + pub const SYMLINK_FOLLOW: u32 = @bitCast(At{ .symlink_follow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = eaccess; }, // https://github.com/SerenityOS/serenity/blob/2808b0376406a40e31293bb3bcb9170374e90506/Kernel/API/POSIX/fcntl.h#L49-L52 - .serenity => struct { - pub const FDCWD = -100; - pub const SYMLINK_NOFOLLOW = 0x100; - pub const REMOVEDIR = 0x200; - pub const EACCESS = 0x400; + .serenity => packed struct(u32) { + _: u8 = 0, + /// Do not follow symbolic links + symlink_nofollow: bool = false, + /// Remove directory instead of file + removedir: bool = false, + /// Check access using effective user and group ID + eaccess: bool = false, + _11: u21 = 0, + + pub const fdcwd: fd_t = -100; + + /// DEPRECATED: use `symlink_nofollow` + pub const SYMLINK_NOFOLLOW: u32 = @bitCast(At{ .symlink_nofollow = true }); + /// DEPRECATED: use `removedir` + pub const REMOVEDIR: u32 = @bitCast(At{ .removedir = true }); + /// DEPRECATED: use `eaccess` + pub const EACCESS: u32 = @bitCast(At{ .eaccess = true }); + /// DEPRECATED: use `fdcwd` + pub const FDCWD = fdcwd; }, else => void, }; @@ -10485,7 +10624,7 @@ pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*:0]const u8, mask: u32 pub extern "c" fn inotify_rm_watch(fd: fd_t, wd: c_int) c_int; pub extern "c" fn fstat64(fd: fd_t, buf: *Stat) c_int; -pub extern "c" fn fstatat64(dirfd: fd_t, noalias path: [*:0]const u8, noalias stat_buf: *Stat, flags: u32) c_int; +pub extern "c" fn fstatat64(dirfd: fd_t, noalias path: [*:0]const u8, noalias stat_buf: *Stat, flags: At) c_int; pub extern "c" fn fallocate64(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int; pub extern "c" fn fopen64(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE; pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index d07901a771..a98be767c1 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -187,7 +187,7 @@ pub fn cwd() Dir { } else if (native_os == .wasi) { return .{ .fd = std.options.wasiCwd() }; } else { - return .{ .fd = posix.AT.fdcwd }; + return .{ .fd = posix.At.fdcwd }; } } diff --git a/lib/std/fs/Dir.zig b/lib/std/fs/Dir.zig index 23bd903fe8..738c0ddf12 100644 --- a/lib/std/fs/Dir.zig +++ b/lib/std/fs/Dir.zig @@ -148,7 +148,7 @@ pub const Iterator = switch (native_os) { const stat_info = posix.fstatat( self.dir.fd, name, - posix.AT.SYMLINK_NOFOLLOW, + .{ .symlink_nofollow = true }, ) catch |err| switch (err) { error.NameTooLong => unreachable, error.SymLinkLoop => unreachable, @@ -1112,7 +1112,7 @@ pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void { // directory, so we need to handle that case specifically and translate the error .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos => { // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them) - const fstat = posix.fstatatZ(self.fd, sub_path_c, posix.AT.SYMLINK_NOFOLLOW) catch return e; + const fstat = posix.fstatatZ(self.fd, sub_path_c, .{ .symlink_nofollow = true }) catch return e; const is_dir = fstat.mode & posix.S.IFMT == posix.S.IFDIR; return if (is_dir) error.IsDir else e; }, @@ -1163,7 +1163,7 @@ pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void { const sub_path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path); return self.deleteDirW(sub_path_w.span()); } else if (native_os == .wasi and !builtin.link_libc) { - posix.unlinkat(self.fd, sub_path, posix.AT.REMOVEDIR) catch |err| switch (err) { + posix.unlinkat(self.fd, sub_path, posix.At.REMOVEDIR) catch |err| switch (err) { error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR else => |e| return e, }; @@ -1175,7 +1175,7 @@ pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void { /// Same as `deleteDir` except the parameter is null-terminated. pub fn deleteDirZ(self: Dir, sub_path_c: [*:0]const u8) DeleteDirError!void { - posix.unlinkatZ(self.fd, sub_path_c, posix.AT.REMOVEDIR) catch |err| switch (err) { + posix.unlinkatZ(self.fd, sub_path_c, posix.At.REMOVEDIR) catch |err| switch (err) { error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR else => |e| return e, }; @@ -1184,7 +1184,7 @@ pub fn deleteDirZ(self: Dir, sub_path_c: [*:0]const u8) DeleteDirError!void { /// Same as `deleteDir` except the parameter is WTF16LE, NT prefixed. /// This function is Windows-only. pub fn deleteDirW(self: Dir, sub_path_w: []const u16) DeleteDirError!void { - posix.unlinkatW(self.fd, sub_path_w, posix.AT.REMOVEDIR) catch |err| switch (err) { + posix.unlinkatW(self.fd, sub_path_w, posix.At.REMOVEDIR) catch |err| switch (err) { error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR else => |e| return e, }; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 8948bec2b2..fb226e211f 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1253,7 +1253,7 @@ pub fn rmdir(path: [*:0]const u8) usize { if (@hasField(SYS, "rmdir")) { return syscall1(.rmdir, @intFromPtr(path)); } else { - return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), @as(u32, @bitCast(At{ .removedir_or_handle_fid = .{ .removedir = true } }))); + return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), @as(u32, @bitCast(At{ .removedir = true }))); } } @@ -3573,7 +3573,7 @@ pub const STDERR_FILENO = 2; pub const AT = At; /// matches AT_* and AT_STATX_* pub const At = packed struct(u32) { - _u1: u8 = 0, + _1: u8 = 0, /// Do not follow symbolic links symlink_nofollow: bool = false, /// Remove directory instead of unlinking file diff --git a/lib/std/posix.zig b/lib/std/posix.zig index f5923116e4..0609755a70 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -63,7 +63,9 @@ pub const AF = system.AF; pub const AF_SUN = system.AF_SUN; pub const AI = system.AI; pub const ARCH = system.ARCH; -pub const AT = system.AT; +/// DEPRECATED: use `At` +pub const AT = At; +pub const At = system.At; pub const AT_SUN = system.AT_SUN; pub const CLOCK = system.CLOCK; pub const CPU_COUNT = system.CPU_COUNT; @@ -480,7 +482,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr } defer close(pathfd); - const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) { + const stat = fstatatZ(pathfd, "", .{ .empty_path = true }) catch |err| switch (err) { error.NameTooLong => unreachable, error.FileNotFound => unreachable, error.Streaming => unreachable, @@ -1553,7 +1555,7 @@ pub fn open(file_path: []const u8, flags: O, perm: mode_t) OpenError!fd_t { if (native_os == .windows) { @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API"); } else if (native_os == .wasi and !builtin.link_libc) { - return openat(AT.FDCWD, file_path, flags, perm); + return openat(At.fdcwd, file_path, flags, perm); } const file_path_c = try toPosixPath(file_path); return openZ(&file_path_c, flags, perm); @@ -1943,7 +1945,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError! if (native_os == .windows) { @compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead"); } else if (native_os == .wasi and !builtin.link_libc) { - return symlinkat(target_path, AT.FDCWD, sym_link_path); + return symlinkat(target_path, At.fdcwd, sym_link_path); } const target_path_c = try toPosixPath(target_path); const sym_link_path_c = try toPosixPath(sym_link_path); @@ -2103,7 +2105,7 @@ pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8) LinkError!void { /// On other platforms, both paths are an opaque sequence of bytes with no particular encoding. pub fn link(oldpath: []const u8, newpath: []const u8) LinkError!void { if (native_os == .wasi and !builtin.link_libc) { - return linkat(AT.FDCWD, oldpath, AT.FDCWD, newpath, 0) catch |err| switch (err) { + return linkat(At.fdcwd, oldpath, At.fdcwd, newpath, 0) catch |err| switch (err) { error.NotDir => unreachable, // link() does not support directories else => |e| return e, }; @@ -2163,7 +2165,7 @@ pub fn linkat( const old: RelativePathWasi = .{ .dir_fd = olddir, .relative_path = oldpath }; const new: RelativePathWasi = .{ .dir_fd = newdir, .relative_path = newpath }; const old_flags: wasi.lookupflags_t = .{ - .SYMLINK_FOLLOW = (flags & AT.SYMLINK_FOLLOW) != 0, + .SYMLINK_FOLLOW = (flags & At.SYMLINK_FOLLOW) != 0, }; switch (wasi.path_link( old.dir_fd, @@ -2234,7 +2236,7 @@ pub const UnlinkError = error{ /// See also `unlinkZ`. pub fn unlink(file_path: []const u8) UnlinkError!void { if (native_os == .wasi and !builtin.link_libc) { - return unlinkat(AT.FDCWD, file_path, 0) catch |err| switch (err) { + return unlinkat(At.fdcwd, file_path, 0) catch |err| switch (err) { error.DirNotEmpty => unreachable, // only occurs when targeting directories else => |e| return e, }; @@ -2308,7 +2310,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo /// WASI-only. Same as `unlinkat` but targeting WASI. /// See also `unlinkat`. pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void { - const remove_dir = (flags & AT.REMOVEDIR) != 0; + const remove_dir = (flags & At.REMOVEDIR) != 0; const res = if (remove_dir) wasi.path_remove_directory(dirfd, file_path.ptr, file_path.len) else @@ -2373,7 +2375,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr /// Same as `unlinkat` but `sub_path_w` is WTF16LE, NT prefixed. Windows only. pub fn unlinkatW(dirfd: fd_t, sub_path_w: []const u16, flags: u32) UnlinkatError!void { - const remove_dir = (flags & AT.REMOVEDIR) != 0; + const remove_dir = (flags & At.REMOVEDIR) != 0; return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir }); } @@ -2421,7 +2423,7 @@ pub const RenameError = error{ /// On other platforms, both paths are an opaque sequence of bytes with no particular encoding. pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { if (native_os == .wasi and !builtin.link_libc) { - return renameat(AT.FDCWD, old_path, AT.FDCWD, new_path); + return renameat(At.fdcwd, old_path, At.FDCWD, new_path); } else if (native_os == .windows) { const old_path_w = try windows.sliceToPrefixedFileW(null, old_path); const new_path_w = try windows.sliceToPrefixedFileW(null, new_path); @@ -2747,7 +2749,7 @@ pub const MakeDirError = std.Io.Dir.MakeError; /// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding. pub fn mkdir(dir_path: []const u8, mode: mode_t) MakeDirError!void { if (native_os == .wasi and !builtin.link_libc) { - return mkdirat(AT.FDCWD, dir_path, mode); + return mkdirat(At.fdcwd, dir_path, mode); } else if (native_os == .windows) { const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path); return mkdirW(dir_path_w.span(), mode); @@ -2832,7 +2834,7 @@ pub const DeleteDirError = error{ /// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding. pub fn rmdir(dir_path: []const u8) DeleteDirError!void { if (native_os == .wasi and !builtin.link_libc) { - return unlinkat(AT.FDCWD, dir_path, AT.REMOVEDIR) catch |err| switch (err) { + return unlinkat(At.fdcwd, dir_path, At.REMOVEDIR) catch |err| switch (err) { error.FileSystem => unreachable, // only occurs when targeting files error.IsDir => unreachable, // only occurs when targeting files else => |e| return e, @@ -2959,7 +2961,7 @@ pub const FchdirError = error{ } || UnexpectedError; pub fn fchdir(dirfd: fd_t) FchdirError!void { - if (dirfd == AT.FDCWD) return; + if (dirfd == At.fdcwd) return; while (true) { switch (errno(system.fchdir(dirfd))) { .SUCCESS => return, @@ -3012,7 +3014,7 @@ pub const ReadLinkError = error{ /// On other platforms, the result is an opaque sequence of bytes with no particular encoding. pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { if (native_os == .wasi and !builtin.link_libc) { - return readlinkat(AT.FDCWD, file_path, out_buffer); + return readlinkat(At.fdcwd, file_path, out_buffer); } else if (native_os == .windows) { var file_path_w = try windows.sliceToPrefixedFileW(null, file_path); const result_w = try readlinkW(file_path_w.span(), &file_path_w.data); @@ -3972,7 +3974,7 @@ pub const FStatAtError = FStatError || error{ /// On WASI, `pathname` should be encoded as valid UTF-8. /// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding. /// See also `fstatatZ`. -pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat { +pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: At) FStatAtError!Stat { if (native_os == .wasi and !builtin.link_libc) { @compileError("use std.Io instead"); } else if (native_os == .windows) { @@ -3985,7 +3987,7 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat /// Same as `fstatat` but `pathname` is null-terminated. /// See also `fstatat`. -pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat { +pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: At) FStatAtError!Stat { if (native_os == .wasi and !builtin.link_libc) { @compileError("use std.Io instead"); } diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index aaaaa1d948..5eed5663ee 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -37,7 +37,7 @@ test "check WASI CWD" { if (!builtin.link_libc) { // WASI without-libc hardcodes fd 3 as the FDCWD token so it can be passed directly to WASI calls - try expectEqual(3, posix.AT.FDCWD); + try expectEqual(3, posix.At.fdcwd); } } } @@ -907,7 +907,7 @@ test "pwrite with empty buffer" { } fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void { - const st = try posix.fstatat(dir, file, posix.AT.SYMLINK_NOFOLLOW); + const st = try posix.fstatat(dir, file, .{ .symlink_nofollow = true }); try expectEqual(mode, st.mode & 0b111_111_111); } @@ -932,13 +932,13 @@ test "fchmodat smoke test" { try posix.symlinkat("regfile", tmp.dir.fd, "symlink"); const sym_mode = blk: { - const st = try posix.fstatat(tmp.dir.fd, "symlink", posix.AT.SYMLINK_NOFOLLOW); + const st = try posix.fstatat(tmp.dir.fd, "symlink", .{ .symlink_nofollow = true }); break :blk st.mode & 0b111_111_111; }; try posix.fchmodat(tmp.dir.fd, "regfile", 0o640, 0); try expectMode(tmp.dir.fd, "regfile", 0o640); - try posix.fchmodat(tmp.dir.fd, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW); + try posix.fchmodat(tmp.dir.fd, "regfile", 0o600, posix.At.SYMLINK_NOFOLLOW); try expectMode(tmp.dir.fd, "regfile", 0o600); try posix.fchmodat(tmp.dir.fd, "symlink", 0o640, 0); @@ -946,7 +946,7 @@ test "fchmodat smoke test" { try expectMode(tmp.dir.fd, "symlink", sym_mode); var test_link = true; - posix.fchmodat(tmp.dir.fd, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) { + posix.fchmodat(tmp.dir.fd, "symlink", 0o600, posix.At.SYMLINK_NOFOLLOW) catch |err| switch (err) { error.OperationNotSupported => test_link = false, else => |e| return e, };