Access before exec in sh

master
Jiajie Chen 6 years ago
parent a739f17988
commit 343574eb12

@ -70,6 +70,9 @@ ifeq ($(arch), $(filter $(arch), x86_64 aarch64))
@mv tmp/bin/busybox $(busybox) @mv tmp/bin/busybox $(busybox)
@rm -rf tmp && rm busybox.tar.xz @rm -rf tmp && rm busybox.tar.xz
endif endif
ifeq ($(arch), riscv64)
@wget https://github.com/rcore-os/busybox-riscv-prebuilts/raw/master/busybox-1.30.1-riscv64/busybox -O $(busybox)
endif
busybox: $(busybox) busybox: $(busybox)

@ -10,7 +10,7 @@ use alloc::vec::Vec;
use core::ptr; use core::ptr;
use rcore_user::io::get_line; use rcore_user::io::get_line;
use rcore_user::syscall::{sys_exec, sys_vfork, sys_wait}; use rcore_user::syscall::{sys_exec, sys_vfork, sys_wait, sys_getcwd, sys_chdir, sys_access};
// IMPORTANT: Must define main() like this // IMPORTANT: Must define main() like this
#[no_mangle] #[no_mangle]
@ -19,10 +19,12 @@ pub fn main() -> i32 {
let mut history = Vec::new(); let mut history = Vec::new();
loop { loop {
print!(">> "); print!("{}> ", sys_getcwd());
let cmd = get_line(&mut history); let cmd = get_line(&mut history);
// split cmd, make argc & argv // split cmd, make argc & argv
// to-do: handle quotes
let cmd = cmd.replace(' ', "\0") + "\0"; let cmd = cmd.replace(' ', "\0") + "\0";
let cmds: Vec<&str> = cmd.split('\0').collect();
let mut ptrs: Vec<usize> = cmd let mut ptrs: Vec<usize> = cmd
.split('\0') .split('\0')
.filter(|s| !s.is_empty()) .filter(|s| !s.is_empty())
@ -31,20 +33,33 @@ pub fn main() -> i32 {
if ptrs.is_empty() { if ptrs.is_empty() {
continue; continue;
} }
ptrs.push(0); // indicate the end of argv
if cmds.len() == 3 {
let pid = sys_vfork(); // handle cd
assert!(pid >= 0); if cmds[0] == "cd" {
if pid == 0 { sys_chdir(cmds[1]);
return sys_exec( continue;
ptrs[0] as *const u8, }
ptrs.as_ptr() as *const *const u8, }
ptr::null(),
); if sys_access(cmds[0]) == 0 {
ptrs.push(0); // indicate the end of argv
let pid = sys_vfork();
assert!(pid >= 0);
if pid == 0 {
return sys_exec(
ptrs[0] as *const u8,
ptrs.as_ptr() as *const *const u8,
ptr::null(),
);
} else {
let mut code: i32 = 0;
sys_wait(pid as usize, &mut code);
println!("\n[Process exited with code {}]", code);
}
} else { } else {
let mut code: i32 = 0; println!("\n[Command {} not found]", cmds[0]);
sys_wait(pid as usize, &mut code);
println!("\n[Process exited with code {}]", code);
} }
} }
} }

@ -1,4 +1,5 @@
use crate::ALLOCATOR; use crate::ALLOCATOR;
use alloc::string::String;
#[inline(always)] #[inline(always)]
fn sys_call(syscall_id: SyscallId, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 { fn sys_call(syscall_id: SyscallId, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 {
@ -111,6 +112,25 @@ pub fn sys_getpid() -> i32 {
sys_call(SyscallId::GetPid, 0, 0, 0, 0, 0, 0) sys_call(SyscallId::GetPid, 0, 0, 0, 0, 0, 0)
} }
/// Get the current working directory
pub fn sys_getcwd() -> String {
let buffer = [0u8; 256];
sys_call(SyscallId::GetCwd, buffer.as_ptr() as usize, 256, 0, 0, 0, 0);
String::from_utf8(buffer.to_vec()).unwrap()
}
/// Change the current working directory
pub fn sys_chdir(path: &str) {
let path = String::from(path) + "\0";
sys_call(SyscallId::Chdir, path.as_bytes().as_ptr() as usize, 0, 0, 0, 0, 0);
}
/// Check file accessibility
pub fn sys_access(path: &str) -> i32 {
let path = String::from(path) + "\0";
sys_call(SyscallId::FAccessAt, -100isize as usize, path.as_bytes().as_ptr() as usize, 0, 0, 0, 0)
}
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct TimeSpec { pub struct TimeSpec {
@ -171,11 +191,13 @@ enum SyscallId {
Kill = 62, Kill = 62,
Fsync = 74, Fsync = 74,
GetCwd = 79, GetCwd = 79,
Chdir = 80,
GetTime = 96, GetTime = 96,
SetPriority = 141, SetPriority = 141,
ArchPrctl = 158, ArchPrctl = 158,
GetDirEntry64 = 217, GetDirEntry64 = 217,
Openat = 257, Openat = 257,
FAccessAt = 269,
Dup3 = 292, Dup3 = 292,
// custom // custom
MapPciDevice = 999, MapPciDevice = 999,
@ -187,14 +209,12 @@ enum SyscallId {
enum SyscallId { enum SyscallId {
Read = 63, Read = 63,
Write = 64, Write = 64,
Openat = 56,
Close = 57, Close = 57,
Fstat = 80, Fstat = 80,
Seek = 62, Seek = 62,
Mmap = 222, Mmap = 222,
Munmap = 215, Munmap = 215,
Yield = 124, Yield = 124,
Dup3 = 24,
Sleep = 101, Sleep = 101,
GetPid = 172, GetPid = 172,
Clone = 220, Clone = 220,
@ -203,11 +223,15 @@ enum SyscallId {
Wait = 260, Wait = 260,
Kill = 129, Kill = 129,
Fsync = 82, Fsync = 82,
GetDirEntry64 = 61,
GetCwd = 17, GetCwd = 17,
Chdir = 49,
GetTime = 169, GetTime = 169,
SetPriority = 140, SetPriority = 140,
ArchPrctl = -4, ArchPrctl = -4,
GetDirEntry64 = 61,
Openat = 56,
Dup3 = 24,
FAccessAt = 269,
// custom // custom
MapPciDevice = 999, MapPciDevice = 999,
GetPaddr = 998, GetPaddr = 998,

Loading…
Cancel
Save