From b4d5787de99b1fab4222dd68a4a044cefa8e7357 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 12 Feb 2019 13:51:34 +0100 Subject: [PATCH] tools: start fs submodule, add read_subdir This creates an iterator relative to a RawFd via nix::dir::Dir over nix::dir::Entrys. Signed-off-by: Wolfgang Bumiller --- src/tools.rs | 1 + src/tools/fs.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/tools/fs.rs diff --git a/src/tools.rs b/src/tools.rs index 56a63f67..06b7eb18 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -25,6 +25,7 @@ pub mod wrapped_reader_stream; pub mod common_regex; pub mod ticket; pub mod borrow; +pub mod fs; /// The `BufferedReader` trait provides a single function /// `buffered_read`. It returns a reference to an internal buffer. The diff --git a/src/tools/fs.rs b/src/tools/fs.rs new file mode 100644 index 00000000..48abe436 --- /dev/null +++ b/src/tools/fs.rs @@ -0,0 +1,37 @@ +//! File system helper utilities. + +use std::os::unix::io::RawFd; + +use failure::Error; +use nix::dir; +use nix::dir::Dir; + +use crate::tools::borrow::Tied; + +// Since Tied implements Deref to U, a Tied already implements Iterator. +// This is simply a wrapper with a shorter type name mapping nix::Error to failure::Error. +/// Wrapper over a pair of `nix::dir::Dir` and `nix::dir::Iter`, returned by `read_subdir()`. +pub struct ReadDir { + iter: Tied>>, +} + +impl Iterator for ReadDir { + type Item = Result; + + fn next(&mut self) -> Option { + self.iter.next().map(|res| res.map_err(|e| Error::from(e))) + } +} + +/// Create an iterator over sub directory entries. +/// This uses `openat` on `dirfd`, so `path` can be relative to that or an absolute path. +pub fn read_subdir(dirfd: RawFd, path: &P) -> Result { + use nix::fcntl::OFlag; + use nix::sys::stat::Mode; + + let dir = Dir::openat(dirfd, path, OFlag::O_RDONLY, Mode::empty())?; + let iter = Tied::new(dir, |dir| { + Box::new(unsafe { (*dir).iter() }) as Box>> + }); + Ok(ReadDir { iter }) +}