# Conflicts: # kernel/src/arch/riscv32/compiler_rt.c # kernel/src/arch/riscv32/consts.rs # kernel/src/arch/riscv32/context.rs # kernel/src/arch/riscv32/io.rs # kernel/src/arch/riscv32/memory.rs # kernel/src/arch/riscv32/paging.rs # user/ucore-ulib/src/syscall.rstoolchain_update
commit
33eaded142
@ -0,0 +1,115 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate ucore_ulib;
|
||||||
|
use ucore_ulib::io::getc;
|
||||||
|
use ucore_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
|
||||||
|
}
|
||||||
|
|
||||||
|
const BUFFER_SIZE: usize = 4096;
|
||||||
|
|
||||||
|
// 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!");
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! print {
|
||||||
|
($($arg:tt)*) => ({
|
||||||
|
$crate::io::print(format_args!($($arg)*));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! println {
|
||||||
|
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||||
|
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(args: fmt::Arguments) {
|
||||||
|
StdOut.write_fmt(args).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 putc(c:u8){
|
||||||
|
sys_putc(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StdOut;
|
||||||
|
struct SysPutc;
|
||||||
|
|
||||||
|
impl fmt::Write for StdOut {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
if sys_write(STDOUT, s.as_ptr(), s.len()) >= 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(fmt::Error::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Write for SysPutc {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
for c in s.bytes() {
|
||||||
|
sys_putc(c);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VFS flags */
|
||||||
|
// TODO: use bitflags
|
||||||
|
// flags for open: choose one of these
|
||||||
|
pub const O_RDONLY: usize = 0; // open for reading only
|
||||||
|
pub const O_WRONLY: usize = 1; // open for writing only
|
||||||
|
pub const O_RDWR: usize = 2; // open for reading and writing
|
||||||
|
// then or in any of these:
|
||||||
|
pub const O_CREAT: usize = 0x00000004; // create file if it does not exist
|
||||||
|
pub const O_EXCL: usize = 0x00000008; // error if O_CREAT and the file exists
|
||||||
|
pub const O_TRUNC: usize = 0x00000010; // truncate file upon open
|
||||||
|
pub const O_APPEND: usize = 0x00000020; // append on each write
|
Loading…
Reference in new issue