From b4833e9c49531427c0d7915379f586a9d83ae80d Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 20 Jan 2019 00:57:30 +0800 Subject: [PATCH] simplify user 'sh' with alloc --- user/rcore-ulib/src/io.rs | 59 ++++++++++++++----- user/rcore-ulib/src/lib.rs | 3 + user/src/bin/sh.rs | 118 +++++++------------------------------ 3 files changed, 69 insertions(+), 111 deletions(-) diff --git a/user/rcore-ulib/src/io.rs b/user/rcore-ulib/src/io.rs index 4c287c2..fa456a6 100644 --- a/user/rcore-ulib/src/io.rs +++ b/user/rcore-ulib/src/io.rs @@ -1,9 +1,11 @@ +use alloc::string::String; use core::fmt::{self, Write}; use core::option::Option; -use crate::syscall::{sys_write, sys_read, sys_putc}; -pub const STDIN: usize=0; -pub const STDOUT: usize=1; +use crate::syscall::{sys_putc, sys_read, sys_write}; + +pub const STDIN: usize = 0; +pub const STDOUT: usize = 1; #[macro_export] macro_rules! print { @@ -26,22 +28,51 @@ pub fn print_putc(args: fmt::Arguments) { SysPutc.write_fmt(args).unwrap(); } -pub fn getc() -> Option{ - use core::mem::uninitialized; - let mut c:[u8;1] = unsafe { uninitialized() }; - let ret=sys_read(STDIN,c.as_mut_ptr(),1); - match ret { - 1 => Some(c[0]), - 0 => None, - _ => panic!(), - } +pub fn getc() -> Option { + let mut c = 0u8; + let ret = sys_read(STDIN, &mut c, 1); + match ret { + 1 => Some(c), + 0 => None, + _ => panic!(), + } } -pub fn putc(c:u8){ - sys_putc(c); +pub fn get_line() -> String { + let mut s = String::new(); + loop { + let ret = getc(); + match ret { + None => return s, + Some(byte) => { + let c = byte as char; + match c { + '\x08' | '\x7f' /* '\b' */ => { + if s.pop().is_some() { + print!("\x08 \x08"); + } + } + ' '...'\x7e' => { + s.push(c); + print!("{}", c); + } + '\n' | '\r' => { + print!("\n"); + return s; + } + _ => {} + } + } + } + } +} + +pub fn putc(c: u8) { + sys_putc(c); } struct StdOut; + struct SysPutc; impl fmt::Write for StdOut { diff --git a/user/rcore-ulib/src/lib.rs b/user/rcore-ulib/src/lib.rs index 18aa0cb..3863e78 100644 --- a/user/rcore-ulib/src/lib.rs +++ b/user/rcore-ulib/src/lib.rs @@ -1,10 +1,13 @@ #![no_std] #![feature(asm)] +#![feature(alloc)] #![feature(lang_items)] #![feature(panic_info_message)] #![feature(linkage)] #![feature(compiler_builtins_lib)] +extern crate alloc; + #[macro_use] pub mod io; pub mod syscall; diff --git a/user/src/bin/sh.rs b/user/src/bin/sh.rs index 4323de0..b467790 100644 --- a/user/src/bin/sh.rs +++ b/user/src/bin/sh.rs @@ -1,115 +1,39 @@ #![no_std] #![no_main] +#![feature(alloc)] +extern crate alloc; #[macro_use] extern crate rcore_ulib; -use rcore_ulib::io::getc; -use rcore_ulib::syscall::{sys_exec, sys_fork, sys_wait}; -pub fn get_line(buffer: &mut [u8]) -> usize { - let mut pos: usize = 0; - loop { - let ret = getc(); - match ret { - None => break, - Some(byte) => { - let c = byte as char; - match c { - '\u{8}' /* '\b' */ => { - if pos > 0 { - print!("\u{8} \u{8}"); - pos-=1; - } - } - ' '...'\u{7e}' => { - if pos { - print!("\n"); - break; - } - _ => {} - } - } - } - } - pos -} +use alloc::vec::Vec; -const BUFFER_SIZE: usize = 4096; +use rcore_ulib::io::get_line; +use rcore_ulib::syscall::{sys_exec, sys_fork, sys_wait}; // IMPORTANT: Must define main() like this #[no_mangle] pub fn main() -> i32 { - use core::mem::uninitialized; - let mut buf: [u8; BUFFER_SIZE] = unsafe { uninitialized() }; println!("Rust user shell"); loop { print!(">> "); - let len = get_line(&mut buf); - if len > BUFFER_SIZE { - println!("Command is too long!"); + let cmd = get_line(); + // split cmd, make argc & argv + let cmd = cmd.replace(' ', "\0") + "\0"; + let ptrs: Vec<*const u8> = cmd.split('\0') + .filter(|s| !s.is_empty()).map(|s| s.as_ptr()).collect(); + if ptrs.is_empty() { + continue; + } + + let pid = sys_fork(); + assert!(pid >= 0); + if pid == 0 { + return sys_exec(ptrs[0], ptrs.len(), ptrs.as_ptr()); } 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 mut code: i32 = 0; + sys_wait(pid as usize, &mut code); + println!("\n[Process exited with code {}]", code); } } }