authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2024-09-23 16:51:11-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-05 00:36:49-07:00
log73de620ad50121bacb0b9b376efd50b5444485b8
tree467046cd1f0d74bfc281e35f613d343064870dc4
parente6fd01a9493bed097271f07cd2493b51df51c98d

std.os.windows.ReadFile: handle ERROR_LOCK_VIOLATION

fixes #21500

4 files changed, 37 insertions(+), 0 deletions(-)

lib/std/fs/test.zig+30
......@@ -1647,6 +1647,36 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
16471647 try testing.expectError(error.WouldBlock, file2);
16481648}
16491649
1650test "read from locked file" {
1651 try testWithAllSupportedPathTypes(struct {
1652 fn impl(ctx: *TestContext) !void {
1653 const filename = try ctx.transformPath("read_lock_file_test.txt");
1654
1655 {
1656 const f = try ctx.dir.createFile(filename, .{ .read = true });
1657 defer f.close();
1658 var buffer: [1]u8 = undefined;
1659 _ = try f.readAll(&buffer);
1660 }
1661 {
1662 const f = try ctx.dir.createFile(filename, .{
1663 .read = true,
1664 .lock = .exclusive,
1665 });
1666 defer f.close();
1667 const f2 = try ctx.dir.openFile(filename, .{});
1668 defer f2.close();
1669 var buffer: [1]u8 = undefined;
1670 if (builtin.os.tag == .windows) {
1671 try std.testing.expectError(error.LockViolation, f2.readAll(&buffer));
1672 } else {
1673 try std.testing.expectEqual(0, f2.readAll(&buffer));
1674 }
1675 }
1676 }
1677 }.impl);
1678}
1679
16501680test "walker" {
16511681 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
16521682
lib/std/os/windows.zig+3
......@@ -599,6 +599,8 @@ pub const ReadFileError = error{
599599 /// The specified network name is no longer available.
600600 ConnectionResetByPeer,
601601 OperationAborted,
602 /// Unable to read file due to lock.
603 LockViolation,
602604 Unexpected,
603605};
604606
......@@ -630,6 +632,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz
630632 .BROKEN_PIPE => return 0,
631633 .HANDLE_EOF => return 0,
632634 .NETNAME_DELETED => return error.ConnectionResetByPeer,
635 .LOCK_VIOLATION => return error.LockViolation,
633636 else => |err| return unexpectedError(err),
634637 }
635638 }
lib/std/posix.zig+3
......@@ -802,6 +802,9 @@ pub const ReadError = error{
802802 /// This error occurs in Linux if the process to be read from
803803 /// no longer exists.
804804 ProcessNotFound,
805
806 /// Unable to read file due to lock.
807 LockViolation,
805808} || UnexpectedError;
806809
807810/// Returns the number of bytes that were read, which can be less than
lib/std/zig/system.zig+1
......@@ -1182,6 +1182,7 @@ fn preadAtLeast(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usi
11821182 error.InputOutput => return error.FileSystem,
11831183 error.AccessDenied => return error.Unexpected,
11841184 error.ProcessNotFound => return error.ProcessNotFound,
1185 error.LockViolation => return error.UnableToReadElfFile,
11851186 };
11861187 if (len == 0) return error.UnexpectedEndOfFile;
11871188 i += len;