diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 3c7d687bf7..dd25b29042 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -1605,7 +1605,7 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 { return os.readlinkC(pathname_c, buffer); } -pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError; +pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError || os.FcntlError; pub fn openSelfExe() OpenSelfExeError!File { if (builtin.os.tag == .linux) { diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index d34c6141d9..454f1e503c 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -34,7 +34,7 @@ pub const File = struct { else => 0o666, }; - pub const OpenError = windows.CreateFileError || os.OpenError; + pub const OpenError = windows.CreateFileError || os.OpenError || os.FcntlError; /// TODO https://github.com/ziglang/zig/issues/3802 pub const OpenFlags = struct { diff --git a/lib/std/os.zig b/lib/std/os.zig index 832e2901af..2741d2d8f3 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1146,18 +1146,26 @@ pub const LockCmd = enum { SetLockBlocking, }; +pub const FcntlError = error{ + /// The file is locked by another process + FileLocked, +} || UnexpectedError; + /// Attempts to get lock the file, blocking if the file is locked. -pub fn fcntlFlock(fd: fd_t, lock_cmd: LockCmd, flock_p: *Flock) OpenError!void { - const cmd: i32 = cmdval: { - switch (lock_cmd) { - .GetLock => break :cmdval F_GETLK, - .SetLock => break :cmdval F_SETLK, - .SetLockBlocking => break :cmdval F_SETLKW, - } +pub fn fcntlFlock(fd: fd_t, lock_cmd: LockCmd, flock_p: *Flock) FcntlError!void { + const cmd: i32 = switch (lock_cmd) { + .GetLock => F_GETLK, + .SetLock => F_SETLK, + .SetLockBlocking => F_SETLKW, }; - const rc = system.fcntl(fd, cmd, flock_p); - if (rc < 0) { - std.debug.panic("fcntl error: {}\n", .{rc}); + while (true) { + switch (errno(system.fcntl(fd, cmd, flock_p))) { + 0 => return, + EACCES => return error.FileLocked, + EAGAIN => return error.FileLocked, + EINTR => continue, + else => |err| return unexpectedErrno(err), + } } }