Skip to content

sendfile syscall #60689

Closed
Closed
@arobase-che

Description

@arobase-che

Should we implement the sendfile syscall to TCPStream and/or UDPStream ?

Even if it's not totally portable (Linux and BSD, windows using transmitfile), I may be a convenient way to send a file effectively.

Activity

hellow554

hellow554 commented on May 10, 2019

@hellow554
Contributor

What about macOS? At least all tier1 targets should be supported at least.
Also I'm not really convinced why this should be in std and not in an own crate. Maybe you can elaborate it further and convince me.

@rustbot modify labels: C-enhancement T-libs

added
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
on May 10, 2019
added
C-feature-requestCategory: A feature request, i.e: not implemented / a PR.
and removed
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
on May 10, 2019
arobase-che

arobase-che commented on May 10, 2019

@arobase-che
Author

Should work on macOS too but i never had used macOS. Mac OS sendfile documentation


I'm not sure it should be in std. Actually, it's a syscall so a very low level feature. As send, accept, bind, recvfrom, ... that are already in std::net. Other languages add it to the std (Python), Go use it internally in his « std » but doesn't provide a way to use it with a socket). But others languages as Haskell uses external lib. Some simply don't (D socket's)

I know i may be more convincing but I'm not sure myself ! In fact, i'm asking it.

It seems to me to be the right way to add it to the std. But maybe it's because I don't know how it could be implemented from an external crate.

abonander

abonander commented on May 10, 2019

@abonander
Contributor

This could be an internal specialization for io::copy(), and/or maybe exposed in std::os::unix::io as

pub fn send_file<R: AsRawFd, W: AsRawFd>(r: &mut R, w: &mut W) -> io::Result<u64> {...}

Windows actually has a painfully close equivalent but it's specifically to copy from a file handle to a socket (which are separate object types in the Windows API) whereas sendfile() works for any pair of file descriptors, so it couldn't be the same interface unless separate traits were used for the read side and the write side and one was only implemented by File and the other by the net stream types.

https://docs.microsoft.com/en-us/windows/desktop/api/mswsock/nf-mswsock-transmitfile

abonander

abonander commented on May 10, 2019

@abonander
Contributor

@arobase-che sendfile() is actually already available in the the libc crate but that's the unsafe extern bindings to the actual function in sys/sendfile.h.

It's of course completely possible to build a safe wrapper around it and it's actually pretty trivial:

extern crate libc;
use std::os::unix::io::AsRawFd;
use std::{io, ptr};


// mutability is not technically required but it fits API conventions
pub fn send_file<R: AsRawFd, W: AsRawFd>(r: &mut R, w: &mut W) -> io::Result<usize> {
    // parameter ordering is reversed
    // null pointer is an out-pointer for the offset after the read, if not null it doesn't update the file cursors which we actually do want
    // last argument is the maximum number of bytes to copy but 
    // the documentation says it stops at 2^31-1 regardless of arch
    match unsafe { libc::sendfile(w.as_raw_fd(), r.as_raw_fd(), ptr::null_mut(), usize::MAX) } {
        -1 => Err(io::Error::last_os_error()),
        copied => Ok(copied as usize), 
    } 
}
abonander

abonander commented on May 10, 2019

@abonander
Contributor

The libc wrapper function for reference: http://man7.org/linux/man-pages/man2/sendfile.2.html

the8472

the8472 commented on May 11, 2019

@the8472
Member

This could be an internal specialization for io::copy()

That would be quite a rabbit hole. There are lots of special copy syscalls on linux.

splice: any -> pipe; pipe -> any
vmsplice: &'static [u8] -> pipe
sendfile: mmapable fd -> socket
copy_file_range: originally just regular -> regular on same file system, but support is expanding

steveklabnik

steveklabnik commented on Mar 27, 2020

@steveklabnik
Member

Triage: I don't think this was ever implemented.

10 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @steveklabnik@hellow554@the8472@jonas-schievink@arobase-che

        Issue actions

          sendfile syscall · Issue #60689 · rust-lang/rust