diff --git a/rust/src/bin/sh.rs b/rust/src/bin/sh.rs index d9482e5..5a80bbe 100644 --- a/rust/src/bin/sh.rs +++ b/rust/src/bin/sh.rs @@ -10,7 +10,7 @@ use alloc::vec::Vec; use core::ptr; use rcore_user::io::get_line; -use rcore_user::syscall::{sys_exec, sys_fork, sys_wait}; +use rcore_user::syscall::{sys_exec, sys_vfork, sys_wait}; // IMPORTANT: Must define main() like this #[no_mangle] @@ -33,7 +33,7 @@ pub fn main() -> i32 { } ptrs.push(0); // indicate the end of argv - let pid = sys_fork(); + let pid = sys_vfork(); assert!(pid >= 0); if pid == 0 { return sys_exec( diff --git a/rust/src/bin/tls.rs b/rust/src/bin/tls.rs index 9646e87..ebbdec0 100644 --- a/rust/src/bin/tls.rs +++ b/rust/src/bin/tls.rs @@ -5,7 +5,7 @@ #[macro_use] extern crate rcore_user; -use rcore_user::syscall::{sys_arch_prctl, sys_fork, sys_getpid, sys_sleep}; +use rcore_user::syscall::{sys_arch_prctl, sys_vfork, sys_getpid, sys_sleep}; fn set_tls(tls: usize, pid: usize) { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] @@ -39,8 +39,8 @@ fn get_tls() -> usize { pub fn main() { println!("I am going to set TLS specific registers"); println!("And see if it changes between context switch"); - sys_fork(); - sys_fork(); + sys_vfork(); + sys_vfork(); let pid = sys_getpid(); for i in 0..10 { let magic = 0xcafebabe; diff --git a/rust/src/syscall.rs b/rust/src/syscall.rs index d340aac..f52eb31 100644 --- a/rust/src/syscall.rs +++ b/rust/src/syscall.rs @@ -55,7 +55,8 @@ pub fn sys_open(path: &str, flags: usize) -> i32 { use core::mem::replace; let end = unsafe { &mut *(path.as_ptr().offset(path.len() as isize) as *mut u8) }; let backup = replace(end, 0); - let ret = sys_call(SyscallId::Open, path.as_ptr() as usize, flags, 0, 0, 0, 0); + const AT_FDCWD: isize = -100; + let ret = sys_call(SyscallId::Openat, AT_FDCWD as usize, path.as_ptr() as usize, flags, 0, 0, 0); *end = backup; ret } @@ -69,8 +70,17 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> i32 { } /// Fork the current process. Return the child's PID. -pub fn sys_fork() -> i32 { - sys_call(SyscallId::Fork, 0, 0, 0, 0, 0, 0) +pub fn sys_vfork() -> i32 { + let mut sp: usize = 0; + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + unsafe { + asm!("mv $0, sp" : "=r" (sp) :: ); + } + // TODO: more arch + const CLONE_VFORK: usize = 0x00004000; + const CLONE_VM: usize = 0x00000100; + const SIGCHILD: usize = 17; + sys_call(SyscallId::Clone, CLONE_VFORK | CLONE_VM | SIGCHILD, sp, 0, 0, 0, 0) } /// Wait the process exit. @@ -120,11 +130,11 @@ pub fn sys_arch_prctl(code: i32, addr: usize) -> i32 { sys_call(SyscallId::ArchPrctl, code as usize, addr, 0, 0, 0, 0) } +#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] #[allow(dead_code)] enum SyscallId { Read = 0, Write = 1, - Open = 2, Close = 3, Fstat = 4, Seek = 8, @@ -135,7 +145,6 @@ enum SyscallId { Sleep = 35, GetPid = 39, Clone = 56, - Fork = 57, Exec = 59, Exit = 60, Wait = 61, @@ -146,4 +155,33 @@ enum SyscallId { GetTime = 96, SetPriority = 141, ArchPrctl = 158, + Openat = 257, } + +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[allow(dead_code)] +enum SyscallId { + Read = 63, + Write = 64, + Openat = 56, + Close = 57, + Fstat = 80, + Seek = 62, + Mmap = 222, + Munmap = 215, + Yield = 124, + Dup2 = -1, + Sleep = 101, + GetPid = 172, + Clone = 220, + Exec = 221, + Exit = 93, + Wait = 260, + Kill = 129, + Fsync = 82, + GetDirEntry = -3, + GetCwd = 17, + GetTime = 169, + SetPriority = 140, + ArchPrctl = -4, +} \ No newline at end of file