feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileSeekBy
fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!void
File
Code
fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!void {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
if (is_windows) {
var iosb: windows.IO_STATUS_BLOCK = undefined;
var info: windows.FILE.POSITION_INFORMATION = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryInformationFile(
file.handle,
&iosb,
&info,
@sizeOf(windows.FILE.POSITION_INFORMATION),
.Position,
)) {
.SUCCESS => break,
.CANCELLED => try syscall.checkCancel(),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.PIPE_NOT_AVAILABLE => return syscall.fail(error.Unseekable),
else => |status| return syscall.unexpectedNtstatus(status),
};
info.CurrentByteOffset = @bitCast((if (offset >= 0) std.math.add(
u64,
@bitCast(info.CurrentByteOffset),
@intCast(offset),
) else std.math.sub(
u64,
@bitCast(info.CurrentByteOffset),
@intCast(-offset),
)) catch |err| switch (err) {
error.Overflow => return syscall.fail(error.Unseekable),
});
while (true) switch (windows.ntdll.NtSetInformationFile(
file.handle,
&iosb,
&info,
@sizeOf(windows.FILE.POSITION_INFORMATION),
.Position,
)) {
.SUCCESS => return syscall.finish(),
.CANCELLED => try syscall.checkCancel(),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.PIPE_NOT_AVAILABLE => return syscall.fail(error.Unseekable),
else => |status| return syscall.unexpectedNtstatus(status),
};
}
if (native_os == .wasi and !builtin.link_libc) {
var new_offset: std.os.wasi.filesize_t = undefined;
const syscall: Syscall = try .start();
while (true) {
switch (std.os.wasi.fd_seek(file.handle, offset, .CUR, &new_offset)) {
.SUCCESS => {
syscall.finish();
return;
},
.INTR => {
try syscall.checkCancel();
continue;
},
else => |e| {
syscall.finish();
switch (e) {
.BADF => |err| return errnoBug(err),
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
.NXIO => return error.Unseekable,
.NOTCAPABLE => return error.AccessDenied,
else => |err| return posix.unexpectedErrno(err),
}
},
}
}
}
if (posix.SEEK == void) return error.Unseekable;
if (native_os == .linux and !builtin.link_libc and @sizeOf(posix.system.syscall_arg_t) == 4) {
var result: i64 = undefined;
const syscall: Syscall = try .start();
while (true) {
switch (posix.errno(posix.system.llseek(file.handle, offset, &result, posix.SEEK.CUR))) {
.SUCCESS => {
syscall.finish();
return;
},
.INTR => {
try syscall.checkCancel();
continue;
},
else => |e| {
syscall.finish();
switch (e) {
.BADF => |err| return errnoBug(err),
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
.NXIO => return error.Unseekable,
else => |err| return posix.unexpectedErrno(err),
}
},
}
}
}
const syscall: Syscall = try .start();
while (true) {
switch (posix.errno(lseek_sym(file.handle, offset, posix.SEEK.CUR))) {
.SUCCESS => {
syscall.finish();
return;
},
.INTR => {
try syscall.checkCancel();
continue;
},
else => |e| {
syscall.finish();
switch (e) {
.BADF => |err| return errnoBug(err),
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
.NXIO => return error.Unseekable,
else => |err| return posix.unexpectedErrno(err),
}
},
}
}
}