Skip to content

Commit 97fd07c

Browse files
committed
getcwd: make a direct POSIX compliant syscall
1 parent 12b5d4f commit 97fd07c

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

src/errno.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,12 @@ impl ToErrno for isize {
751751
}
752752
}
753753

754+
impl ToErrno for Errno {
755+
fn to_errno(&self) -> Option<i32> {
756+
Some(i32::from(*self))
757+
}
758+
}
759+
754760
impl ToErrno for u8 {}
755761
impl ToErrno for u16 {}
756762
impl ToErrno for u32 {}

src/syscalls/mod.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use alloc::ffi::CString;
55
use core::alloc::{GlobalAlloc, Layout};
66
use core::ffi::{CStr, c_char};
77
use core::marker::PhantomData;
8+
use core::ptr::null;
89

910
use dirent_display::Dirent64Display;
1011
use hermit_sync::Lazy;
@@ -21,7 +22,7 @@ pub use self::system::*;
2122
pub use self::tasks::*;
2223
pub use self::timer::*;
2324
use crate::env;
24-
use crate::errno::Errno;
25+
use crate::errno::{Errno, ToErrno};
2526
use crate::executor::block_on;
2627
use crate::fd::{
2728
self, AccessOption, AccessPermission, EventFlags, FileDescriptor, OpenOption, PollFd,
@@ -348,27 +349,40 @@ pub unsafe extern "C" fn sys_open(name: *const c_char, flags: i32, mode: u32) ->
348349

349350
#[hermit_macro::system]
350351
#[unsafe(no_mangle)]
351-
pub unsafe extern "C" fn sys_getcwd(buf: *mut c_char, size: usize) -> i32 {
352-
let cwd = crate::fs::get_cwd();
352+
pub unsafe extern "C" fn sys_getcwd(buf: *mut c_char, size: usize) -> *const c_char {
353+
let error = |e: Errno| {
354+
e.set_errno();
355+
null::<c_char>()
356+
};
357+
358+
if size == 0 {
359+
return error(Errno::Inval);
360+
}
361+
362+
let cwd = fs::get_cwd();
353363
if let Err(e) = cwd {
354-
return -i32::from(e);
364+
return error(e);
355365
}
356366

357367
let Ok(cwd) = cwd else { unreachable!() };
358368

359369
let Ok(cwd) = CString::new(cwd) else {
360-
return -i32::from(Errno::Noent); // extremely unlikely
370+
return error(Errno::Noent);
361371
};
362372

363373
if (cwd.count_bytes() + 1) > size {
364-
return -i32::from(Errno::Range);
374+
return error(Errno::Range);
375+
}
376+
377+
if buf.is_null() {
378+
return cwd.into_raw();
365379
}
366380

367381
unsafe {
368382
buf.copy_from(cwd.as_ptr(), size);
369383
}
370384

371-
i32::try_from(cwd.count_bytes() + 1).unwrap_or(-i32::from(Errno::Range))
385+
buf
372386
}
373387

374388
#[hermit_macro::system]

0 commit comments

Comments
 (0)