simplify user 'sh' with alloc

toolchain_update
WangRunji 6 years ago
parent 68f73bcd1a
commit b4833e9c49

@ -1,6 +1,8 @@
use alloc::string::String;
use core::fmt::{self, Write}; use core::fmt::{self, Write};
use core::option::Option; use core::option::Option;
use crate::syscall::{sys_write, sys_read, sys_putc};
use crate::syscall::{sys_putc, sys_read, sys_write};
pub const STDIN: usize = 0; pub const STDIN: usize = 0;
pub const STDOUT: usize = 1; pub const STDOUT: usize = 1;
@ -27,21 +29,50 @@ pub fn print_putc(args: fmt::Arguments) {
} }
pub fn getc() -> Option<u8> { pub fn getc() -> Option<u8> {
use core::mem::uninitialized; let mut c = 0u8;
let mut c:[u8;1] = unsafe { uninitialized() }; let ret = sys_read(STDIN, &mut c, 1);
let ret=sys_read(STDIN,c.as_mut_ptr(),1);
match ret { match ret {
1 => Some(c[0]), 1 => Some(c),
0 => None, 0 => None,
_ => panic!(), _ => panic!(),
} }
} }
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) { pub fn putc(c: u8) {
sys_putc(c); sys_putc(c);
} }
struct StdOut; struct StdOut;
struct SysPutc; struct SysPutc;
impl fmt::Write for StdOut { impl fmt::Write for StdOut {

@ -1,10 +1,13 @@
#![no_std] #![no_std]
#![feature(asm)] #![feature(asm)]
#![feature(alloc)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
#![feature(linkage)] #![feature(linkage)]
#![feature(compiler_builtins_lib)] #![feature(compiler_builtins_lib)]
extern crate alloc;
#[macro_use] #[macro_use]
pub mod io; pub mod io;
pub mod syscall; pub mod syscall;

@ -1,115 +1,39 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(alloc)]
extern crate alloc;
#[macro_use] #[macro_use]
extern crate rcore_ulib; 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 { use alloc::vec::Vec;
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
}
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 // IMPORTANT: Must define main() like this
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { pub fn main() -> i32 {
use core::mem::uninitialized;
let mut buf: [u8; BUFFER_SIZE] = unsafe { uninitialized() };
println!("Rust user shell"); println!("Rust user shell");
loop { loop {
print!(">> "); print!(">> ");
let len = get_line(&mut buf); let cmd = get_line();
if len > BUFFER_SIZE { // split cmd, make argc & argv
println!("Command is too long!"); let cmd = cmd.replace(' ', "\0") + "\0";
} else { let ptrs: Vec<*const u8> = cmd.split('\0')
let cmd = &buf[..len]; .filter(|s| !s.is_empty()).map(|s| s.as_ptr()).collect();
let mut parsed: [u8; BUFFER_SIZE + 1] = unsafe { uninitialized() }; if ptrs.is_empty() {
let mut offset: [usize; BUFFER_SIZE + 1] = unsafe { uninitialized() }; continue;
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(); let pid = sys_fork();
assert!(pid >= 0);
if pid == 0 { if pid == 0 {
let mut ptrs: [*const u8; BUFFER_SIZE] = unsafe { uninitialized() }; return sys_exec(ptrs[0], ptrs.len(), ptrs.as_ptr());
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 { } else {
let mut code: i32 = unsafe { uninitialized() }; let mut code: i32 = 0;
sys_wait(pid as usize, &mut code as *mut i32); sys_wait(pid as usize, &mut code);
println!("\n[Process exited with code {}]", code); println!("\n[Process exited with code {}]", code);
} }
} }
} }
}
}

Loading…
Cancel
Save