a shell without execute is a repeater!

toolchain_update
Ben Pig Chu 6 years ago
parent 364497e379
commit 6302497c52

@ -0,0 +1,61 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate ucore_ulib;
use ucore_ulib::io::getc;
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() {
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!");
continue;
}
let command=&buf[..len];
use core::str;
println!("{}", unsafe{ str::from_utf8_unchecked(command) })
}
}

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

@ -1,12 +1,12 @@
use crate::syscall::{sys_close, sys_dup, sys_exit, sys_open};
use crate::syscall::{O_RDONLY, O_WRONLY};
use crate::io::{O_RDONLY, O_WRONLY, STDIN, STDOUT};
use core::alloc::Layout;
use core::panic::PanicInfo;
// used for panic
macro_rules! print {
($($arg:tt)*) => ({
$crate::syscall::print_putc(format_args!($($arg)*));
$crate::io::print_putc(format_args!($($arg)*));
});
}
@ -33,11 +33,11 @@ fn initfd(fd2: usize, path: &str, open_flags: usize) -> i32 {
#[no_mangle]
pub extern "C" fn _start(_argc: isize, _argv: *const *const u8) -> ! {
let fd = initfd(0, "stdin:", O_RDONLY);
let fd = initfd(STDIN, "stdin:", O_RDONLY);
if fd < 0 {
panic!("open <stdin> failed: {}.", fd);
}
let fd = initfd(1, "stdout:", O_WRONLY);
let fd = initfd(STDOUT, "stdout:", O_WRONLY);
if fd < 0 {
panic!("open <stdout> failed: {}.", fd);
}

@ -6,5 +6,6 @@
#![feature(compiler_builtins_lib)]
#[macro_use]
pub mod io;
pub mod syscall;
pub mod lang_items;

@ -1,48 +1,3 @@
use core::fmt::{self, Write};
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ({
$crate::syscall::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();
}
struct StdOut;
struct SysPutc;
impl fmt::Write for StdOut {
fn write_str(&mut self, s: &str) -> fmt::Result {
if sys_write(1, 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 as char);
}
Ok(())
}
}
#[inline(always)]
fn sys_call(syscall_id: SyscallId, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 {
let id = syscall_id as usize;
@ -79,6 +34,10 @@ pub fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 {
sys_call(SyscallId::Write, fd, base as usize, len, 0, 0, 0)
}
pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> i32 {
sys_call(SyscallId::Read, fd, base as usize, len, 0, 0, 0)
}
pub fn sys_open(path: &str, flags: usize) -> i32 {
// UNSAFE: append '\0' to the string
use core::mem::replace;
@ -134,7 +93,7 @@ pub fn sys_lab6_set_priority(priority: usize) -> i32 {
sys_call(SyscallId::Lab6SetPriority, priority, 0, 0, 0, 0, 0)
}
pub fn sys_putc(c: char) -> i32 {
pub fn sys_putc(c: u8) -> i32 {
sys_call(SyscallId::Putc, c as usize, 0, 0, 0, 0, 0)
}
@ -167,15 +126,3 @@ enum SyscallId{
Dup = 130,
Lab6SetPriority = 255,
}
/* 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…
Cancel
Save