Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ mman = []
## [hermit-c]: https://github.com/hermit-os/hermit-c
newlib = []

## Enable stubbing result values for some system calls.
##
## For some system calls related to system options in which Hermit does not implement all possible options,
## return 0 (success) instead of an error when the option is unknown ; or return a convincing fake value.
syscall-fake-values = []

#! ### Platform Features

## Enables [Uhyve] support.
Expand Down
37 changes: 27 additions & 10 deletions src/fs/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use alloc::sync::Arc;
use alloc::vec::Vec;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
#[cfg(feature = "syscall-fake-values")]
use core::sync::atomic::{AtomicU64, Ordering};
use core::{mem, ptr};

use align_address::Align;
Expand Down Expand Up @@ -36,6 +38,9 @@ impl RomFileInner {
}
}

#[cfg(feature = "syscall-fake-values")]
static VFS_INO_NUM: AtomicU64 = AtomicU64::new(10_000);

pub struct RomFileInterface {
/// Position within the file
pos: Mutex<usize>,
Expand Down Expand Up @@ -306,6 +311,8 @@ impl RomFile {
st_atim: t,
st_mtim: t,
st_ctim: t,
#[cfg(feature = "syscall-fake-values")]
st_ino: VFS_INO_NUM.fetch_add(1, Ordering::AcqRel),
..Default::default()
};

Expand Down Expand Up @@ -361,6 +368,12 @@ impl RamFile {
st_atim: t,
st_mtim: t,
st_ctim: t,
#[cfg(feature = "syscall-fake-values")]
st_nlink: 1,
#[cfg(feature = "syscall-fake-values")]
st_blksize: 4096,
#[cfg(feature = "syscall-fake-values")]
st_ino: VFS_INO_NUM.fetch_add(1, Ordering::AcqRel),
..Default::default()
};

Expand Down Expand Up @@ -614,15 +627,17 @@ impl VfsNode for MemDirectory {
block_on(
async {
let (component, rest) = path.split_once("/").unwrap_or((path, ""));
let inner = self.inner.read().await;
let node = inner.get(component).ok_or(Errno::Badf)?;

if !rest.is_empty() {
let inner = self.inner.read().await;
let directory = inner.get(component).ok_or(Errno::Badf)?;
return directory.traverse_lstat(rest);
if node.get_kind() == NodeKind::File {
Err(Errno::Notdir)?;
}

return node.traverse_lstat(rest);
}

let inner = self.inner.read().await;
let node = inner.get(component).ok_or(Errno::Badf)?;
node.get_file_attributes()
},
None,
Expand All @@ -633,15 +648,17 @@ impl VfsNode for MemDirectory {
block_on(
async {
let (component, rest) = path.split_once("/").unwrap_or((path, ""));
let inner = self.inner.read().await;
let node = inner.get(component).ok_or(Errno::Badf)?;

if !rest.is_empty() {
let inner = self.inner.read().await;
let directory = inner.get(component).ok_or(Errno::Badf)?;
return directory.traverse_stat(rest);
if node.get_kind() == NodeKind::File {
Err(Errno::Notdir)?;
}

return node.traverse_stat(rest);
}

let inner = self.inner.read().await;
let node = inner.get(component).ok_or(Errno::Badf)?;
node.get_file_attributes()
},
None,
Expand Down
11 changes: 7 additions & 4 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,6 @@ pub unsafe extern "C" fn sys_access(name: *const c_char, flags: i32) -> i32 {
return -i32::from(Errno::Inval);
};

if access_option.contains(AccessOption::F_OK) && access_option != AccessOption::F_OK {
return -i32::from(Errno::Inval);
}

let Ok(name) = unsafe { CStr::from_ptr(name) }.to_str() else {
return -i32::from(Errno::Inval);
};
Expand Down Expand Up @@ -684,13 +680,17 @@ pub unsafe extern "C" fn sys_ioctl(fd: RawFd, cmd: i32, argp: *mut core::ffi::c_
#[hermit_macro::system(errno)]
#[unsafe(no_mangle)]
pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 {
const F_GETFD: i32 = 1;
const F_SETFD: i32 = 2;
const F_GETFL: i32 = 3;
const F_SETFL: i32 = 4;
const FD_CLOEXEC: i32 = 1;

if cmd == F_SETFD && arg == FD_CLOEXEC {
0
} else if cmd == F_GETFD {
// Only the FD_CLOEXEC flag is defined, and it has no effect in hermit, so always return 0
0
} else if cmd == F_GETFL {
let obj = get_object(fd);
obj.map_or_else(
Expand All @@ -717,6 +717,9 @@ pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 {
.map_or_else(|e| -i32::from(e), |()| 0)
},
)
} else if cfg!(feature = "syscall-fake-values") {
warn!("[syscall-fake-values] Unknown fcntl flag {cmd} {arg}, returning 0");
0
} else {
-i32::from(Errno::Inval)
}
Expand Down
Loading