standard_lib/fs/dir/
dir.rs1use std::ffi::CString;
2use std::io::RawOsError;
3
4use libc::{O_DIRECTORY, c_int, mode_t};
5
6use crate::collections::contiguous::Array;
7use crate::fs::dir::{DirEntries, DirEntry};
8#[doc(inline)]
9pub use crate::fs::file::{CloneError, CloseError, MetadataError, OpenError};
10use crate::fs::{Abs, Fd, FileType, Metadata, OwnedPath, Path, Rel};
11use crate::util;
12
13use super::BUFFER_SIZE;
14
15pub(crate) const DEF_DIR_MODE: c_int = 0o777;
16
17pub const CWD: Directory = Directory {
22 fd: Fd(libc::AT_FDCWD),
23};
24
25#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Directory {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Directory",
"fd", &&self.fd)
}
}Debug)]
28pub struct Directory {
29 pub(crate) fd: Fd,
30}
31
32impl Directory {
33 pub fn open<P: Into<OwnedPath<Abs>>>(dir_path: P) -> Result<Directory, OpenError> {
35 match Fd::open(dir_path, O_DIRECTORY, DEF_DIR_MODE) {
36 Ok(fd) => Ok(Directory {
37 fd: fd.assert_type(FileType::Directory)?,
38 }),
39 Err(e) => Err(OpenError::interpret_raw_error(e)),
40 }
41 }
42
43 pub fn open_rel<P: Into<OwnedPath<Rel>>>(
44 &self,
45 relative_to: &Directory,
46 dir_path: P
47 ) -> Result<Directory, OpenError> {
48 match Fd::open_rel(relative_to, dir_path, O_DIRECTORY, DEF_DIR_MODE) {
49 Ok(fd) => Ok(Directory {
50 fd: fd.assert_type(FileType::Directory)?,
51 }),
52 Err(e) => Err(OpenError::interpret_raw_error(e)),
53 }
54 }
55
56 pub fn open_dir_entry(&self, dir_ent: &DirEntry) -> Result<Directory, OpenError> {
57 self.open_rel(dir_ent.parent, dir_ent.path.clone())
59 }
60
61 pub fn create<P: AsRef<Path<Abs>>>(
62 dir_path: P,
63 file_mode: u16
64 ) -> Result<Directory, RawOsError> {
65 let pathname = CString::from(dir_path.as_ref().to_owned());
66
67 match unsafe { libc::mkdir(pathname.as_ptr().cast(), file_mode as mode_t) } {
71 -1 => Err(util::fs::err_no()), fd => Ok(Directory {
73 fd: Fd(fd),
74 }),
75 }
76 }
77
78 pub fn read_entries<'a>(&'a self) -> DirEntries<'a> {
79 let buf = Array::new_uninit(BUFFER_SIZE);
80 DirEntries {
81 dir: self,
82 head: buf.ptr,
83 buf,
84 rem: 0,
85 }
86 }
87
88 pub fn metadata(&self) -> Result<Metadata, MetadataError> {
89 self.fd.metadata()
90 }
91
92 pub fn close(self) -> Result<(), CloseError> {
93 self.fd.close()
94 }
95
96 pub fn try_clone(&self) -> Result<Directory, CloneError> {
97 self.fd.try_clone().map(|new_fd| Directory {
98 fd: new_fd,
99 })
100 }
101}