std.os.windows.ReadFile: handle ERROR_LOCK_VIOLATION

fixes #21500
This commit is contained in:
Jonathan Marler 2024-09-23 16:51:11 -06:00 committed by Andrew Kelley
parent e6fd01a949
commit 73de620ad5
4 changed files with 37 additions and 0 deletions

View File

@ -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;

View File

@ -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),
}
}

View File

@ -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

View File

@ -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;