From 4680d50a8a225309fc706d032a8dc5e71f819ab5 Mon Sep 17 00:00:00 2001 From: Kamal Marhubi Date: Tue, 9 Feb 2016 19:36:04 -0500 Subject: linux: Add sendfile(2) --- Cargo.toml | 3 ++- src/sys/mod.rs | 3 +++ src/sys/sendfile.rs | 12 ++++++++++++ test/test.rs | 3 +++ test/test_sendfile.rs | 30 ++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/sys/sendfile.rs create mode 100644 test/test_sendfile.rs diff --git a/Cargo.toml b/Cargo.toml index 5df27ec8..093468da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 { + 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(); +} -- cgit v1.2.3