summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-06-20 12:57:51 +0900
committerHomu <homu@barosl.com>2016-06-20 12:57:51 +0900
commit0440d26870b36759557fa7ce292c6ccd150511f8 (patch)
tree5c4560d7aa1d0ea19c2cce70453d4f1a58454e92
parentd9f63166dee3bd362af9dc929773d6ae810541f2 (diff)
parent0eb8b4b365fa362c0abd2a5b9da4257e6f2989a3 (diff)
downloadnix-0440d26870b36759557fa7ce292c6ccd150511f8.zip
Auto merge of #377 - aoprisan:master, r=posborne
Added lseek and seek64 I have added lseek and seek64 to unistd, the last one targeting Linux/Android only. I wasn't sure where to place the Whence enum, or if it's a nice of doing, I am quite fresh to Rust.
-rw-r--r--src/unistd.rs35
-rw-r--r--test/test_unistd.rs39
2 files changed, 73 insertions, 1 deletions
diff --git a/src/unistd.rs b/src/unistd.rs
index 89ba3db9..6ab1d920 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -214,6 +214,40 @@ pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
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<libc::off_t> {
+ 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<libc::off64_t> {
+ 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<P: ?Sized + NixPath>(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 410a32d5..188bfbeb 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"))]