use crate::io::glommio_file::GlommioFile;
use crate::parking::Reactor;
use crate::sys;
use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::path::Path;
#[derive(Debug)]
pub struct Directory {
file: GlommioFile,
}
impl AsRawFd for Directory {
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}
impl Directory {
pub fn try_clone(&self) -> io::Result<Directory> {
let fd = enhanced_try!(
sys::duplicate_file(self.file.as_raw_fd()),
"Cloning directory",
self.file
)?;
let file = unsafe { GlommioFile::from_raw_fd(fd as _) }.with_path(self.file.path.clone());
Ok(Directory { file })
}
pub fn sync_open<P: AsRef<Path>>(path: P) -> io::Result<Directory> {
let path = path.as_ref().to_owned();
let flags = libc::O_CLOEXEC | libc::O_DIRECTORY;
let fd = enhanced_try!(
sys::sync_open(&path, flags, 0o755),
"Synchronously opening directory",
Some(&path),
None
)?;
let file = unsafe { GlommioFile::from_raw_fd(fd as _) }.with_path(Some(path));
Ok(Directory { file })
}
pub async fn open<P: AsRef<Path>>(path: P) -> io::Result<Directory> {
let path = path.as_ref().to_owned();
let flags = libc::O_DIRECTORY | libc::O_CLOEXEC;
let source = Reactor::get().open_at(-1, &path, flags, 0o755);
let fd = enhanced_try!(
source.collect_rw().await,
"Opening directory",
Some(&path),
None
)?;
let file = unsafe { GlommioFile::from_raw_fd(fd as _) }.with_path(Some(path));
Ok(Directory { file })
}
pub fn sync_create<P: AsRef<Path>>(path: P) -> io::Result<Directory> {
let path = path.as_ref().to_owned();
enhanced_try!(
match std::fs::create_dir(&path) {
Ok(_) => Ok(()),
Err(x) => {
match x.kind() {
std::io::ErrorKind::AlreadyExists => Ok(()),
_ => Err(x),
}
}
},
"Synchronously creating directory",
Some(&path),
None
)?;
Self::sync_open(&path)
}
pub fn sync_read_dir(&self) -> io::Result<std::fs::ReadDir> {
let path = self.file.path_required("read directory")?;
enhanced_try!(std::fs::read_dir(path), "Reading a directory", self.file)
}
pub async fn sync(&self) -> io::Result<()> {
let source = Reactor::get().fdatasync(self.as_raw_fd());
source.collect_rw().await?;
Ok(())
}
pub async fn close(self) -> io::Result<()> {
self.file.close().await
}
}