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)" {...@@ -1647,6 +1647,36 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
1647 try testing.expectError(error.WouldBlock, file2);1647 try testing.expectError(error.WouldBlock, file2);
1648}1648}
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
1650test "walker" {1680test "walker" {
1651 if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;1681 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{...@@ -599,6 +599,8 @@ pub const ReadFileError = error{
599 /// The specified network name is no longer available.599 /// The specified network name is no longer available.
600 ConnectionResetByPeer,600 ConnectionResetByPeer,
601 OperationAborted,601 OperationAborted,
602 /// Unable to read file due to lock.
603 LockViolation,
602 Unexpected,604 Unexpected,
603};605};
604606
...@@ -630,6 +632,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz...@@ -630,6 +632,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz
630 .BROKEN_PIPE => return 0,632 .BROKEN_PIPE => return 0,
631 .HANDLE_EOF => return 0,633 .HANDLE_EOF => return 0,
632 .NETNAME_DELETED => return error.ConnectionResetByPeer,634 .NETNAME_DELETED => return error.ConnectionResetByPeer,
635 .LOCK_VIOLATION => return error.LockViolation,
633 else => |err| return unexpectedError(err),636 else => |err| return unexpectedError(err),
634 }637 }
635 }638 }
lib/std/posix.zig+3
...@@ -802,6 +802,9 @@ pub const ReadError = error{...@@ -802,6 +802,9 @@ pub const ReadError = error{
802 /// This error occurs in Linux if the process to be read from802 /// This error occurs in Linux if the process to be read from
803 /// no longer exists.803 /// no longer exists.
804 ProcessNotFound,804 ProcessNotFound,
805
806 /// Unable to read file due to lock.
807 LockViolation,
805} || UnexpectedError;808} || UnexpectedError;
806809
807/// Returns the number of bytes that were read, which can be less than810/// 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...@@ -1182,6 +1182,7 @@ fn preadAtLeast(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usi
1182 error.InputOutput => return error.FileSystem,1182 error.InputOutput => return error.FileSystem,
1183 error.AccessDenied => return error.Unexpected,1183 error.AccessDenied => return error.Unexpected,
1184 error.ProcessNotFound => return error.ProcessNotFound,1184 error.ProcessNotFound => return error.ProcessNotFound,
1185 error.LockViolation => return error.UnableToReadElfFile,
1185 };1186 };
1186 if (len == 0) return error.UnexpectedEndOfFile;1187 if (len == 0) return error.UnexpectedEndOfFile;
1187 i += len;1188 i += len;