the shell that is able to fork-exec-wait

toolchain_update
Ben Pig Chu 6 years ago
parent 6302497c52
commit 5135fb0c0e

@ -198,6 +198,9 @@ fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8, tf: &mut TrapF
.collect()
};
if args.len() <= 0 {
return Err(SysError::Inval);
}
// Read program file
let path = args[0].as_str();
let inode = crate::fs::ROOT_INODE.lookup(path)?;

@ -4,6 +4,7 @@
#[macro_use]
extern crate ucore_ulib;
use ucore_ulib::io::getc;
use ucore_ulib::syscall::{sys_fork, sys_exec, sys_wait};
pub fn get_line(buffer: &mut[u8]) -> usize {
let mut pos: usize=0;
@ -43,7 +44,7 @@ const BUFFER_SIZE:usize=4096;
// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() {
pub fn main() -> i32 {
use core::mem::uninitialized;
let mut buf:[u8;BUFFER_SIZE] = unsafe { uninitialized() };
println!("Rust user shell");
@ -52,10 +53,61 @@ pub fn main() {
let len = get_line(&mut buf);
if len>BUFFER_SIZE {
println!("Command is too long!");
continue;
}else{
let cmd=&buf[..len];
let mut parsed:[u8;BUFFER_SIZE+1] = unsafe { uninitialized() };
let mut offset:[usize;BUFFER_SIZE+1] = unsafe { uninitialized() };
let mut start:usize = 0;
let mut pos:usize = 0;
let mut is_word = false;
let mut parsed_pos:usize = 0;
let mut offset_pos:usize = 0;
loop {
if pos>=cmd.len() {
if is_word {
offset[offset_pos]=parsed_pos;
offset_pos+=1;
parsed[parsed_pos..parsed_pos+pos-start].copy_from_slice(&cmd[start..pos]);
parsed_pos+=pos-start;
parsed[parsed_pos]=0;
// parsed_pos+=1;
}
break;
}
if cmd[pos]==(' ' as u8) {
if is_word {
is_word=false;
offset[offset_pos]=parsed_pos;
offset_pos+=1;
parsed[parsed_pos..parsed_pos+pos-start].copy_from_slice(&cmd[start..pos]);
parsed_pos+=pos-start;
parsed[parsed_pos]=0;
parsed_pos+=1;
}
}else{
if !is_word {
is_word=true;
start=pos;
}
}
pos+=1;
}
if offset_pos > 0 {
let pid=sys_fork();
if pid==0 {
let mut ptrs:[*const u8;BUFFER_SIZE] = unsafe { uninitialized() };
for i in 0..offset_pos {
ptrs[i]=unsafe {parsed.as_ptr().offset(offset[i] as isize)};
}
return sys_exec(parsed.as_ptr(),offset_pos,ptrs.as_ptr());
}else if pid<0 {
panic!("pid<0")
}else{
let mut code:i32 = unsafe { uninitialized() };
sys_wait(pid as usize,&mut code as *mut i32);
println!("\n[Process exited with code {}]",code);
}
}
}
let command=&buf[..len];
use core::str;
println!("{}", unsafe{ str::from_utf8_unchecked(command) })
}
}

@ -30,6 +30,11 @@ pub fn sys_exit(code: usize) -> ! {
unreachable!()
}
pub fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8) -> i32 {
sys_call(SyscallId::Exec, name as usize, argc, argv as usize, 0, 0, 0)
}
pub fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 {
sys_call(SyscallId::Write, fd, base as usize, len, 0, 0, 0)
}

Loading…
Cancel
Save