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 {
115115 /// * On other operating systems, the behavior is implemented with an additional
116116 /// `fstat` syscall.
117117 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
119125 /// Open the file with an advisory lock to coordinate with other processes
120126 /// accessing it at the same time. An exclusive lock will prevent other
lib/std/Io/Threaded.zig+3
......@@ -2721,6 +2721,7 @@ fn dirOpenFilePosix(
27212721 .wasi => .{
27222722 .read = flags.mode != .write_only,
27232723 .write = flags.mode != .read_only,
2724 .NOFOLLOW = !flags.follow_symlinks,
27242725 },
27252726 else => .{
27262727 .ACCMODE = switch (flags.mode) {
......@@ -2728,11 +2729,13 @@ fn dirOpenFilePosix(
27282729 .write_only => .WRONLY,
27292730 .read_write => .RDWR,
27302731 },
2732 .NOFOLLOW = !flags.follow_symlinks,
27312733 },
27322734 };
27332735 if (@hasField(posix.O, "CLOEXEC")) os_flags.CLOEXEC = true;
27342736 if (@hasField(posix.O, "LARGEFILE")) os_flags.LARGEFILE = true;
27352737 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
27372740 // Use the O locking flags if the os supports them to acquire the lock
27382741 // 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
295295test "File.stat on a File that is a symlink returns Kind.sym_link" {
296296 const io = testing.io;
297297
298 // This test requires getting a file descriptor of a symlink which
299 // is not possible on all targets
298 // This test requires getting a file descriptor of a symlink which is not
299 // possible on all targets.
300300 switch (builtin.target.os.tag) {
301301 .windows, .linux => {},
302302 else => return error.SkipZigTest,
......@@ -309,7 +309,10 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
309309
310310 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 });
313316 defer symlink.close(io);
314317
315318 const stat = try symlink.stat(io);