feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileReadPositionalPosix
fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize
File
Code
fn fileReadPositionalPosix(file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
var i: usize = 0;
for (data) |buf| {
if (iovecs_buffer.len - i == 0) break;
if (buf.len != 0) {
iovecs_buffer[i] = .{ .base = buf.ptr, .len = buf.len };
i += 1;
}
}
if (i == 0) return 0;
const dest = iovecs_buffer[0..i];
assert(dest[0].len > 0);
if (native_os == .wasi and !builtin.link_libc) {
const syscall: Syscall = try .start();
while (true) {
var nread: usize = undefined;
switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {
.SUCCESS => {
syscall.finish();
return nread;
},
.INTR, .TIMEDOUT => {
try syscall.checkCancel();
continue;
},
.NOTCONN => |err| return syscall.errnoBug(err),
.CONNRESET => |err| return syscall.errnoBug(err),
.INVAL => |err| return syscall.errnoBug(err),
.FAULT => |err| return syscall.errnoBug(err),
.AGAIN => |err| return syscall.errnoBug(err),
.IO => return syscall.fail(error.InputOutput),
.ISDIR => return syscall.fail(error.IsDir),
.BADF => return syscall.fail(error.IsDir),
.NOBUFS => return syscall.fail(error.SystemResources),
.NOMEM => return syscall.fail(error.SystemResources),
.NXIO => return syscall.fail(error.Unseekable),
.SPIPE => return syscall.fail(error.Unseekable),
.OVERFLOW => return syscall.fail(error.Unseekable),
.NOTCAPABLE => return syscall.fail(error.AccessDenied),
else => |err| return syscall.unexpectedErrno(err),
}
}
}
if (have_preadv) {
const syscall: Syscall = try .start();
while (true) {
const rc = if (native_os == .haiku)
posix.system.readv_pos(file.handle, @bitCast(offset), dest.ptr, @intCast(dest.len))
else
preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
switch (posix.errno(rc)) {
.SUCCESS => {
syscall.finish();
return @bitCast(rc);
},
.INTR, .TIMEDOUT => {
try syscall.checkCancel();
continue;
},
.NXIO => return syscall.fail(error.Unseekable),
.SPIPE => return syscall.fail(error.Unseekable),
.OVERFLOW => return syscall.fail(error.Unseekable),
.NOBUFS => return syscall.fail(error.SystemResources),
.NOMEM => return syscall.fail(error.SystemResources),
.AGAIN => return syscall.fail(error.WouldBlock),
.IO => return syscall.fail(error.InputOutput),
.ISDIR => return syscall.fail(error.IsDir),
.NOTCONN => |err| return syscall.errnoBug(err),
.CONNRESET => |err| return syscall.errnoBug(err),
.INVAL => |err| return syscall.errnoBug(err),
.FAULT => |err| return syscall.errnoBug(err),
.BADF => {
syscall.finish();
if (native_os == .wasi) return error.IsDir;
return error.NotOpenForReading;
},
else => |err| return syscall.unexpectedErrno(err),
}
}
}
const syscall: Syscall = try .start();
while (true) {
const rc = pread_sym(file.handle, dest[0].base, @intCast(dest[0].len), @bitCast(offset));
switch (posix.errno(rc)) {
.SUCCESS => {
syscall.finish();
return @bitCast(rc);
},
.INTR, .TIMEDOUT => {
try syscall.checkCancel();
continue;
},
.NXIO => return syscall.fail(error.Unseekable),
.SPIPE => return syscall.fail(error.Unseekable),
.OVERFLOW => return syscall.fail(error.Unseekable),
.NOBUFS => return syscall.fail(error.SystemResources),
.NOMEM => return syscall.fail(error.SystemResources),
.AGAIN => return syscall.fail(error.WouldBlock),
.IO => return syscall.fail(error.InputOutput),
.ISDIR => return syscall.fail(error.IsDir),
.NOTCONN => |err| return syscall.errnoBug(err),
.CONNRESET => |err| return syscall.errnoBug(err),
.INVAL => |err| return syscall.errnoBug(err),
.FAULT => |err| return syscall.errnoBug(err),
.BADF => {
syscall.finish();
if (native_os == .wasi) return error.IsDir;
return error.NotOpenForReading;
},
else => |err| return syscall.unexpectedErrno(err),
}
}
}