std: implement sendfile on linux#4131
Conversation
daurnimator
left a comment
There was a problem hiding this comment.
Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.
lib/std/os.zig
Outdated
| while (true) { | ||
| var rc: usize = undefined; | ||
| var err: usize = undefined; | ||
| if (builtin.os == .linux) { |
There was a problem hiding this comment.
This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.
|
@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good. |
|
|
Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:
Windows has |
lib/std/os.zig
Outdated
| /// There was insufficient memory for reading from infd. | ||
| NoMem, |
There was a problem hiding this comment.
I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.
By convention, ENOMEM in zig turns into one of these two things:
error.OutOfMemoryif it is userspace heap memory that is exhaustederror.SystemResourcesif it is kernel space memory or other resources that are unavailable.
In this case I believe it would be error.SystemResources.
There was a problem hiding this comment.
Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.
95ca1df to
68186bb
Compare
|
I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly. Next up to to add support |
This changset adds a `sendfile(2)` syscall bindings to the linux bits component. Where available, the `sendfile64(2)` syscall will be transparently called. A wrapping function has also been added to the std.os to transform errno returns to Zig errors. Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
68186bb to
fe10fde
Compare
| trailers: [*]iovec_const, | ||
| trl_cnt: c_int, | ||
| }; | ||
| pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int; |
There was a problem hiding this comment.
I need to double check that the offset parameters here should be u64 instead of off_t.
There was a problem hiding this comment.
I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.
|
Thanks! This is merged into #4611. |
|
Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through. |
This changset adds a
sendfile(2)syscall bindings to the linux bitscomponent. Where available, the
sendfile64(2)syscall will betransparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.