• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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]
chdir<P: path::Arg>(path: P) -> io::Result<()>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]
fchdir<Fd: AsFd>(fd: Fd) -> io::Result<()>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]
getcwd<B: Into<Vec<u8>>>(reuse: B) -> io::Result<CString>47 pub fn getcwd<B: Into<Vec<u8>>>(reuse: B) -> io::Result<CString> {
48     _getcwd(reuse.into())
49 }
50 
_getcwd(mut buffer: Vec<u8>) -> io::Result<CString>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 }
73