/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.2/src/fs/abs.rs
Line | Count | Source |
1 | | //! POSIX-style filesystem functions which operate on bare paths. |
2 | | |
3 | | use crate::fd::OwnedFd; |
4 | | #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] |
5 | | use crate::fs::Access; |
6 | | #[cfg(not(any( |
7 | | solarish, |
8 | | target_os = "espidf", |
9 | | target_os = "haiku", |
10 | | target_os = "horizon", |
11 | | target_os = "netbsd", |
12 | | target_os = "nto", |
13 | | target_os = "redox", |
14 | | target_os = "vita", |
15 | | target_os = "wasi", |
16 | | )))] |
17 | | use crate::fs::StatFs; |
18 | | #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] |
19 | | use crate::fs::StatVfs; |
20 | | use crate::fs::{Mode, OFlags, Stat}; |
21 | | #[cfg(not(target_os = "wasi"))] |
22 | | use crate::ugid::{Gid, Uid}; |
23 | | use crate::{backend, io, path}; |
24 | | #[cfg(feature = "alloc")] |
25 | | use { |
26 | | crate::ffi::{CStr, CString}, |
27 | | crate::path::SMALL_PATH_BUFFER_SIZE, |
28 | | alloc::vec::Vec, |
29 | | }; |
30 | | |
31 | | /// `open(path, oflags, mode)`—Opens a file. |
32 | | /// |
33 | | /// POSIX guarantees that `open` will use the lowest unused file descriptor, |
34 | | /// however it is not safe in general to rely on this, as file descriptors may |
35 | | /// be unexpectedly allocated on other threads or in libraries. |
36 | | /// |
37 | | /// The `Mode` argument is only significant when creating a file. |
38 | | /// |
39 | | /// # References |
40 | | /// - [POSIX] |
41 | | /// - [Linux] |
42 | | /// |
43 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/open.html |
44 | | /// [Linux]: https://man7.org/linux/man-pages/man2/open.2.html |
45 | | #[inline] |
46 | 0 | pub fn open<P: path::Arg>(path: P, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> { |
47 | 0 | path.into_with_c_str(|path| backend::fs::syscalls::open(path, flags, mode)) |
48 | 0 | } |
49 | | |
50 | | /// `chmod(path, mode)`—Sets file or directory permissions. |
51 | | /// |
52 | | /// # References |
53 | | /// - [POSIX] |
54 | | /// - [Linux] |
55 | | /// |
56 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chmod.html |
57 | | /// [Linux]: https://man7.org/linux/man-pages/man2/chmod.2.html |
58 | | #[cfg(not(target_os = "wasi"))] |
59 | | #[inline] |
60 | 0 | pub fn chmod<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> { |
61 | 0 | path.into_with_c_str(|path| backend::fs::syscalls::chmod(path, mode)) |
62 | 0 | } |
63 | | |
64 | | /// `stat(path)`—Queries metadata for a file or directory. |
65 | | /// |
66 | | /// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to |
67 | | /// interpret the `st_mode` field. |
68 | | /// |
69 | | /// # References |
70 | | /// - [POSIX] |
71 | | /// - [Linux] |
72 | | /// |
73 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stat.html |
74 | | /// [Linux]: https://man7.org/linux/man-pages/man2/stat.2.html |
75 | | /// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode |
76 | | /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode |
77 | | #[inline] |
78 | 0 | pub fn stat<P: path::Arg>(path: P) -> io::Result<Stat> { |
79 | 0 | path.into_with_c_str(backend::fs::syscalls::stat) |
80 | 0 | } |
81 | | |
82 | | /// `lstat(path)`—Queries metadata for a file or directory, without following |
83 | | /// symlinks. |
84 | | /// |
85 | | /// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to |
86 | | /// interpret the `st_mode` field. |
87 | | /// |
88 | | /// # References |
89 | | /// - [POSIX] |
90 | | /// - [Linux] |
91 | | /// |
92 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/lstat.html |
93 | | /// [Linux]: https://man7.org/linux/man-pages/man2/lstat.2.html |
94 | | /// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode |
95 | | /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode |
96 | | #[inline] |
97 | 0 | pub fn lstat<P: path::Arg>(path: P) -> io::Result<Stat> { |
98 | 0 | path.into_with_c_str(backend::fs::syscalls::lstat) |
99 | 0 | } Unexecuted instantiation: rustix::fs::abs::lstat::<_> Unexecuted instantiation: rustix::fs::abs::lstat::<&std::path::Path> |
100 | | |
101 | | /// `readlink(path)`—Reads the contents of a symlink. |
102 | | /// |
103 | | /// If `reuse` is non-empty, reuse its buffer to store the result if possible. |
104 | | /// |
105 | | /// # References |
106 | | /// - [POSIX] |
107 | | /// - [Linux] |
108 | | /// |
109 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlink.html |
110 | | /// [Linux]: https://man7.org/linux/man-pages/man2/readlink.2.html |
111 | | #[cfg(feature = "alloc")] |
112 | | #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] |
113 | | #[inline] |
114 | 0 | pub fn readlink<P: path::Arg, B: Into<Vec<u8>>>(path: P, reuse: B) -> io::Result<CString> { |
115 | 0 | path.into_with_c_str(|path| _readlink(path, reuse.into())) |
116 | 0 | } |
117 | | |
118 | | #[cfg(feature = "alloc")] |
119 | 0 | fn _readlink(path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> { |
120 | | // This code would benefit from having a better way to read into |
121 | | // uninitialized memory, but that requires `unsafe`. |
122 | 0 | buffer.clear(); |
123 | 0 | buffer.reserve(SMALL_PATH_BUFFER_SIZE); |
124 | 0 | buffer.resize(buffer.capacity(), 0_u8); |
125 | | |
126 | | loop { |
127 | 0 | let nread = backend::fs::syscalls::readlink(path, &mut buffer)?; |
128 | | |
129 | 0 | let nread = nread as usize; |
130 | 0 | assert!(nread <= buffer.len()); |
131 | 0 | if nread < buffer.len() { |
132 | 0 | buffer.resize(nread, 0_u8); |
133 | 0 | return Ok(CString::new(buffer).unwrap()); |
134 | 0 | } |
135 | | // Use `Vec` reallocation strategy to grow capacity exponentially. |
136 | 0 | buffer.reserve(1); |
137 | 0 | buffer.resize(buffer.capacity(), 0_u8); |
138 | | } |
139 | 0 | } |
140 | | |
141 | | /// `rename(old_path, new_path)`—Renames a file or directory. |
142 | | /// |
143 | | /// # References |
144 | | /// - [POSIX] |
145 | | /// - [Linux] |
146 | | /// |
147 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rename.html |
148 | | /// [Linux]: https://man7.org/linux/man-pages/man2/rename.2.html |
149 | | #[inline] |
150 | 0 | pub fn rename<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { |
151 | 0 | old_path.into_with_c_str(|old_path| { |
152 | 0 | new_path.into_with_c_str(|new_path| backend::fs::syscalls::rename(old_path, new_path)) Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0} Unexecuted instantiation: rustix::fs::abs::rename::<_, _>::{closure#0}::{closure#0} |
153 | 0 | }) Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path>::{closure#0} Unexecuted instantiation: rustix::fs::abs::rename::<_, _>::{closure#0} |
154 | 0 | } Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path> Unexecuted instantiation: rustix::fs::abs::rename::<_, _> |
155 | | |
156 | | /// `unlink(path)`—Unlinks a file. |
157 | | /// |
158 | | /// # References |
159 | | /// - [POSIX] |
160 | | /// - [Linux] |
161 | | /// |
162 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlink.html |
163 | | /// [Linux]: https://man7.org/linux/man-pages/man2/unlink.2.html |
164 | | #[inline] |
165 | 0 | pub fn unlink<P: path::Arg>(path: P) -> io::Result<()> { |
166 | 0 | path.into_with_c_str(backend::fs::syscalls::unlink) |
167 | 0 | } Unexecuted instantiation: rustix::fs::abs::unlink::<&std::path::Path> Unexecuted instantiation: rustix::fs::abs::unlink::<_> |
168 | | |
169 | | /// `rmdir(path)`—Removes a directory. |
170 | | /// |
171 | | /// # References |
172 | | /// - [POSIX] |
173 | | /// - [Linux] |
174 | | /// |
175 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rmdir.html |
176 | | /// [Linux]: https://man7.org/linux/man-pages/man2/rmdir.2.html |
177 | | #[inline] |
178 | 0 | pub fn rmdir<P: path::Arg>(path: P) -> io::Result<()> { |
179 | 0 | path.into_with_c_str(backend::fs::syscalls::rmdir) |
180 | 0 | } |
181 | | |
182 | | /// `link(old_path, new_path)`—Creates a hard link. |
183 | | /// |
184 | | /// POSIX leaves it implementation-defined whether `link` follows a symlink in |
185 | | /// `old_path`, or creates a new link to the symbolic link itself. On platforms |
186 | | /// which have it, [`linkat`] avoids this problem since it has an [`AtFlags`] |
187 | | /// parameter and the [`AtFlags::SYMLINK_FOLLOW`] flag determines whether |
188 | | /// symlinks should be followed. |
189 | | /// |
190 | | /// # References |
191 | | /// - [POSIX] |
192 | | /// - [Linux] |
193 | | /// |
194 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/link.html |
195 | | /// [Linux]: https://man7.org/linux/man-pages/man2/link.2.html |
196 | | /// [`linkat`]: crate::fs::linkat |
197 | | /// [`AtFlags`]: crate::fs::AtFlags |
198 | | /// [`AtFlags::SYMLINK_FOLLOW`]: crate::fs::AtFlags::SYMLINK_FOLLOW |
199 | | #[inline] |
200 | 0 | pub fn link<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { |
201 | 0 | old_path.into_with_c_str(|old_path| { |
202 | 0 | new_path.into_with_c_str(|new_path| backend::fs::syscalls::link(old_path, new_path)) |
203 | 0 | }) |
204 | 0 | } |
205 | | |
206 | | /// `symlink(old_path, new_path)`—Creates a symlink. |
207 | | /// |
208 | | /// # References |
209 | | /// - [POSIX] |
210 | | /// - [Linux] |
211 | | /// |
212 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlink.html |
213 | | /// [Linux]: https://man7.org/linux/man-pages/man2/symlink.2.html |
214 | | #[inline] |
215 | 0 | pub fn symlink<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { |
216 | 0 | old_path.into_with_c_str(|old_path| { |
217 | 0 | new_path.into_with_c_str(|new_path| backend::fs::syscalls::symlink(old_path, new_path)) |
218 | 0 | }) |
219 | 0 | } |
220 | | |
221 | | /// `mkdir(path, mode)`—Creates a directory. |
222 | | /// |
223 | | /// # References |
224 | | /// - [POSIX] |
225 | | /// - [Linux] |
226 | | /// |
227 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdir.html |
228 | | /// [Linux]: https://man7.org/linux/man-pages/man2/mkdir.2.html |
229 | | #[inline] |
230 | 0 | pub fn mkdir<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> { |
231 | 0 | path.into_with_c_str(|path| backend::fs::syscalls::mkdir(path, mode)) |
232 | 0 | } |
233 | | |
234 | | /// `access(path, access)`—Tests permissions for a file or directory. |
235 | | /// |
236 | | /// # References |
237 | | /// - [POSIX] |
238 | | /// - [Linux] |
239 | | /// |
240 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/access.html |
241 | | /// [Linux]: https://man7.org/linux/man-pages/man2/access.2.html |
242 | | #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] |
243 | | #[inline] |
244 | 0 | pub fn access<P: path::Arg>(path: P, access: Access) -> io::Result<()> { |
245 | 0 | path.into_with_c_str(|path| backend::fs::syscalls::access(path, access)) |
246 | 0 | } |
247 | | |
248 | | /// `statfs`—Queries filesystem metadata. |
249 | | /// |
250 | | /// Compared to [`statvfs`], this function often provides more information, |
251 | | /// though it's less portable. |
252 | | /// |
253 | | /// # References |
254 | | /// - [Linux] |
255 | | /// |
256 | | /// [Linux]: https://man7.org/linux/man-pages/man2/statfs.2.html |
257 | | #[cfg(not(any( |
258 | | solarish, |
259 | | target_os = "espidf", |
260 | | target_os = "haiku", |
261 | | target_os = "horizon", |
262 | | target_os = "netbsd", |
263 | | target_os = "nto", |
264 | | target_os = "redox", |
265 | | target_os = "vita", |
266 | | target_os = "wasi", |
267 | | )))] |
268 | | #[inline] |
269 | 0 | pub fn statfs<P: path::Arg>(path: P) -> io::Result<StatFs> { |
270 | 0 | path.into_with_c_str(backend::fs::syscalls::statfs) |
271 | 0 | } |
272 | | |
273 | | /// `statvfs`—Queries filesystem metadata, POSIX version. |
274 | | /// |
275 | | /// Compared to [`statfs`], this function often provides less information, but |
276 | | /// it is more portable. But even so, filesystems are very diverse and not all |
277 | | /// the fields are meaningful for every filesystem. And `f_fsid` doesn't seem |
278 | | /// to have a clear meaning anywhere. |
279 | | /// |
280 | | /// # References |
281 | | /// - [POSIX] |
282 | | /// - [Linux] |
283 | | /// |
284 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/statvfs.html |
285 | | /// [Linux]: https://man7.org/linux/man-pages/man2/statvfs.2.html |
286 | | #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] |
287 | | #[inline] |
288 | 0 | pub fn statvfs<P: path::Arg>(path: P) -> io::Result<StatVfs> { |
289 | 0 | path.into_with_c_str(backend::fs::syscalls::statvfs) |
290 | 0 | } |
291 | | |
292 | | /// `chown(path, owner, group)`—Sets open file or directory ownership. |
293 | | /// |
294 | | /// # References |
295 | | /// - [POSIX] |
296 | | /// - [Linux] |
297 | | /// |
298 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chown.html |
299 | | /// [Linux]: https://man7.org/linux/man-pages/man2/chown.2.html |
300 | | #[cfg(not(target_os = "wasi"))] |
301 | | #[inline] |
302 | 0 | pub fn chown<P: path::Arg>(path: P, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { |
303 | 0 | path.into_with_c_str(|path| backend::fs::syscalls::chown(path, owner, group)) |
304 | 0 | } |