simplify user 'sh' with alloc

master
WangRunji 6 years ago
parent 68f73bcd1a
commit b4833e9c49

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

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

@ -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<buffer.len() {
buffer[pos]=byte;
}
pos+=1;
print!("{}", c);
}
'\n' | '\r' => {
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);
}
}
}

Loading…
Cancel
Save