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 args: Vec<String>,
pub envs: BTreeMap<String, String>,
pub envs: Vec<String>,
pub auxv: BTreeMap<u8, usize>,
}
@ -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();

@ -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<Thread>
pub fn new_user<'a, Iter>(
data: &[u8],
exec_path: &str,
args: Iter,
envs: Vec<String>,
) -> Box<Thread>
where
Iter: Iterator<Item = &'a str>,
{
@ -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) }
};

@ -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 {

@ -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

Loading…
Cancel
Save