diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index b0810f81a548e74f0bdddc963a0ae71d8d71c19d..618323dce364e0b32069a2af801850c4f418a902 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 d277361352657adc4e28f9d9f7241ff1290ba4fd..7f4d3290dc2c5fcfd5d180e39f6a7dd08c7d1976 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 000f0898d18f2517180e615cf4d268277c4730bc..d7308850e0724c3ceb14ddf51c24bf92238c6fb4 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 51da2cc6f93ad6c14023cc5a2dfe23d4ff837057..37f8c534b39a178b640dd78681e8c7f6302fa215 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;