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)
@rm -rf tmp && rm busybox.tar.xz
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)

@ -10,7 +10,7 @@ use alloc::vec::Vec;
use core::ptr;
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
#[no_mangle]
@ -19,10 +19,12 @@ pub fn main() -> i32 {
let mut history = Vec::new();
loop {
print!(">> ");
print!("{}> ", sys_getcwd());
let cmd = get_line(&mut history);
// split cmd, make argc & argv
// to-do: handle quotes
let cmd = cmd.replace(' ', "\0") + "\0";
let cmds: Vec<&str> = cmd.split('\0').collect();
let mut ptrs: Vec<usize> = cmd
.split('\0')
.filter(|s| !s.is_empty())
@ -31,20 +33,33 @@ pub fn main() -> i32 {
if ptrs.is_empty() {
continue;
}
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(),
);
if cmds.len() == 3 {
// handle cd
if cmds[0] == "cd" {
sys_chdir(cmds[1]);
continue;
}
}
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 {
let mut code: i32 = 0;
sys_wait(pid as usize, &mut code);
println!("\n[Process exited with code {}]", code);
println!("\n[Command {} not found]", cmds[0]);
}
}
}

@ -1,4 +1,5 @@
use crate::ALLOCATOR;
use alloc::string::String;
#[inline(always)]
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)
}
/// 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)]
#[derive(Debug, Copy, Clone)]
pub struct TimeSpec {
@ -171,11 +191,13 @@ enum SyscallId {
Kill = 62,
Fsync = 74,
GetCwd = 79,
Chdir = 80,
GetTime = 96,
SetPriority = 141,
ArchPrctl = 158,
GetDirEntry64 = 217,
Openat = 257,
FAccessAt = 269,
Dup3 = 292,
// custom
MapPciDevice = 999,
@ -187,14 +209,12 @@ enum SyscallId {
enum SyscallId {
Read = 63,
Write = 64,
Openat = 56,
Close = 57,
Fstat = 80,
Seek = 62,
Mmap = 222,
Munmap = 215,
Yield = 124,
Dup3 = 24,
Sleep = 101,
GetPid = 172,
Clone = 220,
@ -203,11 +223,15 @@ enum SyscallId {
Wait = 260,
Kill = 129,
Fsync = 82,
GetDirEntry64 = 61,
GetCwd = 17,
Chdir = 49,
GetTime = 169,
SetPriority = 140,
ArchPrctl = -4,
GetDirEntry64 = 61,
Openat = 56,
Dup3 = 24,
FAccessAt = 269,
// custom
MapPciDevice = 999,
GetPaddr = 998,

Loading…
Cancel
Save