Skip to content

Commit

Permalink
fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
buhe committed Nov 23, 2021
1 parent 38b3c1a commit 138e014
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 22 deletions.
1 change: 0 additions & 1 deletion os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ $(KERNEL_BIN): kernel
kernel:
@echo Platform: $(BOARD)
@cd ../user && make build
@cargo clean
@cargo build --release

clean:
Expand Down
5 changes: 2 additions & 3 deletions user/src/bin/initproc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ use user::{

#[no_mangle]
fn main() -> i32 {
if fork() == 0 {
// child process
exec("user_shell\0");
if fork() == 0 {
exec("user_shell\0", &[0 as *const u8]);
} else {
loop {
let mut exit_code: i32 = 0;
Expand Down
84 changes: 80 additions & 4 deletions user/src/bin/user_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ const DL: u8 = 0x7fu8;
const BS: u8 = 0x08u8;

use alloc::string::String;
use user::{fork, exec, waitpid};
use alloc::vec::Vec;
use user::{
fork,
exec,
waitpid,
open,
OpenFlags,
close,
dup,
};
use user::console::getchar;

#[no_mangle]
pub fn main() -> i32 {
println!("Rust user shell");
println!("Rust user shell");
let mut line: String = String::new();
print!(">> ");
loop {
Expand All @@ -26,11 +35,78 @@ pub fn main() -> i32 {
LF | CR => {
println!("");
if !line.is_empty() {
line.push('\0');
let args: Vec<_> = line.as_str().split(' ').collect();
let mut args_copy: Vec<String> = args
.iter()
.map(|&arg| {
let mut string = String::new();
string.push_str(arg);
string
})
.collect();

args_copy
.iter_mut()
.for_each(|string| {
string.push('\0');
});

// redirect input
let mut input = String::new();
if let Some((idx, _)) = args_copy
.iter()
.enumerate()
.find(|(_, arg)| arg.as_str() == "<\0") {
input = args_copy[idx + 1].clone();
args_copy.drain(idx..=idx + 1);
}

// redirect output
let mut output = String::new();
if let Some((idx, _)) = args_copy
.iter()
.enumerate()
.find(|(_, arg)| arg.as_str() == ">\0") {
output = args_copy[idx + 1].clone();
args_copy.drain(idx..=idx + 1);
}

let mut args_addr: Vec<*const u8> = args_copy
.iter()
.map(|arg| arg.as_ptr())
.collect();
args_addr.push(0 as *const u8);
let pid = fork();
if pid == 0 {
// input redirection
if !input.is_empty() {
let input_fd = open(input.as_str(), OpenFlags::RDONLY);
if input_fd == -1 {
println!("Error when opening file {}", input);
return -4;
}
let input_fd = input_fd as usize;
close(0);
assert_eq!(dup(input_fd), 0);
close(input_fd);
}
// output redirection
if !output.is_empty() {
let output_fd = open(
output.as_str(),
OpenFlags::CREATE | OpenFlags::WRONLY
);
if output_fd == -1 {
println!("Error when opening file {}", output);
return -4;
}
let output_fd = output_fd as usize;
close(1);
assert_eq!(dup(output_fd), 1);
close(output_fd);
}
// child process
if exec(line.as_str()) == -1 {
if exec(args_copy[0].as_str(), args_addr.as_slice()) == -1 {
println!("Error when executing!");
return -4;
}
Expand Down
40 changes: 28 additions & 12 deletions user/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
#![no_std]
#![feature(asm)]
#![feature(linkage)]
#![feature(alloc_error_handler)]
#![feature(panic_info_message)]

#[macro_use]
extern crate bitflags;
#![feature(alloc_error_handler)]

#[macro_use]
pub mod console;
mod lang;
mod scall_os;
mod lang;

extern crate alloc;
#[macro_use]
extern crate bitflags;

use buddy_system_allocator::LockedHeap;
use scall_os::*;
use buddy_system_allocator::LockedHeap;
use alloc::vec::Vec;

const USER_HEAP_SIZE: usize = 16384;
const USER_HEAP_SIZE: usize = 32768;

static mut HEAP_SPACE: [u8; USER_HEAP_SIZE] = [0; USER_HEAP_SIZE];

Expand All @@ -29,17 +31,31 @@ pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {

#[no_mangle]
#[link_section = ".text.entry"]
pub extern "C" fn _start() -> ! {
unsafe {
pub extern "C" fn _start(argc: usize, argv: usize) -> ! {
unsafe {
HEAP.lock()
.init(HEAP_SPACE.as_ptr() as usize, USER_HEAP_SIZE);
}
exit(main());
let mut v: Vec<&'static str> = Vec::new();
for i in 0..argc {
let str_start = unsafe {
((argv + i * core::mem::size_of::<usize>()) as *const usize).read_volatile()
};
let len = (0usize..).find(|i| unsafe {
((str_start + *i) as *const u8).read_volatile() == 0
}).unwrap();
v.push(
core::str::from_utf8(unsafe {
core::slice::from_raw_parts(str_start as *const u8, len)
}).unwrap()
);
}
exit(main(argc, v.as_slice()));
}

#[linkage = "weak"]
#[no_mangle]
fn main() -> i32 {
fn main(_argc: usize, _argv: &[&str]) -> i32 {
panic!("Cannot find main!");
}

Expand All @@ -64,7 +80,7 @@ pub fn yield_() -> isize { sys_yield() }
pub fn get_time() -> isize { sys_get_time() }
pub fn getpid() -> isize { sys_getpid() }
pub fn fork() -> isize { sys_fork() }
pub fn exec(path: &str) -> isize { sys_exec(path) }
pub fn exec(path: &str, args: &[*const u8]) -> isize { sys_exec(path, args) }
pub fn wait(exit_code: &mut i32) -> isize {
loop {
match sys_waitpid(-1, exit_code as *mut _) {
Expand Down
4 changes: 2 additions & 2 deletions user/src/scall_os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ pub fn sys_fork() -> isize {
syscall(SYSCALL_FORK, [0, 0, 0])
}

pub fn sys_exec(path: &str) -> isize {
syscall(SYSCALL_EXEC, [path.as_ptr() as usize, 0, 0])
pub fn sys_exec(path: &str, args: &[*const u8]) -> isize {
syscall(SYSCALL_EXEC, [path.as_ptr() as usize, args.as_ptr() as usize, 0])
}

pub fn sys_waitpid(pid: isize, exit_code: *mut i32) -> isize {
Expand Down

0 comments on commit 138e014

Please sign in to comment.