Skip to content

Commit

Permalink
impl linux splicing and teeing
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed Jul 7, 2024
1 parent 79e78aa commit 28c66a5
Showing 1 changed file with 115 additions and 6 deletions.
121 changes: 115 additions & 6 deletions src/read/split.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Traits for splitting and teeing file contents into multiple parallel streams.
mod file {
pub mod file {
use std::io;
use std::ops;

Expand Down Expand Up @@ -58,7 +58,7 @@ mod file {
) -> io::Result<usize>;
}

mod immediate {
pub mod immediate {
use super::{CopyRange, FixedFile, InputFile, OutputFile};

use std::io;
Expand Down Expand Up @@ -235,7 +235,7 @@ mod file {
}
}

mod linux {
pub mod linux {
use super::{CopyRange, FixedFile, InputFile, OutputFile};

use std::fs;
Expand Down Expand Up @@ -463,7 +463,7 @@ mod file {
}
}

mod pipe {
pub mod pipe {
use super::file::{InputFile, OutputFile};

use std::io;
Expand Down Expand Up @@ -509,7 +509,7 @@ mod pipe {
) -> io::Result<usize>;
}

/* mod in_memory { */
/* pub mod in_memory { */
/* use super::{ReadEnd, WriteEnd}; */

/* use std::io; */
Expand Down Expand Up @@ -553,12 +553,14 @@ mod pipe {
/* } */
/* } */

mod linux {
pub mod linux {
use super::super::file::linux::{FileInput, FileOutput};
use super::{ReadEnd, ReadSplicer, Tee, WriteEnd, WriteSplicer};

use std::io;
use std::ops;

Check failure on line 561 in src/read/split.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, stable

unused import: `std::ops`

Check failure on line 561 in src/read/split.rs

View workflow job for this annotation

GitHub Actions / style_and_docs (--no-default-features)

unused import: `std::ops`
use std::os::fd::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;

use libc;

Expand Down Expand Up @@ -655,6 +657,113 @@ mod pipe {
Ok((r, w))
}

pub struct PipeWriteSplicer;

impl WriteSplicer for PipeWriteSplicer {
type InF = FileInput;
type OutP = WritePipe;

fn splice_from_file(
&self,
from: (&Self::InF, u64),
to: &mut Self::OutP,
len: usize,
) -> io::Result<usize> {
let (from, from_start) = from;

let from_fd: libc::c_int = from.fd();
let mut from_offset: libc::loff_t = from_start.try_into().unwrap();
let to_fd: libc::c_int = to.fd();

let flags: libc::c_uint = 0;
let rc: libc::ssize_t = unsafe {
libc::splice(
from_fd,
&mut from_offset,
to_fd,
ptr::null_mut(),
len,
flags,
)
};
if rc < 0 {
return Err(io::Error::last_os_error());
}
let n: usize = rc.try_into().unwrap();
Ok(n)
}
}

pub struct PipeReadSplicer;

impl ReadSplicer for PipeReadSplicer {
type InP = ReadPipe;
type OutF = FileOutput;

fn splice_to_file(
&self,
from: &mut Self::InP,
to: (&mut Self::OutF, u64),
len: usize,
) -> io::Result<usize> {
let (to, to_start) = to;

let from_fd: libc::c_int = from.fd();
let to_fd: libc::c_int = to.fd();
let mut to_offset: libc::loff_t = to_start.try_into().unwrap();

let flags: libc::c_uint = 0;
let rc: libc::ssize_t = unsafe {
libc::splice(from_fd, ptr::null_mut(), to_fd, &mut to_offset, len, flags)
};
if rc < 0 {
return Err(io::Error::last_os_error());
}
let n: usize = rc.try_into().unwrap();
Ok(n)
}
}

pub struct PipeTee;

impl Tee for PipeTee {
type InP = ReadPipe;
type OutP = WritePipe;

fn tee(&self, from: &Self::InP, to: &mut Self::OutP, len: usize) -> io::Result<usize> {
let from_fd: libc::c_int = from.fd();
let to_fd: libc::c_int = to.fd();

let flags: libc::c_uint = 0;
let rc: libc::ssize_t = unsafe { libc::tee(from_fd, to_fd, len, flags) };
if rc < 0 {
return Err(io::Error::last_os_error());
}
let n: usize = rc.try_into().unwrap();
Ok(n)
}

fn splice(
&self,
from: &mut Self::InP,
to: &mut Self::OutP,
len: usize,
) -> io::Result<usize> {
let from_fd: libc::c_int = from.fd();
let to_fd: libc::c_int = to.fd();

let flags: libc::c_uint = 0;
let rc: libc::ssize_t = unsafe {
libc::splice(from_fd, ptr::null_mut(), to_fd, ptr::null_mut(), len, flags)
};
if rc < 0 {
return Err(io::Error::last_os_error());
}
let n: usize = rc.try_into().unwrap();
Ok(n)
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down

0 comments on commit 28c66a5

Please sign in to comment.