Commit f8ddc3d873

LemonBoy <thatlemon@gmail.com>
2020-11-22 23:28:40
std: Fix file locking logic for BSD targets
1 parent 9d2fe16
Changed files (4)
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"};
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
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 };
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);