Skip to content

Commit c450aeb

Browse files
committed
Amjad50/OS: added support for chdir, getcwd, and current_exe
We can manipulate working directories now, also as a bonus from the kernel now, file operations work with relative paths :)
1 parent 7071dfc commit c450aeb

File tree

1 file changed

+45
-4
lines changed
  • library/std/src/sys/amjad_os

1 file changed

+45
-4
lines changed

library/std/src/sys/amjad_os/os.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
use user_std::SyscallError;
2+
13
use crate::error::Error as StdError;
24
use crate::ffi::{OsStr, OsString};
35
use crate::fmt;
46
use crate::io;
57
use crate::marker::PhantomData;
8+
use crate::os::amjad_os::prelude::OsStringExt;
69
use crate::path::{self, PathBuf};
10+
use crate::sys::amjad_os::syscall_to_io_error;
11+
use crate::sys::common::small_c_string::run_path_with_cstr;
712

813
// This function is needed by the panic runtime. The symbol is named in
914
// pre-link args for the target specification, so keep that in sync.
@@ -29,11 +34,35 @@ pub fn error_string(_errno: i32) -> String {
2934
}
3035

3136
pub fn getcwd() -> io::Result<PathBuf> {
32-
todo!("getcwd")
37+
let mut buf = Vec::with_capacity(512);
38+
loop {
39+
unsafe {
40+
// Safety: the size is equal to the capacity, I'm setting the length so we can access the slice
41+
// its safe to use since the data will be overwritten by getcwd
42+
buf.set_len(buf.capacity());
43+
match user_std::io::syscall_get_cwd(&mut buf) {
44+
Ok(len) => {
45+
// Safety: forcing the length back to the safe space
46+
buf.set_len(len);
47+
buf.shrink_to_fit();
48+
return Ok(PathBuf::from(OsString::from_vec(buf)));
49+
}
50+
Err(SyscallError::BufferTooSmall) => {
51+
// Trigger the internal buffer resizing logic of `Vec` by requiring
52+
// more space than the current capacity.
53+
// at this stage we have already set the length to the capacity
54+
buf.reserve(1);
55+
}
56+
Err(e) => return Err(syscall_to_io_error(e)),
57+
}
58+
}
59+
}
3360
}
3461

35-
pub fn chdir(_: &path::Path) -> io::Result<()> {
36-
todo!("chdir")
62+
pub fn chdir(p: &path::Path) -> io::Result<()> {
63+
run_path_with_cstr(p, |p| unsafe {
64+
user_std::io::syscall_chdir(p).map_err(syscall_to_io_error)
65+
})
3766
}
3867

3968
pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
@@ -74,7 +103,19 @@ impl StdError for JoinPathsError {
74103
}
75104

76105
pub fn current_exe() -> io::Result<PathBuf> {
77-
todo!("current_exe")
106+
use crate::env;
107+
use crate::io::ErrorKind;
108+
109+
let exe_path = env::args().next().ok_or(io::const_io_error!(
110+
ErrorKind::Uncategorized,
111+
"an executable path was not found because no arguments were provided through argv"
112+
))?;
113+
let path = PathBuf::from(exe_path);
114+
115+
// Prepend the current working directory to the path if it's not absolute.
116+
// TODO: `is_absolute` is broken for non-unix since it relies on `cfgs` which I don't want to modify,
117+
// I'm opening a PR to fix that, then this will be changed to `is_absolute` but doesn't change much anyway
118+
if !path.has_root() { getcwd().map(|cwd| cwd.join(path)) } else { Ok(path) }
78119
}
79120

80121
pub struct Env(!);

0 commit comments

Comments
 (0)