Skip to content

Commit 548f2b1

Browse files
committed
Auto merge of #266 - kamalmarhubi:linux-sendfile, r=arcnmx
linux: Add sendfile(2)
2 parents c33ba29 + 4680d50 commit 548f2b1

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ preadv_pwritev = []
2020
signalfd = []
2121

2222
[dependencies]
23-
libc = "0.2.4"
23+
libc = "0.2.7"
2424
bitflags = "0.3.3"
2525

2626
[dev-dependencies]
2727
rand = "0.3.8"
2828
tempdir = "0.3"
29+
tempfile = "2"
2930
nix-test = { path = "nix-test" }
3031

3132
[[test]]

src/sys/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub mod memfd;
1616
#[cfg(not(any(target_os = "ios", target_os = "freebsd", target_os = "dragonfly")))]
1717
pub mod ioctl;
1818

19+
#[cfg(any(target_os = "linux", target_os = "android"))]
20+
pub mod sendfile;
21+
1922
pub mod signal;
2023

2124
#[cfg(any(target_os = "linux", target_os = "android"))]

src/sys/sendfile.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::os::unix::io::RawFd;
2+
use std::ptr;
3+
4+
use libc::{self, off_t};
5+
6+
use {Errno, Result};
7+
8+
pub fn sendfile(out_fd: RawFd, in_fd: RawFd, offset: Option<&mut off_t>, count: usize) -> Result<usize> {
9+
let offset = offset.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut());
10+
let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
11+
Errno::result(ret).map(|r| r as usize)
12+
}

test/test.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ extern crate nix;
33
extern crate libc;
44
extern crate rand;
55
extern crate tempdir;
6+
extern crate tempfile;
67

78
extern crate nix_test as nixtest;
89

910
mod sys;
1011
mod test_net;
1112
mod test_nix_path;
13+
#[cfg(any(target_os = "linux", target_os = "android"))]
14+
mod test_sendfile;
1215
mod test_stat;
1316
mod test_unistd;
1417

test/test_sendfile.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::io::prelude::*;
2+
use std::os::unix::prelude::*;
3+
4+
use tempfile::tempfile;
5+
6+
use libc::off_t;
7+
8+
use nix::unistd::{close, pipe, read};
9+
use nix::sys::sendfile::sendfile;
10+
11+
#[test]
12+
fn test_sendfile() {
13+
const CONTENTS: &'static [u8] = b"abcdef123456";
14+
let mut tmp = tempfile().unwrap();
15+
tmp.write(CONTENTS).unwrap();
16+
17+
let (rd, wr) = pipe().unwrap();
18+
let mut offset: off_t = 5;
19+
let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
20+
21+
assert_eq!(2, res);
22+
23+
let mut buf = [0u8; 1024];
24+
assert_eq!(2, read(rd, &mut buf).unwrap());
25+
assert_eq!(b"f1", &buf[0..2]);
26+
assert_eq!(7, offset);
27+
28+
close(rd).unwrap();
29+
close(wr).unwrap();
30+
}

0 commit comments

Comments
 (0)