From a979b6b5ec35d82d6cfedfc00cc3ac8540110aec Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 2 Mar 2019 19:09:39 +0800 Subject: [PATCH] impl sys_getppid. fix checking pointer for process syscalls --- crate/thread/src/thread_pool.rs | 3 +++ kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/proc.rs | 37 +++++++++++++++++++++++---------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/crate/thread/src/thread_pool.rs b/crate/thread/src/thread_pool.rs index 2f2bacd..3d464a7 100644 --- a/crate/thread/src/thread_pool.rs +++ b/crate/thread/src/thread_pool.rs @@ -198,6 +198,9 @@ impl ThreadPool { pub fn get_children(&self, tid: Tid) -> Vec { self.threads[tid].lock().as_ref().expect("process not exist").children.clone() } + pub fn get_parent(&self, tid: Tid) -> Tid { + self.threads[tid].lock().as_ref().expect("process not exist").parent + } pub fn exit(&self, tid: Tid, code: ExitCode) { // NOTE: if `tid` is running, status change will be deferred. diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 5c31dc2..d04d96f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -50,7 +50,6 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { // 034 => sys_pause(), 035 => sys_sleep(args[0]), // TODO: nanosleep 039 => sys_getpid(), -// 040 => sys_getppid(), 041 => sys_socket(args[0], args[1], args[2]), 042 => sys_connect(args[0], args[1] as *const u8, args[2]), // 043 => sys_accept(), @@ -82,6 +81,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 096 => sys_get_time(), // TODO: sys_gettimeofday // 097 => sys_getrlimit(), // 098 => sys_getrusage(), + 110 => sys_getppid(), // 133 => sys_mknod(), 141 => sys_set_priority(args[0]), // 160 => sys_setrlimit(), diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 8a61025..de43834 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -13,7 +13,9 @@ pub fn sys_fork(tf: &TrapFrame) -> SysResult { /// Wait the process exit. /// Return the PID. Store exit code to `code` if it's not null. pub fn sys_wait(pid: usize, code: *mut i32) -> SysResult { - // TODO: check ptr + if !process().memory_set.check_mut_ptr(code) { + return Err(SysError::EFAULT); + } loop { use alloc::vec; let wait_procs = match pid { @@ -49,19 +51,25 @@ pub fn sys_wait(pid: usize, code: *mut i32) -> SysResult { } pub fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8, tf: &mut TrapFrame) -> SysResult { - // TODO: check ptr - let name = if name.is_null() { "" } else { unsafe { util::from_cstr(name) } }; - info!("exec: {:?}, argc: {}, argv: {:?}", name, argc, argv); - // Copy args to kernel - let args: Vec = unsafe { - slice::from_raw_parts(argv, argc).iter() - .map(|&arg| String::from(util::from_cstr(arg))) - .collect() + let proc = process(); + let name = if name.is_null() { String::from("") } else { + unsafe { proc.memory_set.check_and_clone_cstr(name) } + .ok_or(SysError::EFAULT)? }; - - if args.len() <= 0 { + if argc <= 0 { return Err(SysError::EINVAL); } + // Check and copy args to kernel + let mut args = Vec::new(); + unsafe { + for &ptr in slice::from_raw_parts(argv, argc) { + let arg = proc.memory_set.check_and_clone_cstr(ptr) + .ok_or(SysError::EFAULT)?; + args.push(arg); + } + } + info!("exec: name: {:?}, args: {:?}", name, args); + // Read program file let path = args[0].as_str(); let inode = crate::fs::ROOT_INODE.lookup(path)?; @@ -107,6 +115,13 @@ pub fn sys_getpid() -> SysResult { Ok(thread::current().id() as isize) } +/// Get the parent process id +pub fn sys_getppid() -> SysResult { + let pid = thread::current().id(); + let ppid = processor().manager().get_parent(pid); + Ok(ppid as isize) +} + /// Exit the current process pub fn sys_exit(exit_code: isize) -> ! { let pid = thread::current().id();