authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-18 23:28:10-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:10-08:00
logc1b9c46319ff6c76484121c177086b1fbe70d50c
treedbdab5112d3350bdf43362b494986e29126a242b
parentf27bd87ade2e43dce66963f43ce678e361ddbfc2

std.Io: introduce path_only to File.OpenFlags


3 files changed, 15 insertions(+), 3 deletions(-)

lib/std/Io/File.zig+6
...@@ -115,6 +115,12 @@ pub const OpenFlags = struct {...@@ -115,6 +115,12 @@ pub const OpenFlags = struct {
115 /// * On other operating systems, the behavior is implemented with an additional115 /// * On other operating systems, the behavior is implemented with an additional
116 /// `fstat` syscall.116 /// `fstat` syscall.
117 allow_directory: bool = true,117 allow_directory: bool = true,
118 /// Indicates intent for only some operations to be performed on this
119 /// opened file:
120 /// * `close`
121 /// * `stat`
122 /// On Linux and FreeBSD, this corresponds to `std.posix.O.PATH`.
123 path_only: bool = false,
118124
119 /// Open the file with an advisory lock to coordinate with other processes125 /// Open the file with an advisory lock to coordinate with other processes
120 /// accessing it at the same time. An exclusive lock will prevent other126 /// accessing it at the same time. An exclusive lock will prevent other
lib/std/Io/Threaded.zig+3
...@@ -2721,6 +2721,7 @@ fn dirOpenFilePosix(...@@ -2721,6 +2721,7 @@ fn dirOpenFilePosix(
2721 .wasi => .{2721 .wasi => .{
2722 .read = flags.mode != .write_only,2722 .read = flags.mode != .write_only,
2723 .write = flags.mode != .read_only,2723 .write = flags.mode != .read_only,
2724 .NOFOLLOW = !flags.follow_symlinks,
2724 },2725 },
2725 else => .{2726 else => .{
2726 .ACCMODE = switch (flags.mode) {2727 .ACCMODE = switch (flags.mode) {
...@@ -2728,11 +2729,13 @@ fn dirOpenFilePosix(...@@ -2728,11 +2729,13 @@ fn dirOpenFilePosix(
2728 .write_only => .WRONLY,2729 .write_only => .WRONLY,
2729 .read_write => .RDWR,2730 .read_write => .RDWR,
2730 },2731 },
2732 .NOFOLLOW = !flags.follow_symlinks,
2731 },2733 },
2732 };2734 };
2733 if (@hasField(posix.O, "CLOEXEC")) os_flags.CLOEXEC = true;2735 if (@hasField(posix.O, "CLOEXEC")) os_flags.CLOEXEC = true;
2734 if (@hasField(posix.O, "LARGEFILE")) os_flags.LARGEFILE = true;2736 if (@hasField(posix.O, "LARGEFILE")) os_flags.LARGEFILE = true;
2735 if (@hasField(posix.O, "NOCTTY")) os_flags.NOCTTY = !flags.allow_ctty;2737 if (@hasField(posix.O, "NOCTTY")) os_flags.NOCTTY = !flags.allow_ctty;
2738 if (@hasField(posix.O, "PATH") and flags.path_only) os_flags.PATH = true;
27362739
2737 // Use the O locking flags if the os supports them to acquire the lock2740 // Use the O locking flags if the os supports them to acquire the lock
2738 // atomically. Note that the NONBLOCK flag is removed after the openat()2741 // atomically. Note that the NONBLOCK flag is removed after the openat()
lib/std/fs/test.zig+6-3
...@@ -295,8 +295,8 @@ fn testReadLinkAbsolute(io: Io, target_path: []const u8, symlink_path: []const u...@@ -295,8 +295,8 @@ fn testReadLinkAbsolute(io: Io, target_path: []const u8, symlink_path: []const u
295test "File.stat on a File that is a symlink returns Kind.sym_link" {295test "File.stat on a File that is a symlink returns Kind.sym_link" {
296 const io = testing.io;296 const io = testing.io;
297297
298 // This test requires getting a file descriptor of a symlink which298 // This test requires getting a file descriptor of a symlink which is not
299 // is not possible on all targets299 // possible on all targets.
300 switch (builtin.target.os.tag) {300 switch (builtin.target.os.tag) {
301 .windows, .linux => {},301 .windows, .linux => {},
302 else => return error.SkipZigTest,302 else => return error.SkipZigTest,
...@@ -309,7 +309,10 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {...@@ -309,7 +309,10 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
309309
310 try setupSymlink(io, ctx.dir, dir_target_path, "symlink", .{ .is_directory = true });310 try setupSymlink(io, ctx.dir, dir_target_path, "symlink", .{ .is_directory = true });
311311
312 var symlink: Dir = try ctx.dir.openDir(io, "symlink", .{ .follow_symlinks = false });312 var symlink: File = try ctx.dir.openFile(io, "symlink", .{
313 .follow_symlinks = false,
314 .path_only = true,
315 });
313 defer symlink.close(io);316 defer symlink.close(io);
314317
315 const stat = try symlink.stat(io);318 const stat = try symlink.stat(io);