]>
Commit | Line | Data |
---|---|---|
353b0b11 FG |
1 | use crate::ffi::CString; |
2 | use crate::path::SMALL_PATH_BUFFER_SIZE; | |
3 | use crate::{backend, io, path}; | |
4 | use alloc::vec::Vec; | |
5 | #[cfg(not(target_os = "fuchsia"))] | |
6 | use backend::fd::AsFd; | |
7 | ||
8 | /// `chdir(path)`—Change the current working directory. | |
9 | /// | |
10 | /// # References | |
11 | /// - [POSIX] | |
12 | /// - [Linux] | |
13 | /// | |
14 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html | |
15 | /// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html | |
16 | #[inline] | |
17 | pub fn chdir<P: path::Arg>(path: P) -> io::Result<()> { | |
18 | path.into_with_c_str(backend::process::syscalls::chdir) | |
19 | } | |
20 | ||
21 | /// `fchdir(fd)`—Change the current working directory. | |
22 | /// | |
23 | /// # References | |
24 | /// - [POSIX] | |
25 | /// - [Linux] | |
26 | /// | |
27 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html | |
28 | /// [Linux]: https://man7.org/linux/man-pages/man2/fchdir.2.html | |
29 | #[cfg(not(target_os = "fuchsia"))] | |
30 | #[inline] | |
31 | pub fn fchdir<Fd: AsFd>(fd: Fd) -> io::Result<()> { | |
32 | backend::process::syscalls::fchdir(fd.as_fd()) | |
33 | } | |
34 | ||
35 | /// `getcwd()`—Return the current working directory. | |
36 | /// | |
37 | /// If `reuse` is non-empty, reuse its buffer to store the result if possible. | |
38 | /// | |
39 | /// # References | |
40 | /// - [POSIX] | |
41 | /// - [Linux] | |
42 | /// | |
43 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html | |
44 | /// [Linux]: https://man7.org/linux/man-pages/man3/getcwd.3.html | |
45 | #[cfg(not(target_os = "wasi"))] | |
46 | #[inline] | |
47 | pub fn getcwd<B: Into<Vec<u8>>>(reuse: B) -> io::Result<CString> { | |
48 | _getcwd(reuse.into()) | |
49 | } | |
50 | ||
51 | fn _getcwd(mut buffer: Vec<u8>) -> io::Result<CString> { | |
52 | // This code would benefit from having a better way to read into | |
53 | // uninitialized memory, but that requires `unsafe`. | |
54 | buffer.clear(); | |
55 | buffer.reserve(SMALL_PATH_BUFFER_SIZE); | |
56 | buffer.resize(buffer.capacity(), 0_u8); | |
57 | ||
58 | loop { | |
59 | match backend::process::syscalls::getcwd(&mut buffer) { | |
60 | Err(io::Errno::RANGE) => { | |
61 | buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially | |
62 | buffer.resize(buffer.capacity(), 0_u8); | |
63 | } | |
64 | Ok(_) => { | |
65 | let len = buffer.iter().position(|x| *x == b'\0').unwrap(); | |
66 | buffer.resize(len, 0_u8); | |
67 | return Ok(CString::new(buffer).unwrap()); | |
68 | } | |
69 | Err(errno) => return Err(errno), | |
70 | } | |
71 | } | |
72 | } |