Implement env support in sys_exec

master
Jiajie Chen 6 years ago
parent aa5d0028f0
commit 0ff24fe589

@ -5,7 +5,7 @@ use core::ptr::null;
pub struct ProcInitInfo { pub struct ProcInitInfo {
pub args: Vec<String>, pub args: Vec<String>,
pub envs: BTreeMap<String, String>, pub envs: Vec<String>,
pub auxv: BTreeMap<u8, usize>, pub auxv: BTreeMap<u8, usize>,
} }
@ -19,10 +19,8 @@ impl ProcInitInfo {
let envs: Vec<_> = self let envs: Vec<_> = self
.envs .envs
.iter() .iter()
.map(|(key, value)| { .map(|arg| {
writer.push_str(value.as_str()); writer.push_str(arg.as_str());
writer.push_slice(&[b"="]);
writer.push_slice(key.as_bytes());
writer.sp writer.sp
}) })
.collect(); .collect();

@ -158,7 +158,12 @@ impl Thread {
} }
/// Make a new user process from ELF `data` /// Make a new user process from ELF `data`
pub fn new_user<'a, Iter>(data: &[u8], exec_path: &str, args: Iter) -> Box<Thread> pub fn new_user<'a, Iter>(
data: &[u8],
exec_path: &str,
args: Iter,
envs: Vec<String>,
) -> Box<Thread>
where where
Iter: Iterator<Item = &'a str>, Iter: Iterator<Item = &'a str>,
{ {
@ -185,7 +190,7 @@ impl Thread {
new_args.insert(1, exec_path); new_args.insert(1, exec_path);
new_args.remove(2); new_args.remove(2);
warn!("loader args: {:?}", new_args); 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 { } else {
warn!("loader specified as {} but failed to read", &loader_path); warn!("loader specified as {} but failed to read", &loader_path);
} }
@ -215,7 +220,7 @@ impl Thread {
// Make init info // Make init info
let init_info = ProcInitInfo { let init_info = ProcInitInfo {
args: args.map(|s| String::from(s)).collect(), args: args.map(|s| String::from(s)).collect(),
envs: BTreeMap::new(), envs,
auxv: { auxv: {
let mut map = BTreeMap::new(); let mut map = BTreeMap::new();
if let Some(phdr_vaddr) = elf.get_phdr_vaddr() { if let Some(phdr_vaddr) = elf.get_phdr_vaddr() {
@ -421,7 +426,7 @@ impl ElfExt for ElfFile<'_> {
virt_addr + mem_size, virt_addr + mem_size,
ph.flags().to_attr(), ph.flags().to_attr(),
ByFrame::new(GlobalFrameAlloc), ByFrame::new(GlobalFrameAlloc),
"", "elf",
); );
unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) } unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) }
}; };

@ -10,9 +10,12 @@ use alloc::vec::Vec;
pub fn run_user_shell() { pub fn run_user_shell() {
if let Ok(inode) = ROOT_INODE.lookup("rust/sh") { if let Ok(inode) = ROOT_INODE.lookup("rust/sh") {
let data = inode.read_as_vec().unwrap(); let data = inode.read_as_vec().unwrap();
processor() processor().manager().add(Thread::new_user(
.manager() data.as_slice(),
.add(Thread::new_user(data.as_slice(), "rust/sh", "sh".split(' '))); "rust/sh",
"sh".split(' '),
Vec::new(),
));
} else { } else {
processor().manager().add(Thread::new_kernel(shell, 0)); processor().manager().add(Thread::new_kernel(shell, 0));
} }
@ -23,9 +26,11 @@ pub fn run_user_shell() {
let cmdline = CMDLINE.read(); let cmdline = CMDLINE.read();
let inode = ROOT_INODE.lookup(&cmdline).unwrap(); let inode = ROOT_INODE.lookup(&cmdline).unwrap();
let data = inode.read_as_vec().unwrap(); let data = inode.read_as_vec().unwrap();
processor() processor().manager().add(Thread::new_user(
.manager() data.as_slice(),
.add(Thread::new_user(data.as_slice(), cmdline.split(' '))); cmdline.split(' '),
Vec::new(),
));
} }
pub extern "C" fn shell(_arg: usize) -> ! { 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(); let name = cmd.trim().split(' ').next().unwrap();
if let Ok(file) = ROOT_INODE.lookup(name) { if let Ok(file) = ROOT_INODE.lookup(name) {
let data = file.read_as_vec().unwrap(); let data = file.read_as_vec().unwrap();
let _pid = processor() let _pid = processor().manager().add(Thread::new_user(
.manager() data.as_slice(),
.add(Thread::new_user(data.as_slice(), &cmd, cmd.split(' '))); &cmd,
cmd.split(' '),
Vec::new(),
));
// TODO: wait until process exits, or use user land shell completely // TODO: wait until process exits, or use user land shell completely
//unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); //unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap();
} else { } else {

@ -208,11 +208,11 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
warn!("sys_getpgid is unimplemented"); warn!("sys_getpgid is unimplemented");
Ok(0) Ok(0)
} }
SYS_GETGROUPS=> { SYS_GETGROUPS => {
warn!("sys_getgroups is unimplemented"); warn!("sys_getgroups is unimplemented");
Ok(0) Ok(0)
} }
SYS_SETGROUPS=> { SYS_SETGROUPS => {
warn!("sys_setgroups is unimplemented"); warn!("sys_setgroups is unimplemented");
Ok(0) Ok(0)
} }

@ -146,23 +146,28 @@ pub fn sys_exec(
current_argv = current_argv.add(1); current_argv = current_argv.add(1);
} }
} }
// // Check and copy envs to kernel // Check and copy envs to kernel
// let mut envs = Vec::new(); let mut envs = Vec::new();
// unsafe { unsafe {
// let mut current_env = envp as *const *const u8; let mut current_env = envp as *const *const u8;
// proc.vm.check_read_ptr(current_env)?; if !current_env.is_null() {
// while !(*current_env).is_null() { proc.vm.check_read_ptr(current_env)?;
// let env = proc.vm.check_and_clone_cstr(*current_env)?; while !(*current_env).is_null() {
// envs.push(env); let env = proc.vm.check_and_clone_cstr(*current_env)?;
// current_env = current_env.add(1); envs.push(env);
// } current_env = current_env.add(1);
// } }
// }
}
if args.is_empty() { if args.is_empty() {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
info!("EXEC: name:{:?} , args {:?}", exec_name, args); info!(
"EXEC: name:{:?} , args {:?}, envp {:?}",
exec_name, args, envs
);
// Read program file // Read program file
//let path = args[0].as_str(); //let path = args[0].as_str();
@ -171,8 +176,8 @@ pub fn sys_exec(
let buf = inode.read_as_vec()?; let buf = inode.read_as_vec()?;
// Make new Thread // Make new Thread
let iter = args.iter().map(|s| s.as_str()); let args_iter = args.iter().map(|s| s.as_str());
let mut thread = Thread::new_user(buf.as_slice(), exec_path, iter); let mut thread = Thread::new_user(buf.as_slice(), exec_path, args_iter, envs);
thread.proc.lock().clone_for_exec(&proc); thread.proc.lock().clone_for_exec(&proc);
// Activate new page table // Activate new page table

Loading…
Cancel
Save