diff options
author | Kamal Marhubi <kamal@marhubi.com> | 2016-02-09 21:15:59 -0500 |
---|---|---|
committer | Kamal Marhubi <kamal@marhubi.com> | 2016-02-14 23:41:57 -0500 |
commit | c381997c0ae55cea2e1e6ff1e89f424472eda0ef (patch) | |
tree | a16a7761a932b720fc4c9d5c2c9a02c07c652518 /src/fcntl.rs | |
parent | 548f2b1b2696ecb581c79688a130d7f9cd4d1e28 (diff) | |
download | nix-c381997c0ae55cea2e1e6ff1e89f424472eda0ef.zip |
linux: Add splice(2), tee(2), vmsplice(2)
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r-- | src/fcntl.rs | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index 2b1c7b89..c98674c7 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -3,6 +3,11 @@ use libc::{c_int, c_uint}; use sys::stat::Mode; use std::os::unix::io::RawFd; +#[cfg(any(target_os = "linux", target_os = "android"))] +use sys::uio::IoVec; // For vmsplice +#[cfg(any(target_os = "linux", target_os = "android"))] +use libc; + pub use self::consts::*; pub use self::ffi::flock; @@ -182,8 +187,43 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> { } #[cfg(any(target_os = "linux", target_os = "android"))] +pub fn splice(fd_in: RawFd, off_in: Option<&mut libc::loff_t>, + fd_out: RawFd, off_out: Option<&mut libc::loff_t>, + len: usize, flags: SpliceFFlags) -> Result<usize> { + use std::ptr; + let off_in = off_in.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut()); + let off_out = off_out.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut()); + + let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> { + let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<usize> { + let ret = unsafe { + libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits()) + }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] mod consts { - use libc::c_int; + use libc::{self, c_int, c_uint}; + + bitflags! { + flags SpliceFFlags: c_uint { + const SPLICE_F_MOVE = libc::SPLICE_F_MOVE, + const SPLICE_F_NONBLOCK = libc::SPLICE_F_NONBLOCK, + const SPLICE_F_MORE = libc::SPLICE_F_MORE, + const SPLICE_F_GIFT = libc::SPLICE_F_GIFT, + } + } bitflags!( flags OFlag: c_int { |