Skip to content

Instantly share code, notes, and snippets.

@sethdusek
Created July 14, 2017 23:08
Show Gist options
  • Save sethdusek/363f028f5f67521eb65a8bf2724bb370 to your computer and use it in GitHub Desktop.
Save sethdusek/363f028f5f67521eb65a8bf2724bb370 to your computer and use it in GitHub Desktop.
use libc::{c_int, splice};
use std::os::unix::io::AsRawFd;
use std::io::Result;
use std::io::prelude::*;
const __NR_copy_file_range: ::libc::c_long = 326;
unsafe fn copy_file_range(fd_in: c_int, off_in: *mut ::libc::loff_t, fd_out: c_int, off_out: *mut ::libc::loff_t, len: usize, flags: u32) -> i64 {
::libc::syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags)
}
pub trait ZeroCopy<T> {
unsafe fn copy_to_fd(&mut self, fd: &mut T, bytes: usize) -> Result<usize>;
}
impl <T, FD> ZeroCopy<FD> for T where T: AsRawFd + Read,
FD: AsRawFd + Write {
default unsafe fn copy_to_fd(&mut self, fd: &mut FD, bytes: usize) -> Result<usize> {
let res = splice(0, ::std::ptr::null_mut(), fd.as_raw_fd(), ::std::ptr::null_mut(), 12, 0);
Ok(res as usize)
}
}
impl <FD> ZeroCopy<FD> for ::std::fs::File {
unsafe fn copy_to_fd(&mut self, fd: &mut FD, bytes: usize) -> Result<usize> {
ZeroCopy::copy_to_fd(self, fd, bytes);
}
}
impl ZeroCopy<::std::fs::File> for ::std::fs::File {
unsafe fn copy_to_fd(&mut self, fd: &mut ::std::fs::File, bytes: usize) -> Result<usize> {
let bytes = copy_file_range(self.as_raw_fd(), ::std::ptr::null_mut(), fd.as_raw_fd(), ::std::ptr::null_mut(), bytes, 0);
if bytes < 0 {
Err(::std::io::Error::last_os_error())
}
else { Ok(bytes as usize) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment