diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index 4f60ca2..fab4552 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -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)?; diff --git a/user/src/bin/sh.rs b/user/src/bin/sh.rs index 486541f..70e84e3 100644 --- a/user/src/bin/sh.rs +++ b/user/src/bin/sh.rs @@ -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) }) } } diff --git a/user/ucore-ulib/src/syscall.rs b/user/ucore-ulib/src/syscall.rs index 9eeddf2..8f0b06a 100644 --- a/user/ucore-ulib/src/syscall.rs +++ b/user/ucore-ulib/src/syscall.rs @@ -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) }