Open coolyjg opened 1 year ago
renameat
, readv
, fdatasync
. Please note that fsync
and fdatasync
is not really implemented.For python update openat
and add readlinkat
First add a struct Directory at fs.rs
pub struct Directory {
inner: Mutex<axfs::fops::Directory>,
}
impl Directory {
fn new(inner: axfs::fops::Directory) -> Self {
Self {
inner: Mutex::new(inner),
}
}
fn add_to_fd_table(self) -> LinuxResult<c_int> {
super::fd_ops::add_file_like(Arc::new(self))
}
fn from_fd(fd: c_int) -> LinuxResult<Arc<Self>> {
let f = super::fd_ops::get_file_like(fd)?;
f.into_any()
.downcast::<Self>()
.map_err(|_| LinuxError::EINVAL)
}
}
impl FileLike for Directory {
fn read(&self, buf: &mut [u8]) -> LinuxResult<usize> {
Err(LinuxError::EACCES)
}
fn write(&self, buf: &[u8]) -> LinuxResult<usize> {
Err(LinuxError::EACCES)
}
fn stat(&self) -> LinuxResult<ctypes::stat> {
Err(LinuxError::EACCES)
}
fn into_any(self: Arc<Self>) -> Arc<dyn core::any::Any + Send + Sync> {
self
}
fn poll(&self) -> LinuxResult<PollState> {
Ok(PollState {
readable: true,
writable: true,
})
}
fn set_nonblocking(&self, _nonblocking: bool) -> LinuxResult {
Ok(())
}
}
modify openat
make it can open a dir
/// Open a file under a specific dir
///
///
pub fn sys_openat(_fd: usize, path: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int {
let path = char_ptr_to_str(path);
debug!("sys_openat <= {:?}, {:#o} {:#o}", path, flags, mode);
syscall_body!(sys_openat, {
let options = flags_to_options(flags, mode);
if (flags as u32) & ctypes::O_DIRECTORY != 0 {
let dir = axfs::fops::Directory::open_dir(path?, &options)?;
Directory::new(dir).add_to_fd_table()
}
else{
let file = axfs::fops::File::open(path?, &options)?;
File::new(file).add_to_fd_table()
}
})
}
add readlinkat
/// read value of a symbolic link relative to directory file descriptor
///
///
pub fn sys_readlinkat(fd: c_int, pathname: *const c_char, buf: *mut c_char, bufsize: usize) -> usize {
let path = char_ptr_to_str(pathname);
debug!("sys_readlinkat <= path = {:?}, fd = {:}, bufsize = {:}", path, fd, bufsize);
syscall_body!(sys_readlinkat, {
let mut options = OpenOptions::new();
options.read(true);
let dst = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, bufsize as _) };
// if fd == AT_FDCWD then readat the relative path
if fd == ctypes::AT_FDCWD as c_int {
let file = axfs::fops::File::open(path?, &options)?;
let mut file = File::new(file);
Ok(file.read(dst)?)
}
else{
let dir = Directory::from_fd(fd)?;
let mut file = dir.inner.lock().open_file_at(path?, &options)?;
Ok(file.read(dst)?)
}
})
}
For python add getdents64
First add type ino_t
, dirent
in api/arceos_posix_api/build.rs
fn gen_c_to_rust_bindings(in_file: &str, out_file: &str) {
let allow_types = [
"stat",
"size_t",
"ssize_t",
...
"ino_t", // new line
"dirent", // new line
];
...
}
Then add sys_getdents64
in fs.rs
type LinuxDirent64 = ctypes::dirent;
fn convert_name_to_array(name: &[u8]) -> [i8; 256] {
let mut array = [0i8; 256];
let len = name.len();
let name_ptr = name.as_ptr() as *const i8;
let array_ptr = array.as_mut_ptr();
unsafe {
core::ptr::copy_nonoverlapping(name_ptr, array_ptr, len);
}
array
}
/// Read directory entries from a directory file descriptor.
///
/// TODO: check errors
pub unsafe fn sys_getdents64(fd: c_uint, dirent: *mut LinuxDirent64, count: c_uint) -> c_long {
debug!(
"sys_getdents64 <= fd: {}, dirent: {:p}, count: {}",
fd, dirent, count
);
syscall_body!(sys_getdents64, {
let expect_entries = count as usize / 280;
let dir = Directory::from_fd(fd as i32)?;
let mut my_dirent: Vec<DirEntry> = (0..expect_entries).map(|_| DirEntry::default()).collect();
let n = dir.inner.lock().read_dir(&mut my_dirent)?;
for (i, entry) in my_dirent.iter().enumerate() {
let linux_dirent = LinuxDirent64 {
d_ino: 1,
d_off: 280,
d_reclen: 280,
d_type: entry.entry_type() as u8,
d_name: convert_name_to_array(&entry.name_as_bytes()),
};
unsafe {
core::ptr::write(dirent.add(i), linux_dirent);
}
}
Ok(n * 280)
})
}
Missing syscall :SYS_linkat
, the system call number is 37
Missing syscall: SYS_getrandom
, whose number is 278 in aarch64.
Missing syscall:
SYS_getrandom
, whose number is 278 in aarch64.
Maybe ulib/ruxlibc/src/rand.rs
should be put under ruxos-posix-api/
Missing syscall: SYS_preadv
, whose number is 69 in aarch64.
Missing the implement of syscall SYS_mremap
, which needed by WAMR.
Missing the implement of syscall
SYS_mremap
, which needed by WAMR.
You can use munmap
+ mmap
to do a fake implementation temporarily. True implementation should wait for @ken4647 's work.
Previous readlinkat
implementation is wrong. Now it is changed to #61
A bug in system call SYS_ppoll
: argument timeout could be NULL, and should be checked before using it.
below is new version:
/// `ppoll` used by A64. Currently ignore signal
pub unsafe fn sys_ppoll(
fds: *mut ctypes::pollfd,
nfds: ctypes::nfds_t,
timeout: *const ctypes::timespec,
_sig_mask: *const ctypes::sigset_t,
_sig_num: ctypes::size_t,
) -> c_int {
let to = if timeout.is_null(){
-1
} else {
Duration::from(*timeout).as_millis() as c_int
};
debug!("sys_ppoll <= nfds: {} timeout: {:?}", nfds, to);
sys_poll(fds, nfds, to)
}
missing SYS_kill and SYS_times.
missing SYS_timerfd_create, SYS_timerfd_settime and SYS_timerfd_gettime.
This issue is intended to collect problems/requirements/demands for syscalls in rukos when integrating apps. Here, you can add: