From f8ddc3d8732feece71d6ee55cdfc4d61a5a7e16e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 22 Nov 2020 23:28:40 +0100 Subject: [PATCH] std: Fix file locking logic for BSD targets --- lib/std/child_process.zig | 1 + lib/std/fs.zig | 8 +++++--- lib/std/fs/test.zig | 12 ------------ lib/std/os.zig | 4 ++++ 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index de9099076..b61fe9470 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -368,6 +368,7 @@ pub const ChildProcess = struct { error.DeviceBusy => unreachable, error.FileLocksNotSupported => unreachable, error.BadPathName => unreachable, // Windows-only + error.WouldBlock => unreachable, else => |e| return e, } else diff --git a/lib/std/fs.zig b/lib/std/fs.zig index db95b2a7d..2419ea2a5 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -405,7 +405,7 @@ pub const Dir = struct { else => false, }; if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or - (skip_zero_fileno and bsd_entry.d_fileno == 0)) + (skip_zero_fileno and bsd_entry.d_fileno == 0)) { continue :start_over; } @@ -863,8 +863,8 @@ pub const Dir = struct { 0; const lock_flag: u32 = if (has_flock_open_flags) switch (flags.lock) { .None => @as(u32, 0), - .Shared => os.O_SHLOCK, - .Exclusive => os.O_EXLOCK, + .Shared => os.O_SHLOCK | nonblocking_lock_flag, + .Exclusive => os.O_EXLOCK | nonblocking_lock_flag, } else 0; const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0; @@ -1178,6 +1178,7 @@ pub const Dir = struct { error.NoSpaceLeft => unreachable, // not providing O_CREAT error.PathAlreadyExists => unreachable, // not providing O_CREAT error.FileLocksNotSupported => unreachable, // locking folders is not supported + error.WouldBlock => unreachable, // can't happen for directories else => |e| return e, }; return Dir{ .fd = fd }; @@ -1221,6 +1222,7 @@ pub const Dir = struct { error.NoSpaceLeft => unreachable, // not providing O_CREAT error.PathAlreadyExists => unreachable, // not providing O_CREAT error.FileLocksNotSupported => unreachable, // locking folders is not supported + error.WouldBlock => unreachable, // can't happen for directories else => |e| return e, }; return Dir{ .fd = fd }; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 5469192f6..3850758ba 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -691,9 +691,6 @@ test "realpath" { test "open file with exclusive nonblocking lock twice" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 - if (builtin.os.tag == .freebsd) return error.SkipZigTest; - const filename = "file_nonblocking_lock_test.txt"; var tmp = tmpDir(.{}); @@ -709,9 +706,6 @@ test "open file with exclusive nonblocking lock twice" { test "open file with shared and exclusive nonblocking lock" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 - if (builtin.os.tag == .freebsd) return error.SkipZigTest; - const filename = "file_nonblocking_lock_test.txt"; var tmp = tmpDir(.{}); @@ -727,9 +721,6 @@ test "open file with shared and exclusive nonblocking lock" { test "open file with exclusive and shared nonblocking lock" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 - if (builtin.os.tag == .freebsd) return error.SkipZigTest; - const filename = "file_nonblocking_lock_test.txt"; var tmp = tmpDir(.{}); @@ -791,9 +782,6 @@ test "open file with exclusive lock twice, make sure it waits" { test "open file with exclusive nonblocking lock twice (absolute paths)" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759 - if (builtin.os.tag == .freebsd) return error.SkipZigTest; - const allocator = testing.allocator; const file_paths: [1][]const u8 = .{"zig-test-absolute-paths.txt"}; diff --git a/lib/std/os.zig b/lib/std/os.zig index e7c618431..c93f8d72a 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1020,6 +1020,8 @@ pub const OpenError = error{ BadPathName, InvalidUtf8, + + WouldBlock, } || UnexpectedError; /// Open and possibly create a file. Keeps trying if it gets interrupted. @@ -1201,6 +1203,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t) EEXIST => return error.PathAlreadyExists, EBUSY => return error.DeviceBusy, EOPNOTSUPP => return error.FileLocksNotSupported, + EWOULDBLOCK => return error.WouldBlock, else => |err| return unexpectedErrno(err), } } @@ -4187,6 +4190,7 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP const flags = if (builtin.os.tag == .linux) O_PATH | O_NONBLOCK | O_CLOEXEC else O_NONBLOCK | O_CLOEXEC; const fd = openZ(pathname, flags, 0) catch |err| switch (err) { error.FileLocksNotSupported => unreachable, + error.WouldBlock => unreachable, else => |e| return e, }; defer close(fd);