Skip to content

Commit

Permalink
add support for opendir/fdopendir
Browse files Browse the repository at this point in the history
  • Loading branch information
Mic92 committed Mar 19, 2017
1 parent 5c90289 commit 1eb7cb7
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ preadv_pwritev = []
signalfd = []

[dependencies]
libc = { git = "https://github.com/rust-lang/libc" }
libc = { git = "https://github.com/Mic92/libc", branch = "master" }
bitflags = "0.7"
cfg-if = "0.1.0"
void = "1.0.2"
Expand Down
50 changes: 50 additions & 0 deletions src/dirent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use {Result, Error, Errno, NixPath};
use libc::{self, DIR};
use std::os::unix::io::RawFd;
use errno;

pub struct Dir {
handle: *mut DIR,
}

impl Drop for Dir {
fn drop(&mut self) {
unsafe { libc::closedir(self.handle) };
}
}

pub fn fdopendir(fd: RawFd) -> Result<Dir> {
let dirp = unsafe { libc::fdopendir(fd) };
if dirp.is_null() {
Err(Error::last().into())
} else {
Ok(Dir { handle: dirp })
}
}

pub fn opendir<P: ?Sized + NixPath>(name: &P) -> Result<Dir> {
let dirp = try!(name.with_nix_path(|cstr| {
unsafe { libc::opendir(cstr.as_ptr()) }
}));
if dirp.is_null() {
Err(Error::last().into())
} else {
Ok(Dir { handle: dirp })
}
}

pub fn readdir<'a>(dir: &'a mut Dir) -> Result<Option<&'a libc::dirent>> {
let dirent = unsafe {
Errno::clear();
libc::readdir(dir.handle)
};
if dirent.is_null() {
match Errno::last() {
errno::UnknownErrno => Ok(None),
_ => Err(Error::last().into()),
}
} else {
Ok(Some(unsafe{&*dirent}))
}
}

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub mod libc {
pub use libc::{c_int, c_void};
pub use errno::Errno;

pub mod dirent;
pub mod errno;
pub mod features;
pub mod fcntl;
Expand Down
1 change: 1 addition & 0 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern crate tempfile;
extern crate nix_test as nixtest;

mod sys;
mod test_dirent;
mod test_fcntl;
mod test_net;
mod test_nix_path;
Expand Down
34 changes: 34 additions & 0 deletions test/test_dirent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

mod test_dirent {
use nix::dirent::{opendir, fdopendir, readdir, Dir};
use tempdir::TempDir;
use std::fs::File;
use std::path::Path;
use std::os::unix::io::IntoRawFd;

fn test_readdir<OPEN>(open_fn: OPEN) where OPEN: Fn(&Path) -> Dir {
let tempdir = TempDir::new("nix-test_readdir")
.unwrap_or_else(|e| panic!("tempdir failed: {}", e));
let mut dir = open_fn(tempdir.path());
let entry1 = readdir(&mut dir).unwrap().unwrap().clone();
assert_eq!(entry1.d_name[0..2], ['.' as i8, '\0' as i8]);

let entry2 = readdir(&mut dir).unwrap().unwrap().clone();
assert_eq!(entry2.d_name[0..2], ['.' as i8, '.' as i8]);

assert!(readdir(&mut dir).unwrap().is_none());
}

#[test]
fn test_opendir() {
test_readdir(|path| opendir(path).unwrap() );
}

#[test]
fn test_fdopendir() {
test_readdir(|path|
fdopendir(File::open(path).unwrap().into_raw_fd()).unwrap()
);
}

}

0 comments on commit 1eb7cb7

Please sign in to comment.