feature. See also
. The project being documented here (as the example) is the Zig library itself.
Dispatch.fileWriteFilePositional
fn fileWriteFilePositional(
userdata: ?*anyopaque,
file: File,
header: []const u8,
file_reader: *File.Reader,
limit: Io.Limit,
offset: u64,
) File.WriteFilePositionalError!usize
File
Code
fn fileWriteFilePositional(
userdata: ?*anyopaque,
file: File,
header: []const u8,
file_reader: *File.Reader,
limit: Io.Limit,
offset: u64,
) File.WriteFilePositionalError!usize {
const ev: *Evented = @ptrCast(@alignCast(userdata));
const reader_buffered = file_reader.interface.buffered();
if (reader_buffered.len >= @backingInt(limit)) {
const n = try fileWritePositional(
ev,
file,
header,
&.{limit.slice(reader_buffered)},
1,
offset,
);
file_reader.interface.toss(n -| header.len);
return n;
}
const out_fd = file.handle;
const in_fd = file_reader.file.handle;
if (file_reader.size) |size| {
if (size - file_reader.pos == 0) {
if (reader_buffered.len != 0) {
const n = try fileWritePositional(
ev,
file,
header,
&.{limit.slice(reader_buffered)},
1,
offset,
);
file_reader.interface.toss(n -| header.len);
return n;
} else {
return error.EndOfStream;
}
}
}
if (@atomicLoad(UseFcopyfile, &ev.use_fcopyfile, .monotonic) == .disabled)
return error.Unimplemented;
if (file_reader.pos != 0) return error.Unimplemented;
if (offset != 0) return error.Unimplemented;
if (limit != .unlimited) return error.Unimplemented;
const size = file_reader.getSize() catch return error.Unimplemented;
if (header.len != 0 or reader_buffered.len != 0) {
const n = try fileWritePositional(
ev,
file,
header,
&.{limit.slice(reader_buffered)},
1,
offset,
);
file_reader.interface.toss(n -| header.len);
return n;
}
while (true) {
const rc = c.fcopyfile(in_fd, out_fd, null, .{ .DATA = true });
switch (c.errno(rc)) {
.SUCCESS => break,
.INTR => {},
.OPNOTSUPP => {
// something else.
@atomicStore(UseFcopyfile, &ev.use_fcopyfile, .disabled, .monotonic);
return 0;
},
else => |e| {
assert(error.Unexpected == switch (e) {
.NOMEM => return error.SystemResources,
.INVAL => |err| errnoBug(err),
else => |err| unexpectedErrno(err),
});
return 0;
},
}
}
file_reader.pos = size;
return size;
}