diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index b0810f81a5..618323dce3 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1647,6 +1647,36 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" { try testing.expectError(error.WouldBlock, file2); } +test "read from locked file" { + try testWithAllSupportedPathTypes(struct { + fn impl(ctx: *TestContext) !void { + const filename = try ctx.transformPath("read_lock_file_test.txt"); + + { + const f = try ctx.dir.createFile(filename, .{ .read = true }); + defer f.close(); + var buffer: [1]u8 = undefined; + _ = try f.readAll(&buffer); + } + { + const f = try ctx.dir.createFile(filename, .{ + .read = true, + .lock = .exclusive, + }); + defer f.close(); + const f2 = try ctx.dir.openFile(filename, .{}); + defer f2.close(); + var buffer: [1]u8 = undefined; + if (builtin.os.tag == .windows) { + try std.testing.expectError(error.LockViolation, f2.readAll(&buffer)); + } else { + try std.testing.expectEqual(0, f2.readAll(&buffer)); + } + } + } + }.impl); +} + test "walker" { if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index d277361352..7f4d3290dc 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -599,6 +599,8 @@ pub const ReadFileError = error{ /// The specified network name is no longer available. ConnectionResetByPeer, OperationAborted, + /// Unable to read file due to lock. + LockViolation, Unexpected, }; @@ -630,6 +632,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz .BROKEN_PIPE => return 0, .HANDLE_EOF => return 0, .NETNAME_DELETED => return error.ConnectionResetByPeer, + .LOCK_VIOLATION => return error.LockViolation, else => |err| return unexpectedError(err), } } diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 000f0898d1..d7308850e0 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -802,6 +802,9 @@ pub const ReadError = error{ /// This error occurs in Linux if the process to be read from /// no longer exists. ProcessNotFound, + + /// Unable to read file due to lock. + LockViolation, } || UnexpectedError; /// Returns the number of bytes that were read, which can be less than diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 51da2cc6f9..37f8c534b3 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -1182,6 +1182,7 @@ fn preadAtLeast(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usi error.InputOutput => return error.FileSystem, error.AccessDenied => return error.Unexpected, error.ProcessNotFound => return error.ProcessNotFound, + error.LockViolation => return error.UnableToReadElfFile, }; if (len == 0) return error.UnexpectedEndOfFile; i += len;