1#![deny(unsafe_op_in_unsafe_fn)]
2
3use crate::io;
4use crate::path::{Path, PathBuf};
5
6pub mod common;
7
8cfg_select! {
9 target_family = "unix" => {
10 mod unix;
11 use unix as imp;
12 pub use unix::{chown, fchown, lchown, mkfifo};
13 #[cfg(not(target_os = "fuchsia"))]
14 pub use unix::chroot;
15 pub(crate) use unix::debug_assert_fd_is_open;
16 #[cfg(any(target_os = "linux", target_os = "android"))]
17 pub(crate) use unix::CachedFileMetadata;
18 use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path;
19 }
20 target_os = "windows" => {
21 mod windows;
22 use windows as imp;
23 pub use windows::{symlink_inner, junction_point};
24 use crate::sys::path::with_native_path;
25 }
26 target_os = "hermit" => {
27 mod hermit;
28 use hermit as imp;
29 }
30 target_os = "solid_asp3" => {
31 mod solid;
32 use solid as imp;
33 }
34 target_os = "uefi" => {
35 mod uefi;
36 use uefi as imp;
37 }
38 target_os = "wasi" => {
39 mod wasi;
40 use wasi as imp;
41 }
42 _ => {
43 mod unsupported;
44 use unsupported as imp;
45 }
46}
47
48#[cfg(not(any(target_family = "unix", target_os = "windows")))]
50#[inline]
51pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&Path) -> io::Result<T>) -> io::Result<T> {
52 f(path)
53}
54
55pub use imp::{
56 DirBuilder, DirEntry, File, FileAttr, FilePermissions, FileTimes, FileType, OpenOptions,
57 ReadDir,
58};
59
60pub fn read_dir(path: &Path) -> io::Result<ReadDir> {
61 imp::readdir(path)
63}
64
65pub fn remove_file(path: &Path) -> io::Result<()> {
66 with_native_path(path, &imp::unlink)
67}
68
69pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
70 with_native_path(old, &|old| with_native_path(new, &|new| imp::rename(old, new)))
71}
72
73pub fn remove_dir(path: &Path) -> io::Result<()> {
74 with_native_path(path, &imp::rmdir)
75}
76
77pub fn remove_dir_all(path: &Path) -> io::Result<()> {
78 #[cfg(not(windows))]
80 return imp::remove_dir_all(path);
81 #[cfg(windows)]
82 with_native_path(path, &imp::remove_dir_all)
83}
84
85pub fn read_link(path: &Path) -> io::Result<PathBuf> {
86 with_native_path(path, &imp::readlink)
87}
88
89pub fn symlink(original: &Path, link: &Path) -> io::Result<()> {
90 #[cfg(windows)]
92 return imp::symlink(original, link);
93 #[cfg(not(windows))]
94 with_native_path(original, &|original| {
95 with_native_path(link, &|link| imp::symlink(original, link))
96 })
97}
98
99pub fn hard_link(original: &Path, link: &Path) -> io::Result<()> {
100 with_native_path(original, &|original| {
101 with_native_path(link, &|link| imp::link(original, link))
102 })
103}
104
105pub fn metadata(path: &Path) -> io::Result<FileAttr> {
106 with_native_path(path, &imp::stat)
107}
108
109pub fn symlink_metadata(path: &Path) -> io::Result<FileAttr> {
110 with_native_path(path, &imp::lstat)
111}
112
113pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> {
114 with_native_path(path, &|path| imp::set_perm(path, perm.clone()))
115}
116
117#[cfg(unix)]
118pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> {
119 use crate::fs::OpenOptions;
120 use crate::os::unix::fs::OpenOptionsExt;
121
122 OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm)
123}
124
125#[cfg(not(unix))]
126pub fn set_permissions_nofollow(_path: &Path, _perm: crate::fs::Permissions) -> io::Result<()> {
127 crate::unimplemented!(
128 "`set_permissions_nofollow` is currently only implemented on Unix platforms"
129 )
130}
131
132pub fn canonicalize(path: &Path) -> io::Result<PathBuf> {
133 with_native_path(path, &imp::canonicalize)
134}
135
136pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
137 #[cfg(not(windows))]
139 return imp::copy(from, to);
140 #[cfg(windows)]
141 with_native_path(from, &|from| with_native_path(to, &|to| imp::copy(from, to)))
142}
143
144pub fn exists(path: &Path) -> io::Result<bool> {
145 #[cfg(not(windows))]
147 return imp::exists(path);
148 #[cfg(windows)]
149 with_native_path(path, &imp::exists)
150}