diff --git a/kernel/src/process/abi.rs b/kernel/src/process/abi.rs index 913fb1a..dcaa428 100644 --- a/kernel/src/process/abi.rs +++ b/kernel/src/process/abi.rs @@ -5,7 +5,7 @@ use core::ptr::null; pub struct ProcInitInfo { pub args: Vec, - pub envs: BTreeMap, + pub envs: Vec, pub auxv: BTreeMap, } @@ -19,10 +19,8 @@ impl ProcInitInfo { let envs: Vec<_> = self .envs .iter() - .map(|(key, value)| { - writer.push_str(value.as_str()); - writer.push_slice(&[b"="]); - writer.push_slice(key.as_bytes()); + .map(|arg| { + writer.push_str(arg.as_str()); writer.sp }) .collect(); diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 0bf6781..a8b0b63 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -158,7 +158,12 @@ impl Thread { } /// Make a new user process from ELF `data` - pub fn new_user<'a, Iter>(data: &[u8], exec_path: &str, args: Iter) -> Box + pub fn new_user<'a, Iter>( + data: &[u8], + exec_path: &str, + args: Iter, + envs: Vec, + ) -> Box where Iter: Iterator, { @@ -185,7 +190,7 @@ impl Thread { new_args.insert(1, exec_path); new_args.remove(2); warn!("loader args: {:?}", new_args); - return Thread::new_user(buf.as_slice(), exec_path,new_args.into_iter()); + return Thread::new_user(buf.as_slice(), exec_path, new_args.into_iter(), envs); } else { warn!("loader specified as {} but failed to read", &loader_path); } @@ -215,7 +220,7 @@ impl Thread { // Make init info let init_info = ProcInitInfo { args: args.map(|s| String::from(s)).collect(), - envs: BTreeMap::new(), + envs, auxv: { let mut map = BTreeMap::new(); if let Some(phdr_vaddr) = elf.get_phdr_vaddr() { @@ -421,7 +426,7 @@ impl ElfExt for ElfFile<'_> { virt_addr + mem_size, ph.flags().to_attr(), ByFrame::new(GlobalFrameAlloc), - "", + "elf", ); unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) } }; diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 9b2690e..4c88786 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -10,9 +10,12 @@ use alloc::vec::Vec; pub fn run_user_shell() { if let Ok(inode) = ROOT_INODE.lookup("rust/sh") { let data = inode.read_as_vec().unwrap(); - processor() - .manager() - .add(Thread::new_user(data.as_slice(), "rust/sh", "sh".split(' '))); + processor().manager().add(Thread::new_user( + data.as_slice(), + "rust/sh", + "sh".split(' '), + Vec::new(), + )); } else { processor().manager().add(Thread::new_kernel(shell, 0)); } @@ -23,9 +26,11 @@ pub fn run_user_shell() { let cmdline = CMDLINE.read(); let inode = ROOT_INODE.lookup(&cmdline).unwrap(); let data = inode.read_as_vec().unwrap(); - processor() - .manager() - .add(Thread::new_user(data.as_slice(), cmdline.split(' '))); + processor().manager().add(Thread::new_user( + data.as_slice(), + cmdline.split(' '), + Vec::new(), + )); } pub extern "C" fn shell(_arg: usize) -> ! { @@ -42,9 +47,12 @@ pub extern "C" fn shell(_arg: usize) -> ! { let name = cmd.trim().split(' ').next().unwrap(); if let Ok(file) = ROOT_INODE.lookup(name) { let data = file.read_as_vec().unwrap(); - let _pid = processor() - .manager() - .add(Thread::new_user(data.as_slice(), &cmd, cmd.split(' '))); + let _pid = processor().manager().add(Thread::new_user( + data.as_slice(), + &cmd, + cmd.split(' '), + Vec::new(), + )); // TODO: wait until process exits, or use user land shell completely //unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); } else { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 1545af6..aaf9b9f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -208,11 +208,11 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_getpgid is unimplemented"); Ok(0) } - SYS_GETGROUPS=> { + SYS_GETGROUPS => { warn!("sys_getgroups is unimplemented"); Ok(0) } - SYS_SETGROUPS=> { + SYS_SETGROUPS => { warn!("sys_setgroups is unimplemented"); Ok(0) } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 1159ff3..7e68948 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -146,23 +146,28 @@ pub fn sys_exec( current_argv = current_argv.add(1); } } -// // Check and copy envs to kernel -// let mut envs = Vec::new(); -// unsafe { -// let mut current_env = envp as *const *const u8; -// proc.vm.check_read_ptr(current_env)?; -// while !(*current_env).is_null() { -// let env = proc.vm.check_and_clone_cstr(*current_env)?; -// envs.push(env); -// current_env = current_env.add(1); -// } -// } -// + // Check and copy envs to kernel + let mut envs = Vec::new(); + unsafe { + let mut current_env = envp as *const *const u8; + if !current_env.is_null() { + proc.vm.check_read_ptr(current_env)?; + while !(*current_env).is_null() { + let env = proc.vm.check_and_clone_cstr(*current_env)?; + envs.push(env); + current_env = current_env.add(1); + } + } + } + if args.is_empty() { return Err(SysError::EINVAL); } - info!("EXEC: name:{:?} , args {:?}", exec_name, args); + info!( + "EXEC: name:{:?} , args {:?}, envp {:?}", + exec_name, args, envs + ); // Read program file //let path = args[0].as_str(); @@ -171,8 +176,8 @@ pub fn sys_exec( let buf = inode.read_as_vec()?; // Make new Thread - let iter = args.iter().map(|s| s.as_str()); - let mut thread = Thread::new_user(buf.as_slice(), exec_path, iter); + let args_iter = args.iter().map(|s| s.as_str()); + let mut thread = Thread::new_user(buf.as_slice(), exec_path, args_iter, envs); thread.proc.lock().clone_for_exec(&proc); // Activate new page table