From e9597d901bbae5d4e267abaa0fc29ffbe2ed9e2e Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Tue, 18 Jan 2022 04:19:05 -0800 Subject: [PATCH] Remove cmdargs and i/o redirection. --- os/src/mm/page_table.rs | 3 +- os/src/syscall/mod.rs | 2 +- os/src/syscall/process.rs | 22 ++------- os/src/task/task.rs | 36 ++------------- user/src/bin/cat.rs | 32 ------------- user/src/bin/cmdline_args.rs | 16 ------- user/src/bin/initproc.rs | 4 +- user/src/bin/run_pipe_test.rs | 4 +- user/src/bin/user_shell.rs | 85 +++-------------------------------- user/src/bin/usertests.rs | 4 +- user/src/lib.rs | 24 ++-------- user/src/syscall.rs | 9 +--- 12 files changed, 28 insertions(+), 213 deletions(-) delete mode 100644 user/src/bin/cat.rs delete mode 100644 user/src/bin/cmdline_args.rs diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index e0a1bc6b..1412c9fe 100644 --- a/os/src/mm/page_table.rs +++ b/os/src/mm/page_table.rs @@ -190,6 +190,7 @@ pub fn translated_str(token: usize, ptr: *const u8) -> String { string } +#[allow(unused)] pub fn translated_ref(token: usize, ptr: *const T) -> &'static T { let page_table = PageTable::from_token(token); page_table.translate_va(VirtAddr::from(ptr as usize)).unwrap().get_ref() @@ -252,4 +253,4 @@ impl Iterator for UserBufferIterator { Some(r) } } -} \ No newline at end of file +} diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index cd65aa78..817c0ea7 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -27,7 +27,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { SYSCALL_GET_TIME => sys_get_time(), SYSCALL_GETPID => sys_getpid(), SYSCALL_FORK => sys_fork(), - SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize), + SYSCALL_EXEC => sys_exec(args[0] as *const u8), SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32), _ => panic!("Unsupported syscall_id: {}", syscall_id), } diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index cf3cbcb4..a43ccfaf 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -9,15 +9,12 @@ use crate::timer::get_time_ms; use crate::mm::{ translated_str, translated_refmut, - translated_ref, }; use crate::fs::{ open_file, OpenFlags, }; use alloc::sync::Arc; -use alloc::vec::Vec; -use alloc::string::String; pub fn sys_exit(exit_code: i32) -> ! { exit_current_and_run_next(exit_code); @@ -51,25 +48,14 @@ pub fn sys_fork() -> isize { new_pid as isize } -pub fn sys_exec(path: *const u8, mut args: *const usize) -> isize { +pub fn sys_exec(path: *const u8) -> isize { let token = current_user_token(); let path = translated_str(token, path); - let mut args_vec: Vec = Vec::new(); - loop { - let arg_str_ptr = *translated_ref(token, args); - if arg_str_ptr == 0 { - break; - } - args_vec.push(translated_str(token, arg_str_ptr as *const u8)); - unsafe { args = args.add(1); } - } if let Some(app_inode) = open_file(path.as_str(), OpenFlags::RDONLY) { let all_data = app_inode.read_all(); let task = current_task().unwrap(); - let argc = args_vec.len(); - task.exec(all_data.as_slice(), args_vec); - // return argc because cx.x[10] will be covered with it later - argc as isize + task.exec(all_data.as_slice()); + 0 } else { -1 } @@ -112,4 +98,4 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { -2 } // ---- release current PCB automatically -} \ No newline at end of file +} diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 25b2226d..f46db719 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -3,7 +3,6 @@ use crate::mm::{ PhysPageNum, KERNEL_SPACE, VirtAddr, - translated_refmut, }; use crate::trap::{TrapContext, trap_handler}; use crate::config::TRAP_CONTEXT; @@ -14,7 +13,6 @@ use super::{PidHandle, pid_alloc, KernelStack}; use alloc::sync::{Weak, Arc}; use alloc::vec; use alloc::vec::Vec; -use alloc::string::String; use crate::fs::{File, Stdin, Stdout}; pub struct TaskControlBlock { @@ -109,37 +107,13 @@ impl TaskControlBlock { ); task_control_block } - pub fn exec(&self, elf_data: &[u8], args: Vec) { + pub fn exec(&self, elf_data: &[u8]) { // memory_set with elf program headers/trampoline/trap context/user stack - let (memory_set, mut user_sp, entry_point) = MemorySet::from_elf(elf_data); + let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data); let trap_cx_ppn = memory_set .translate(VirtAddr::from(TRAP_CONTEXT).into()) .unwrap() .ppn(); - // push arguments on user stack - user_sp -= (args.len() + 1) * core::mem::size_of::(); - let argv_base = user_sp; - let mut argv: Vec<_> = (0..=args.len()) - .map(|arg| { - translated_refmut( - memory_set.token(), - (argv_base + arg * core::mem::size_of::()) as *mut usize - ) - }) - .collect(); - *argv[args.len()] = 0; - for i in 0..args.len() { - user_sp -= args[i].len() + 1; - *argv[i] = user_sp; - let mut p = user_sp; - for c in args[i].as_bytes() { - *translated_refmut(memory_set.token(), p as *mut u8) = *c; - p += 1; - } - *translated_refmut(memory_set.token(), p as *mut u8) = 0; - } - // make the user_sp aligned to 8B for k210 platform - user_sp -= user_sp % core::mem::size_of::(); // **** access current TCB exclusively let mut inner = self.inner_exclusive_access(); @@ -148,15 +122,13 @@ impl TaskControlBlock { // update trap_cx ppn inner.trap_cx_ppn = trap_cx_ppn; // initialize trap_cx - let mut trap_cx = TrapContext::app_init_context( + let trap_cx = TrapContext::app_init_context( entry_point, user_sp, KERNEL_SPACE.exclusive_access().token(), self.kernel_stack.get_top(), trap_handler as usize, ); - trap_cx.x[10] = args.len(); - trap_cx.x[11] = argv_base; *inner.get_trap_cx() = trap_cx; // **** release current PCB } @@ -221,4 +193,4 @@ pub enum TaskStatus { Ready, Running, Zombie, -} \ No newline at end of file +} diff --git a/user/src/bin/cat.rs b/user/src/bin/cat.rs deleted file mode 100644 index a5c9ee5c..00000000 --- a/user/src/bin/cat.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![no_std] -#![no_main] - -#[macro_use] -extern crate user_lib; -extern crate alloc; - -use user_lib::{ - open, - OpenFlags, - close, - read, -}; -use alloc::string::String; - -#[no_mangle] -pub fn main(argc: usize, argv: &[&str]) -> i32 { - assert!(argc == 2); - let fd = open(argv[1], OpenFlags::RDONLY); - if fd == -1 { - panic!("Error occured when opening file"); - } - let fd = fd as usize; - let mut buf = [0u8; 256]; - loop { - let size = read(fd, &mut buf) as usize; - if size == 0 { break; } - println!("{}", core::str::from_utf8(&buf[..size]).unwrap()); - } - close(fd); - 0 -} diff --git a/user/src/bin/cmdline_args.rs b/user/src/bin/cmdline_args.rs deleted file mode 100644 index b49ec332..00000000 --- a/user/src/bin/cmdline_args.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![no_std] -#![no_main] - -extern crate alloc; - -#[macro_use] -extern crate user_lib; - -#[no_mangle] -pub fn main(argc: usize, argv: &[&str]) -> i32 { - println!("argc = {}", argc); - for i in 0..argc { - println!("argv[{}] = {}", i, argv[i]); - } - 0 -} \ No newline at end of file diff --git a/user/src/bin/initproc.rs b/user/src/bin/initproc.rs index 99563f47..a201fffb 100644 --- a/user/src/bin/initproc.rs +++ b/user/src/bin/initproc.rs @@ -14,7 +14,7 @@ use user_lib::{ #[no_mangle] fn main() -> i32 { if fork() == 0 { - exec("user_shell\0", &[0 as *const u8]); + exec("user_shell\0"); } else { loop { let mut exit_code: i32 = 0; @@ -31,4 +31,4 @@ fn main() -> i32 { } } 0 -} \ No newline at end of file +} diff --git a/user/src/bin/run_pipe_test.rs b/user/src/bin/run_pipe_test.rs index 000b82d5..a62a98b7 100644 --- a/user/src/bin/run_pipe_test.rs +++ b/user/src/bin/run_pipe_test.rs @@ -10,7 +10,7 @@ use user_lib::{fork, exec, wait}; pub fn main() -> i32 { for i in 0..1000 { if fork() == 0 { - exec("pipe_large_test\0", &[0 as *const u8]); + exec("pipe_large_test\0"); } else { let mut _unused: i32 = 0; wait(&mut _unused); @@ -18,4 +18,4 @@ pub fn main() -> i32 { } } 0 -} \ No newline at end of file +} diff --git a/user/src/bin/user_shell.rs b/user/src/bin/user_shell.rs index b2c33f2d..f0858234 100644 --- a/user/src/bin/user_shell.rs +++ b/user/src/bin/user_shell.rs @@ -12,16 +12,7 @@ const DL: u8 = 0x7fu8; const BS: u8 = 0x08u8; use alloc::string::String; -use alloc::vec::Vec; -use user_lib::{ - fork, - exec, - waitpid, - open, - OpenFlags, - close, - dup, -}; +use user_lib::{fork, exec, waitpid}; use user_lib::console::getchar; #[no_mangle] @@ -35,78 +26,11 @@ pub fn main() -> i32 { LF | CR => { println!(""); if !line.is_empty() { - let args: Vec<_> = line.as_str().split(' ').collect(); - let mut args_copy: Vec = 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); + line.push('\0'); 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(args_copy[0].as_str(), args_addr.as_slice()) == -1 { + if exec(line.as_str()) == -1 { println!("Error when executing!"); return -4; } @@ -135,4 +59,5 @@ pub fn main() -> i32 { } } } -} \ No newline at end of file +} + diff --git a/user/src/bin/usertests.rs b/user/src/bin/usertests.rs index e8be6c45..cf77f15c 100644 --- a/user/src/bin/usertests.rs +++ b/user/src/bin/usertests.rs @@ -26,7 +26,7 @@ pub fn main() -> i32 { println!("Usertests: Running {}", test); let pid = fork(); if pid == 0 { - exec(*test, &[0 as *const u8]); + exec(*test); panic!("unreachable!"); } else { let mut exit_code: i32 = Default::default(); @@ -37,4 +37,4 @@ pub fn main() -> i32 { } println!("Usertests passed!"); 0 -} \ No newline at end of file +} diff --git a/user/src/lib.rs b/user/src/lib.rs index 95d611db..9f409728 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -14,7 +14,6 @@ extern crate bitflags; use syscall::*; use buddy_system_allocator::LockedHeap; -use alloc::vec::Vec; const USER_HEAP_SIZE: usize = 32768; @@ -30,31 +29,17 @@ pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { #[no_mangle] #[link_section = ".text.entry"] -pub extern "C" fn _start(argc: usize, argv: usize) -> ! { +pub extern "C" fn _start() -> ! { unsafe { HEAP.lock() .init(HEAP_SPACE.as_ptr() as usize, USER_HEAP_SIZE); } - let mut v: Vec<&'static str> = Vec::new(); - for i in 0..argc { - let str_start = unsafe { - ((argv + i * core::mem::size_of::()) 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())); + exit(main()); } #[linkage = "weak"] #[no_mangle] -fn main(_argc: usize, _argv: &[&str]) -> i32 { +fn main() -> i32 { panic!("Cannot find main!"); } @@ -68,7 +53,6 @@ bitflags! { } } -pub fn dup(fd: usize) -> isize { sys_dup(fd) } pub fn open(path: &str, flags: OpenFlags) -> isize { sys_open(path, flags.bits) } pub fn close(fd: usize) -> isize { sys_close(fd) } pub fn read(fd: usize, buf: &mut [u8]) -> isize { sys_read(fd, buf) } @@ -78,7 +62,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, args: &[*const u8]) -> isize { sys_exec(path, args) } +pub fn exec(path: &str) -> isize { sys_exec(path) } pub fn wait(exit_code: &mut i32) -> isize { loop { match sys_waitpid(-1, exit_code as *mut _) { diff --git a/user/src/syscall.rs b/user/src/syscall.rs index 4c1bffce..7bdf57f2 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -1,6 +1,5 @@ use core::arch::asm; -const SYSCALL_DUP: usize = 24; const SYSCALL_OPEN: usize = 56; const SYSCALL_CLOSE: usize = 57; const SYSCALL_READ: usize = 63; @@ -27,10 +26,6 @@ fn syscall(id: usize, args: [usize; 3]) -> isize { ret } -pub fn sys_dup(fd: usize) -> isize { - syscall(SYSCALL_DUP, [fd, 0, 0]) -} - pub fn sys_open(path: &str, flags: u32) -> isize { syscall(SYSCALL_OPEN, [path.as_ptr() as usize, flags as usize, 0]) } @@ -68,8 +63,8 @@ pub fn sys_fork() -> isize { syscall(SYSCALL_FORK, [0, 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_exec(path: &str) -> isize { + syscall(SYSCALL_EXEC, [path.as_ptr() as usize, 0, 0]) } pub fn sys_waitpid(pid: isize, exit_code: *mut i32) -> isize {