standard_lib/fs/path/
abs.rs1use std::env;
2use std::ffi::{CString, OsString};
3use std::io::RawOsError;
4use std::marker::PhantomData;
5use std::mem::MaybeUninit;
6
7use libc::{EACCES, EBADF, EFAULT, ELOOP, ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EOVERFLOW, stat as Stat};
8
9use super::{OwnedPath, Path, PathState, Rel};
10use crate::fs::error::{ExcessiveLinksError, MetadataOverflowError, MissingComponentError, NoSearchError, NonDirComponentError, OOMError, PathLengthError};
11use crate::fs::panic::{BadFdPanic, BadStackAddrPanic, Panic, UnexpectedErrorPanic};
12use crate::fs::path::{PathError, PathOrMetadataError};
13use crate::fs::Metadata;
14use crate::fs::file::MetadataError;
15use crate::util::{self, sealed::Sealed};
16
17#[derive(Debug)]
18pub enum Abs {}
19
20impl Sealed for Abs {}
21
22impl PathState for Abs {}
23
24impl OwnedPath<Abs> {
25 pub fn root() -> OwnedPath<Abs> {
26 OwnedPath::<Abs> {
27 _state: PhantomData,
28 inner: OsString::from("/"),
29 }
30 }
31
32 pub fn home() -> Option<OwnedPath<Abs>> {
33 Some(OwnedPath::<Abs>::from(
36 env::home_dir()?.as_os_str()
37 ))
38 }
39
40 pub fn cwd() -> Option<OwnedPath<Abs>> {
41 Some(OwnedPath::<Abs>::from(
43 env::current_dir().ok()?.as_os_str()
44 ))
45 }
46}
47
48impl Path<Abs> {
49 pub fn root() -> &'static Path<Abs> {
50 unsafe { Path::from_unchecked("/") }
51 }
52
53 pub fn read_all_links(&self) -> Result<OwnedPath<Abs>, RawOsError> {
54 todo!()
56 }
57
58 pub fn normalize_lexically(&self) -> OwnedPath<Abs> {
59 todo!()
61 }
62
63 pub fn make_relative<P: AsRef<Path<Abs>>>(&self, from: P) -> OwnedPath<Rel> {
64 todo!("{:?}", &from.as_ref())
66 }
67
68 pub(crate) fn match_metadata_error() -> Result<(), PathOrMetadataError> {
73 match util::fs::err_no() {
74 EACCES => Err(PathError::from(NoSearchError))?,
75 EBADF => BadFdPanic.panic(),
76 EFAULT => BadStackAddrPanic.panic(),
77 ELOOP => Err(PathError::from(ExcessiveLinksError))?,
78 ENAMETOOLONG => Err(PathError::from(PathLengthError))?,
79 ENOENT => Err(PathError::from(MissingComponentError))?,
80 ENOMEM => Err(MetadataError::from(OOMError))?,
81 ENOTDIR => Err(PathError::from(NonDirComponentError))?,
82 EOVERFLOW => Err(MetadataError::from(MetadataOverflowError))?,
83 e => UnexpectedErrorPanic(e).panic(),
84 }
85 }
86
87 pub fn metadata(&self) -> Result<Metadata, PathOrMetadataError> {
88 let pathname = CString::from(self.to_owned());
90
91 let mut raw_meta: MaybeUninit<Stat> = MaybeUninit::uninit();
92 if unsafe { libc::stat(pathname.as_ptr().cast(), raw_meta.as_mut_ptr()) } == -1 {
93 Self::match_metadata_error()?
94 }
95 let raw = unsafe { raw_meta.assume_init() };
97
98 Ok(Metadata::from_stat(raw))
99 }
100
101 pub fn metadata_no_follow(&self) -> Result<Metadata, PathOrMetadataError> {
102 let pathname = CString::from(self.to_owned());
103
104 let mut raw_meta: MaybeUninit<Stat> = MaybeUninit::uninit();
105 if unsafe { libc::lstat(pathname.as_ptr().cast(), raw_meta.as_mut_ptr()) } == -1 {
106 Self::match_metadata_error()?
107 }
108 let raw = unsafe { raw_meta.assume_init() };
110
111 Ok(Metadata::from_stat(raw))
112 }
113
114 }