From 0eb8b4b365fa362c0abd2a5b9da4257e6f2989a3 Mon Sep 17 00:00:00 2001 From: Andrei Oprisan Date: Wed, 8 Jun 2016 15:52:26 +0300 Subject: [PATCH] Added lseek to unistd llseek and lseek64 impl Whence fixed formatting awful typo when refactoring no llseek wrong test name using off64_t got rid of offset Added SeekHole/Data; formatted test; SeekCur/Set/End use libc constants --- src/unistd.rs | 35 ++++++++++++++++++++++++++++++++++- test/test_unistd.rs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/unistd.rs b/src/unistd.rs index 89ba3db90f047..6ab1d920e47c7 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -214,6 +214,40 @@ pub fn write(fd: RawFd, buf: &[u8]) -> Result { Errno::result(res).map(|r| r as usize) } +pub enum Whence { + SeekSet, + SeekCur, + SeekEnd, + SeekData, + SeekHole +} + +impl Whence { + fn to_libc_type(&self) -> c_int { + match self { + &Whence::SeekSet => libc::SEEK_SET, + &Whence::SeekCur => libc::SEEK_CUR, + &Whence::SeekEnd => libc::SEEK_END, + &Whence::SeekData => 3, + &Whence::SeekHole => 4 + } + } + +} + +pub fn lseek(fd: RawFd, offset: libc::off_t, whence: Whence) -> Result { + let res = unsafe { libc::lseek(fd, offset, whence.to_libc_type()) }; + + Errno::result(res).map(|r| r as libc::off_t) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result { + let res = unsafe { libc::lseek64(fd, offset, whence.to_libc_type()) }; + + Errno::result(res).map(|r| r as libc::off64_t) +} + pub fn pipe() -> Result<(RawFd, RawFd)> { unsafe { let mut fds: [c_int; 2] = mem::uninitialized(); @@ -292,7 +326,6 @@ pub fn unlink(path: &P) -> Result<()> { libc::unlink(cstr.as_ptr()) } })); - Errno::result(res).map(drop) } diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 410a32d5201d7..188bfbeba9c9b 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -3,6 +3,13 @@ use nix::unistd::ForkResult::*; use nix::sys::wait::*; use std::ffi::CString; +use std::io::{Write, Read}; +use tempfile::tempfile; +use libc::off_t; +use std::os::unix::prelude::*; + + + #[test] fn test_fork_and_waitpid() { let pid = fork(); @@ -112,6 +119,38 @@ macro_rules! execve_test_factory( ) ); +#[test] +fn test_lseek() { + const CONTENTS: &'static [u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write(CONTENTS).unwrap(); + + let offset: off_t = 5; + lseek(tmp.as_raw_fd(), offset, Whence::SeekSet).unwrap(); + + let mut buf = String::new(); + tmp.read_to_string(&mut buf).unwrap(); + assert_eq!(b"f123456", buf.as_bytes()); + + close(tmp.as_raw_fd()).unwrap(); +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +#[test] +fn test_lseek64() { + const CONTENTS: &'static [u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write(CONTENTS).unwrap(); + + lseek64(tmp.as_raw_fd(), 5, Whence::SeekSet).unwrap(); + + let mut buf = String::new(); + tmp.read_to_string(&mut buf).unwrap(); + assert_eq!(b"f123456", buf.as_bytes()); + + close(tmp.as_raw_fd()).unwrap(); +} + execve_test_factory!(test_execve, execve, b"/bin/sh", b"/system/bin/sh"); #[cfg(any(target_os = "linux", target_os = "android"))]