diff options
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/sys/mod.rs | 3 | ||||
-rw-r--r-- | src/sys/sendfile.rs | 12 | ||||
-rw-r--r-- | test/test.rs | 3 | ||||
-rw-r--r-- | test/test_sendfile.rs | 30 |
5 files changed, 50 insertions, 1 deletions
@@ -20,12 +20,13 @@ preadv_pwritev = [] signalfd = [] [dependencies] -libc = "0.2.4" +libc = "0.2.7" bitflags = "0.3.3" [dev-dependencies] rand = "0.3.8" tempdir = "0.3" +tempfile = "2" nix-test = { path = "nix-test" } [[test]] diff --git a/src/sys/mod.rs b/src/sys/mod.rs index c7fdc4dc..de449b76 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -16,6 +16,9 @@ pub mod memfd; #[cfg(not(any(target_os = "ios", target_os = "freebsd", target_os = "dragonfly")))] pub mod ioctl; +#[cfg(any(target_os = "linux", target_os = "android"))] +pub mod sendfile; + pub mod signal; #[cfg(any(target_os = "linux", target_os = "android"))] diff --git a/src/sys/sendfile.rs b/src/sys/sendfile.rs new file mode 100644 index 00000000..2c39ea90 --- /dev/null +++ b/src/sys/sendfile.rs @@ -0,0 +1,12 @@ +use std::os::unix::io::RawFd; +use std::ptr; + +use libc::{self, off_t}; + +use {Errno, Result}; + +pub fn sendfile(out_fd: RawFd, in_fd: RawFd, offset: Option<&mut off_t>, count: usize) -> Result<usize> { + let offset = offset.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut()); + let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) }; + Errno::result(ret).map(|r| r as usize) +} diff --git a/test/test.rs b/test/test.rs index b5e9847e..53f61fb5 100644 --- a/test/test.rs +++ b/test/test.rs @@ -3,12 +3,15 @@ extern crate nix; extern crate libc; extern crate rand; extern crate tempdir; +extern crate tempfile; extern crate nix_test as nixtest; mod sys; mod test_net; mod test_nix_path; +#[cfg(any(target_os = "linux", target_os = "android"))] +mod test_sendfile; mod test_stat; mod test_unistd; diff --git a/test/test_sendfile.rs b/test/test_sendfile.rs new file mode 100644 index 00000000..7db65b9a --- /dev/null +++ b/test/test_sendfile.rs @@ -0,0 +1,30 @@ +use std::io::prelude::*; +use std::os::unix::prelude::*; + +use tempfile::tempfile; + +use libc::off_t; + +use nix::unistd::{close, pipe, read}; +use nix::sys::sendfile::sendfile; + +#[test] +fn test_sendfile() { + const CONTENTS: &'static [u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write(CONTENTS).unwrap(); + + let (rd, wr) = pipe().unwrap(); + let mut offset: off_t = 5; + let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap(); + + assert_eq!(2, res); + + let mut buf = [0u8; 1024]; + assert_eq!(2, read(rd, &mut buf).unwrap()); + assert_eq!(b"f1", &buf[0..2]); + assert_eq!(7, offset); + + close(rd).unwrap(); + close(wr).unwrap(); +} |