Skip to content

Instantly share code, notes, and snippets.

@SethDusek
Last active July 16, 2017 01:10
Show Gist options
  • Save SethDusek/94700326bb011ed1ffdacfcba886ba79 to your computer and use it in GitHub Desktop.
Save SethDusek/94700326bb011ed1ffdacfcba886ba79 to your computer and use it in GitHub Desktop.
use std::io;
use std::os::unix::io::AsRawFd;
pub struct Stdin(io::Stdin);
pub struct Stdout(io::Stdout);
pub struct Stderr(io::Stderr);
impl AsRawFd for Stdin {
fn as_raw_fd(&self) -> i32 { 0 }
}
impl From<io::Stdin> for Stdin {
fn from(val: io::Stdin) -> Self {
Stdin(val)
}
}
impl AsRawFd for Stdout {
fn as_raw_fd(&self) -> i32 { 1 }
}
impl From<io::Stdout> for Stdout {
fn from(val: io::Stdout) -> Self {
Stdout(val)
}
}
impl ::std::io::Write for Stdout {
fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
self.0.write(buf)
}
fn flush(&mut self) -> ::std::io::Result<()> {
self.0.flush()
}
}
impl AsRawFd for Stderr {
fn as_raw_fd(&self) -> i32 { 2 }
}
impl From<io::Stderr> for Stderr {
fn from(val: io::Stderr) -> Self {
Stderr(val)
}
}
#![feature(specialization)]
extern crate libc;
pub mod zc;
pub mod iowrapper;
pub use zc::ZeroCopy;
extern crate libc;
extern crate zerocopy;
use zerocopy::ZeroCopy;
use std::fs::File;
fn main() {
let mut file = File::open("foo").unwrap();
let out = std::io::stdout();
println!("{:?}", unsafe { file.copy_to_fd(&mut zerocopy::iowrapper::Stdout::from(out), 2) });
}
use libc::{c_int, splice};
use std::io::Result;
use std::io::prelude::*;
use std::os::unix::io::AsRawFd;
use iowrapper::*;
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(self.as_raw_fd(), ::std::ptr::null_mut(), fd.as_raw_fd(), ::std::ptr::null_mut(), bytes, 0);
if res < 0 {
Err(::std::io::Error::last_os_error())
}
else {
Ok(res as usize)
}
}
}
/*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