#![allow(deprecated)]
use std::{
ffi::CString,
fs::File,
io::{self, ErrorKind},
os::{
fd::{AsFd, BorrowedFd},
unix::{
ffi::OsStrExt,
io::{AsRawFd, FromRawFd, RawFd},
},
},
path::Path,
};
use libc::{c_int, c_uint, mode_t, openat};
#[deprecated(since = "0.4.0", note = "Use cap_std::fs::Dir instead")]
pub struct Directory {
file: File,
}
impl Directory {
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Directory> {
let file = File::open(path.as_ref())?;
Ok(Directory { file })
}
pub fn open_file<P: AsRef<Path> + ?Sized>(
&self,
path: &P,
flags: c_int,
mode: Option<mode_t>,
) -> io::Result<File> {
let p = CString::new(path.as_ref().as_os_str().as_bytes())
.or(Err(io::Error::new(ErrorKind::Other, "not a valid C path")))?;
unsafe {
let fd = match mode {
Some(mode) => openat(self.file.as_raw_fd(), p.as_ptr(), flags, mode as c_uint),
None => openat(self.file.as_raw_fd(), p.as_ptr(), 0),
};
if fd < 0 {
Err(io::Error::last_os_error())
} else {
Ok(File::from_raw_fd(fd))
}
}
}
}
impl FromRawFd for Directory {
unsafe fn from_raw_fd(fd: RawFd) -> Directory {
Directory {
file: File::from_raw_fd(fd),
}
}
}
impl AsFd for Directory {
fn as_fd(&self) -> BorrowedFd<'_> {
self.file.as_fd()
}
}
impl AsRawFd for Directory {
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}