mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-17 12:47:16 +00:00
add syscall rt_sigaction and rt_sigreturn
This commit is contained in:
parent
288cba2832
commit
634d4a5016
@ -3,7 +3,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
|
use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
|
||||||
use spin::mutex::Mutex;
|
use spin::mutex::Mutex;
|
||||||
|
|
||||||
use crate::{debug, task::Task};
|
use crate::task::Task;
|
||||||
|
|
||||||
/// A wait queue.
|
/// A wait queue.
|
||||||
///
|
///
|
||||||
@ -214,7 +214,7 @@ impl<D: Clone + Eq + PartialEq> Waiter<D> {
|
|||||||
pub fn wait(&self) {
|
pub fn wait(&self) {
|
||||||
while !self.is_woken_up.load(Ordering::Relaxed) {
|
while !self.is_woken_up.load(Ordering::Relaxed) {
|
||||||
// yield the execution, to allow other task to contine
|
// yield the execution, to allow other task to contine
|
||||||
debug!("Waiter: wait");
|
// debug!("Waiter: wait");
|
||||||
Task::yield_now();
|
Task::yield_now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ pub fn handle_exception(context: &mut CpuContext) {
|
|||||||
let current = current!();
|
let current = current!();
|
||||||
let pid = current.pid();
|
let pid = current.pid();
|
||||||
debug!("trap info = {:x?}", trap_info);
|
debug!("trap info = {:x?}", trap_info);
|
||||||
|
debug!("cpu context = {:x?}", context);
|
||||||
let signal = Box::new(FaultSignal::new(&trap_info));
|
let signal = Box::new(FaultSignal::new(&trap_info));
|
||||||
current.sig_queues().lock().enqueue(signal);
|
current.sig_queues().lock().enqueue(signal);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ use self::signal::sig_disposition::SigDispositions;
|
|||||||
use self::signal::sig_mask::SigMask;
|
use self::signal::sig_mask::SigMask;
|
||||||
use self::signal::sig_queues::SigQueues;
|
use self::signal::sig_queues::SigQueues;
|
||||||
use self::signal::signals::kernel::KernelSignal;
|
use self::signal::signals::kernel::KernelSignal;
|
||||||
|
use self::signal::SigContext;
|
||||||
use self::status::ProcessStatus;
|
use self::status::ProcessStatus;
|
||||||
use self::task::create_user_task_from_elf;
|
use self::task::create_user_task_from_elf;
|
||||||
|
|
||||||
@ -64,6 +65,8 @@ pub struct Process {
|
|||||||
sig_queues: Mutex<SigQueues>,
|
sig_queues: Mutex<SigQueues>,
|
||||||
/// Process-level sigmask
|
/// Process-level sigmask
|
||||||
sig_mask: Mutex<SigMask>,
|
sig_mask: Mutex<SigMask>,
|
||||||
|
/// Signal handler Context
|
||||||
|
sig_context: Mutex<Option<SigContext>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Process {
|
impl Process {
|
||||||
@ -116,6 +119,7 @@ impl Process {
|
|||||||
sig_dispositions: Mutex::new(sig_dispositions),
|
sig_dispositions: Mutex::new(sig_dispositions),
|
||||||
sig_queues: Mutex::new(sig_queues),
|
sig_queues: Mutex::new(sig_queues),
|
||||||
sig_mask: Mutex::new(sig_mask),
|
sig_mask: Mutex::new(sig_mask),
|
||||||
|
sig_context: Mutex::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +226,10 @@ impl Process {
|
|||||||
&self.process_group
|
&self.process_group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sig_context(&self) -> &Mutex<Option<SigContext>> {
|
||||||
|
&self.sig_context
|
||||||
|
}
|
||||||
|
|
||||||
/// add a child process
|
/// add a child process
|
||||||
pub fn add_child(&self, child: Arc<Process>) {
|
pub fn add_child(&self, child: Arc<Process>) {
|
||||||
debug!("process: {}, add child: {} ", self.pid(), child.pid());
|
debug!("process: {}, add child: {} ", self.pid(), child.pid());
|
||||||
|
@ -21,7 +21,7 @@ impl ProcessFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// used for wait4 and kill
|
// used for wait4 and kill
|
||||||
pub fn from_id(wait_pid: isize) -> Self {
|
pub fn from_id(wait_pid: i32) -> Self {
|
||||||
// https://man7.org/linux/man-pages/man2/waitpid.2.html
|
// https://man7.org/linux/man-pages/man2/waitpid.2.html
|
||||||
// https://man7.org/linux/man-pages/man2/kill.2.html
|
// https://man7.org/linux/man-pages/man2/kill.2.html
|
||||||
if wait_pid < -1 {
|
if wait_pid < -1 {
|
||||||
|
13
src/kxos-std/src/process/signal/c_types.rs
Normal file
13
src/kxos-std/src/process/signal/c_types.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub type sigset_t = u64;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct sigaction_t {
|
||||||
|
pub handler_ptr: Vaddr,
|
||||||
|
pub flags: u32,
|
||||||
|
pub restorer_ptr: Vaddr,
|
||||||
|
pub mask: sigset_t,
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
pub mod c_types;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod sig_action;
|
pub mod sig_action;
|
||||||
pub mod sig_disposition;
|
pub mod sig_disposition;
|
||||||
@ -6,15 +7,19 @@ pub mod sig_num;
|
|||||||
pub mod sig_queues;
|
pub mod sig_queues;
|
||||||
pub mod signals;
|
pub mod signals;
|
||||||
|
|
||||||
use kxos_frame::task::Task;
|
use kxos_frame::{cpu::CpuContext, task::Task};
|
||||||
|
|
||||||
|
use self::sig_mask::SigMask;
|
||||||
|
use self::sig_num::SigNum;
|
||||||
|
use crate::memory::{write_bytes_to_user, write_val_to_user};
|
||||||
|
use crate::process::signal::sig_action::SigActionFlags;
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::sig_action::{SigAction, SigDefaultAction},
|
process::signal::sig_action::{SigAction, SigDefaultAction},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handle pending signal for current process
|
/// Handle pending signal for current process
|
||||||
pub fn handle_pending_signal() {
|
pub fn handle_pending_signal(context: &mut CpuContext) {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let pid = current.pid();
|
let pid = current.pid();
|
||||||
let process_name = current.filename().unwrap();
|
let process_name = current.filename().unwrap();
|
||||||
@ -25,12 +30,24 @@ pub fn handle_pending_signal() {
|
|||||||
let sig_num = signal.num();
|
let sig_num = signal.num();
|
||||||
debug!("sig_num = {:?}, sig_name = {}", sig_num, sig_num.sig_name());
|
debug!("sig_num = {:?}, sig_name = {}", sig_num, sig_num.sig_name());
|
||||||
let sig_action = current.sig_dispositions().lock().get(sig_num);
|
let sig_action = current.sig_dispositions().lock().get(sig_num);
|
||||||
debug!("sig action: {:?}", sig_action);
|
debug!("sig action: {:x?}", sig_action);
|
||||||
match sig_action {
|
match sig_action {
|
||||||
SigAction::Ign => {
|
SigAction::Ign => {
|
||||||
debug!("Ignore signal {:?}", sig_num);
|
debug!("Ignore signal {:?}", sig_num);
|
||||||
}
|
}
|
||||||
SigAction::User { .. } => todo!(),
|
SigAction::User {
|
||||||
|
handler_addr,
|
||||||
|
flags,
|
||||||
|
restorer_addr,
|
||||||
|
mask,
|
||||||
|
} => handle_user_signal_handler(
|
||||||
|
sig_num,
|
||||||
|
handler_addr,
|
||||||
|
flags,
|
||||||
|
restorer_addr,
|
||||||
|
mask,
|
||||||
|
context,
|
||||||
|
),
|
||||||
SigAction::Dfl => {
|
SigAction::Dfl => {
|
||||||
let sig_default_action = SigDefaultAction::from_signum(sig_num);
|
let sig_default_action = SigDefaultAction::from_signum(sig_num);
|
||||||
debug!("sig_default_action: {:?}", sig_default_action);
|
debug!("sig_default_action: {:?}", sig_default_action);
|
||||||
@ -70,3 +87,85 @@ pub fn handle_pending_signal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_user_signal_handler(
|
||||||
|
sig_num: SigNum,
|
||||||
|
handler_addr: Vaddr,
|
||||||
|
flags: SigActionFlags,
|
||||||
|
restorer_addr: Vaddr,
|
||||||
|
mask: SigMask,
|
||||||
|
context: &mut CpuContext,
|
||||||
|
) {
|
||||||
|
debug!("sig_num = {:?}", sig_num);
|
||||||
|
debug!("handler_addr = 0x{:x}", handler_addr);
|
||||||
|
debug!("flags = {:?}", flags);
|
||||||
|
debug!("restorer_addr = 0x{:x}", restorer_addr);
|
||||||
|
// FIXME: How to respect flags
|
||||||
|
if flags.intersects(!(SigActionFlags::SA_RESTART | SigActionFlags::SA_RESTORER)) {
|
||||||
|
panic!("Unsupported Signal flags");
|
||||||
|
}
|
||||||
|
let current = current!();
|
||||||
|
// block signals in sigmask when running signal handler
|
||||||
|
current.sig_mask().lock().block(mask.as_u64());
|
||||||
|
// store context in current process
|
||||||
|
let sig_context = SigContext::new(context.clone(), mask);
|
||||||
|
*(current.sig_context().lock()) = Some(sig_context);
|
||||||
|
// set up signal stack in user stack
|
||||||
|
let mut user_rsp = context.gp_regs.rsp;
|
||||||
|
// avoid corrupt user stack, we minus 128 first.
|
||||||
|
user_rsp = user_rsp - 128;
|
||||||
|
// Copy the trampoline code.
|
||||||
|
if flags.contains(SigActionFlags::SA_RESTORER) {
|
||||||
|
// If contains SA_RESTORER flag, trampoline code is provided by libc in restorer_addr.
|
||||||
|
// We just store restorer_addr on user stack to allow user code just to trampoline code.
|
||||||
|
user_rsp = write_u64_to_user_stack(user_rsp, restorer_addr as u64);
|
||||||
|
} else {
|
||||||
|
// Otherwise we create
|
||||||
|
const TRAMPOLINE: &[u8] = &[
|
||||||
|
0xb8, 0x0f, 0x00, 0x00, 0x00, // mov eax, 15(syscall number of rt_sigreturn)
|
||||||
|
0x0f, 0x05, // syscall (call rt_sigreturn)
|
||||||
|
0x90, // nop (for alignment)
|
||||||
|
];
|
||||||
|
user_rsp = user_rsp - TRAMPOLINE.len() as u64;
|
||||||
|
let trampoline_rip = user_rsp;
|
||||||
|
write_bytes_to_user(user_rsp as Vaddr, TRAMPOLINE);
|
||||||
|
user_rsp = write_u64_to_user_stack(user_rsp, trampoline_rip);
|
||||||
|
}
|
||||||
|
context.gp_regs.rip = handler_addr as _;
|
||||||
|
context.gp_regs.rsp = user_rsp;
|
||||||
|
// parameters of signal handler
|
||||||
|
context.gp_regs.rdi = sig_num.as_u8() as u64; // signal number
|
||||||
|
context.gp_regs.rsi = 0; // siginfo_t* siginfo
|
||||||
|
context.gp_regs.rdx = 0; // void* ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_u64_to_user_stack(rsp: u64, value: u64) -> u64 {
|
||||||
|
let rsp = rsp - 8;
|
||||||
|
write_val_to_user(rsp as Vaddr, &value);
|
||||||
|
rsp
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to store process context before running signal handler.
|
||||||
|
/// In rt_sigreturn, this context is used to restore process context.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct SigContext {
|
||||||
|
cpu_context: CpuContext,
|
||||||
|
sig_mask: SigMask,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SigContext {
|
||||||
|
pub const fn new(cpu_context: CpuContext, sig_mask: SigMask) -> SigContext {
|
||||||
|
Self {
|
||||||
|
cpu_context,
|
||||||
|
sig_mask,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cpu_context(&self) -> &CpuContext {
|
||||||
|
&self.cpu_context
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sig_mask(&self) -> &SigMask {
|
||||||
|
&self.sig_mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::{constants::*, sig_mask::SigMask, sig_num::SigNum};
|
use super::{c_types::sigaction_t, constants::*, sig_mask::SigMask, sig_num::SigNum};
|
||||||
|
use crate::prelude::*;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use kxos_frame::warn;
|
use kxos_frame::warn;
|
||||||
|
|
||||||
@ -21,6 +22,58 @@ impl Default for SigAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<sigaction_t> for SigAction {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(input: sigaction_t) -> Result<Self> {
|
||||||
|
let action = match input.handler_ptr {
|
||||||
|
SIG_DFL => SigAction::Dfl,
|
||||||
|
SIG_IGN => SigAction::Ign,
|
||||||
|
_ => {
|
||||||
|
let flags = SigActionFlags::from_bits_truncate(input.flags);
|
||||||
|
let mask = SigMask::from(input.mask);
|
||||||
|
SigAction::User {
|
||||||
|
handler_addr: input.handler_ptr,
|
||||||
|
flags,
|
||||||
|
restorer_addr: input.restorer_ptr,
|
||||||
|
mask,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SigAction {
|
||||||
|
pub fn to_c(&self) -> sigaction_t {
|
||||||
|
match self {
|
||||||
|
SigAction::Dfl => sigaction_t {
|
||||||
|
handler_ptr: SIG_DFL,
|
||||||
|
flags: 0,
|
||||||
|
restorer_ptr: 0,
|
||||||
|
mask: 0,
|
||||||
|
},
|
||||||
|
SigAction::Ign => sigaction_t {
|
||||||
|
handler_ptr: SIG_IGN,
|
||||||
|
flags: 0,
|
||||||
|
restorer_ptr: 0,
|
||||||
|
mask: 0,
|
||||||
|
},
|
||||||
|
SigAction::User {
|
||||||
|
handler_addr,
|
||||||
|
flags,
|
||||||
|
restorer_addr,
|
||||||
|
mask,
|
||||||
|
} => sigaction_t {
|
||||||
|
handler_ptr: *handler_addr,
|
||||||
|
flags: flags.to_u32(),
|
||||||
|
restorer_ptr: *restorer_addr,
|
||||||
|
mask: mask.as_u64(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct SigActionFlags: u32 {
|
pub struct SigActionFlags: u32 {
|
||||||
const SA_NOCLDSTOP = 1;
|
const SA_NOCLDSTOP = 1;
|
||||||
@ -35,10 +88,11 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u32> for SigActionFlags {
|
impl TryFrom<u32> for SigActionFlags {
|
||||||
type Error = &'static str;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(bits: u32) -> Result<Self, Self::Error> {
|
fn try_from(bits: u32) -> Result<Self> {
|
||||||
let flags = SigActionFlags::from_bits(bits).ok_or_else(|| "invalid sigaction flags")?;
|
let flags = SigActionFlags::from_bits(bits)
|
||||||
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid sig action flag"))?;
|
||||||
if flags.contains(SigActionFlags::SA_RESTART) {
|
if flags.contains(SigActionFlags::SA_RESTART) {
|
||||||
warn!("SA_RESTART is not supported");
|
warn!("SA_RESTART is not supported");
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ pub fn create_new_task(userspace: Arc<UserSpace>, parent: Weak<Process>) -> Arc<
|
|||||||
if current.status().lock().is_zombie() {
|
if current.status().lock().is_zombie() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
handle_pending_signal();
|
handle_pending_signal(context);
|
||||||
if current.status().lock().is_zombie() {
|
if current.status().lock().is_zombie() {
|
||||||
debug!("exit due to signal");
|
debug!("exit due to signal");
|
||||||
break;
|
break;
|
||||||
@ -66,7 +66,7 @@ pub fn create_new_task(userspace: Arc<UserSpace>, parent: Weak<Process>) -> Arc<
|
|||||||
while current.status().lock().is_suspend() {
|
while current.status().lock().is_suspend() {
|
||||||
Process::yield_now();
|
Process::yield_now();
|
||||||
debug!("{} is suspended.", current.pid());
|
debug!("{} is suspended.", current.pid());
|
||||||
handle_pending_signal();
|
handle_pending_signal(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!("exit user loop");
|
debug!("exit user loop");
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use super::constants::*;
|
use super::{constants::*, SyscallReturn};
|
||||||
use crate::{memory::read_bytes_from_user, prelude::*, syscall::SYS_ACCESS};
|
use crate::{memory::read_bytes_from_user, prelude::*, syscall::SYS_ACCESS};
|
||||||
|
|
||||||
pub fn sys_access(filename_ptr: Vaddr, file_mode: u64) -> Result<isize> {
|
pub fn sys_access(filename_ptr: Vaddr, file_mode: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_ACCESS]", SYS_ACCESS);
|
debug!("[syscall][id={}][SYS_ACCESS]", SYS_ACCESS);
|
||||||
let mut filename_buffer = vec![0u8; MAX_FILENAME_LEN];
|
let mut filename_buffer = vec![0u8; MAX_FILENAME_LEN];
|
||||||
read_bytes_from_user(filename_ptr, &mut filename_buffer);
|
read_bytes_from_user(filename_ptr, &mut filename_buffer);
|
||||||
let filename = CString::from(CStr::from_bytes_until_nul(&filename_buffer).unwrap());
|
let filename = CString::from(CStr::from_bytes_until_nul(&filename_buffer).unwrap());
|
||||||
debug!("filename: {:?}", filename);
|
debug!("filename: {:?}", filename);
|
||||||
warn!("access currenly does not check and just return success");
|
warn!("access currenly does not check and just return success");
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ use kxos_frame::cpu::CpuContext;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::syscall::SYS_ARCH_PRCTL;
|
use crate::syscall::SYS_ARCH_PRCTL;
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ArchPrctlCode {
|
pub enum ArchPrctlCode {
|
||||||
@ -26,19 +28,12 @@ impl TryFrom<u64> for ArchPrctlCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_arch_prctl(code: u64, addr: u64, context: &mut CpuContext) -> Result<isize> {
|
pub fn sys_arch_prctl(code: u64, addr: u64, context: &mut CpuContext) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_ARCH_PRCTL]", SYS_ARCH_PRCTL);
|
debug!("[syscall][id={}][SYS_ARCH_PRCTL]", SYS_ARCH_PRCTL);
|
||||||
let arch_prctl_code = ArchPrctlCode::try_from(code)?;
|
let arch_prctl_code = ArchPrctlCode::try_from(code)?;
|
||||||
debug!("arch_prctl_code: {:?}", arch_prctl_code);
|
debug!("arch_prctl_code: {:?}", arch_prctl_code);
|
||||||
let res = do_arch_prctl(arch_prctl_code, addr, context).unwrap();
|
let res = do_arch_prctl(arch_prctl_code, addr, context).unwrap();
|
||||||
Ok(res as _)
|
Ok(SyscallReturn::Return(res as _))
|
||||||
// match arch_prctl_code {
|
|
||||||
// Err(_) => SyscallResult::Return(-1),
|
|
||||||
// Ok(code) => {
|
|
||||||
// let res = do_arch_prctl(code, addr, context).unwrap();
|
|
||||||
// SyscallResult::Return(res as _)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, context: &mut CpuContext) -> Result<u64> {
|
pub fn do_arch_prctl(code: ArchPrctlCode, addr: u64, context: &mut CpuContext) -> Result<u64> {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use crate::syscall::SyscallReturn;
|
||||||
use crate::{process::Process, syscall::SYS_BRK};
|
use crate::{process::Process, syscall::SYS_BRK};
|
||||||
|
|
||||||
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
/// expand the user heap to new heap end, returns the new heap end if expansion succeeds.
|
||||||
pub fn sys_brk(heap_end: u64) -> Result<isize> {
|
pub fn sys_brk(heap_end: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_BRK]", SYS_BRK);
|
debug!("[syscall][id={}][SYS_BRK]", SYS_BRK);
|
||||||
let current = Process::current();
|
let current = Process::current();
|
||||||
let new_heap_end = if heap_end == 0 {
|
let new_heap_end = if heap_end == 0 {
|
||||||
@ -20,5 +21,5 @@ pub fn sys_brk(heap_end: u64) -> Result<isize> {
|
|||||||
.expect("brk should work on process with user space");
|
.expect("brk should work on process with user space");
|
||||||
let new_heap_end = user_heap.brk(new_heap_end, vm_space);
|
let new_heap_end = user_heap.brk(new_heap_end, vm_space);
|
||||||
|
|
||||||
Ok(new_heap_end as _)
|
Ok(SyscallReturn::Return(new_heap_end as _))
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ use kxos_frame::cpu::CpuContext;
|
|||||||
use crate::process::clone::{clone_child, CloneArgs, CloneFlags};
|
use crate::process::clone::{clone_child, CloneArgs, CloneFlags};
|
||||||
use crate::{prelude::*, syscall::SYS_CLONE};
|
use crate::{prelude::*, syscall::SYS_CLONE};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
// The order of arguments for clone differs in different architecture.
|
// The order of arguments for clone differs in different architecture.
|
||||||
// This order we use here is the order for x86_64. See https://man7.org/linux/man-pages/man2/clone.2.html.
|
// This order we use here is the order for x86_64. See https://man7.org/linux/man-pages/man2/clone.2.html.
|
||||||
pub fn sys_clone(
|
pub fn sys_clone(
|
||||||
@ -12,7 +14,7 @@ pub fn sys_clone(
|
|||||||
child_tidptr: Vaddr,
|
child_tidptr: Vaddr,
|
||||||
tls: usize,
|
tls: usize,
|
||||||
parent_context: CpuContext,
|
parent_context: CpuContext,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_CLONE]", SYS_CLONE);
|
debug!("[syscall][id={}][SYS_CLONE]", SYS_CLONE);
|
||||||
debug!("flags = {}", clone_flags);
|
debug!("flags = {}", clone_flags);
|
||||||
let clone_flags = CloneFlags::from(clone_flags);
|
let clone_flags = CloneFlags::from(clone_flags);
|
||||||
@ -28,5 +30,5 @@ pub fn sys_clone(
|
|||||||
debug!("*********schedule child process, pid = {}**********", pid);
|
debug!("*********schedule child process, pid = {}**********", pid);
|
||||||
child_process.send_to_scheduler();
|
child_process.send_to_scheduler();
|
||||||
debug!("*********return to parent process, pid = {}*********", pid);
|
debug!("*********return to parent process, pid = {}*********", pid);
|
||||||
Ok(child_pid as _)
|
Ok(SyscallReturn::Return(child_pid as _))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use kxos_frame::cpu::CpuContext;
|
use kxos_frame::cpu::CpuContext;
|
||||||
|
|
||||||
use super::constants::*;
|
use super::{constants::*, SyscallReturn};
|
||||||
use crate::process::elf::load_elf_to_vm_space;
|
use crate::process::elf::load_elf_to_vm_space;
|
||||||
use crate::{memory::read_bytes_from_user, prelude::*, process::Process, syscall::SYS_EXECVE};
|
use crate::{memory::read_bytes_from_user, prelude::*, process::Process, syscall::SYS_EXECVE};
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ pub fn sys_execve(
|
|||||||
argv_ptr_ptr: Vaddr,
|
argv_ptr_ptr: Vaddr,
|
||||||
envp_ptr_ptr: Vaddr,
|
envp_ptr_ptr: Vaddr,
|
||||||
context: &mut CpuContext,
|
context: &mut CpuContext,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_EXECVE]", SYS_EXECVE);
|
debug!("[syscall][id={}][SYS_EXECVE]", SYS_EXECVE);
|
||||||
let mut filename_buffer = vec![0u8; MAX_FILENAME_LEN];
|
let mut filename_buffer = vec![0u8; MAX_FILENAME_LEN];
|
||||||
read_bytes_from_user(filename_ptr, &mut filename_buffer);
|
read_bytes_from_user(filename_ptr, &mut filename_buffer);
|
||||||
@ -40,11 +40,12 @@ pub fn sys_execve(
|
|||||||
let defalut_content = CpuContext::default();
|
let defalut_content = CpuContext::default();
|
||||||
context.gp_regs = defalut_content.gp_regs;
|
context.gp_regs = defalut_content.gp_regs;
|
||||||
context.fs_base = defalut_content.fs_base;
|
context.fs_base = defalut_content.fs_base;
|
||||||
|
context.fp_regs = defalut_content.fp_regs;
|
||||||
// set new entry point
|
// set new entry point
|
||||||
context.gp_regs.rip = elf_load_info.entry_point();
|
context.gp_regs.rip = elf_load_info.entry_point();
|
||||||
debug!("entry_point: 0x{:x}", elf_load_info.entry_point());
|
debug!("entry_point: 0x{:x}", elf_load_info.entry_point());
|
||||||
// set new user stack top
|
// set new user stack top
|
||||||
context.gp_regs.rsp = elf_load_info.user_stack_top();
|
context.gp_regs.rsp = elf_load_info.user_stack_top();
|
||||||
debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top());
|
debug!("user stack top: 0x{:x}", elf_load_info.user_stack_top());
|
||||||
Ok(0)
|
Ok(SyscallReturn::NoReturn)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::syscall::SYS_EXIT;
|
use crate::syscall::{SyscallReturn, SYS_EXIT};
|
||||||
|
|
||||||
pub fn sys_exit(exit_code: i32) -> Result<isize> {
|
pub fn sys_exit(exit_code: i32) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_EXIT]", SYS_EXIT);
|
debug!("[syscall][id={}][SYS_EXIT]", SYS_EXIT);
|
||||||
current!().exit(exit_code);
|
current!().exit(exit_code);
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::syscall::SYS_EXIT_GROUP;
|
use crate::syscall::{SyscallReturn, SYS_EXIT_GROUP};
|
||||||
|
|
||||||
pub fn sys_exit_group(exit_code: u64) -> Result<isize> {
|
pub fn sys_exit_group(exit_code: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_EXIT_GROUP]", SYS_EXIT_GROUP);
|
debug!("[syscall][id={}][SYS_EXIT_GROUP]", SYS_EXIT_GROUP);
|
||||||
current!().exit(exit_code as _);
|
current!().exit(exit_code as _);
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,12 @@ use kxos_frame::cpu::CpuContext;
|
|||||||
|
|
||||||
use crate::{process::Process, syscall::SYS_FORK};
|
use crate::{process::Process, syscall::SYS_FORK};
|
||||||
|
|
||||||
pub fn sys_fork(parent_context: CpuContext) -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_fork(parent_context: CpuContext) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_FORK]", SYS_FORK);
|
debug!("[syscall][id={}][SYS_FORK]", SYS_FORK);
|
||||||
let child_process = fork(parent_context);
|
let child_process = fork(parent_context);
|
||||||
Ok(child_process.pid() as _)
|
Ok(SyscallReturn::Return(child_process.pid() as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fork a child process
|
/// Fork a child process
|
||||||
|
@ -3,9 +3,9 @@ use kxos_frame::vm::VmIo;
|
|||||||
use crate::fs::stat::Stat;
|
use crate::fs::stat::Stat;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use crate::syscall::SYS_FSTAT;
|
use crate::syscall::{SyscallReturn, SYS_FSTAT};
|
||||||
|
|
||||||
pub fn sys_fstat(fd: u64, stat_buf_ptr: Vaddr) -> Result<isize> {
|
pub fn sys_fstat(fd: u64, stat_buf_ptr: Vaddr) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_FSTAT]", SYS_FSTAT);
|
debug!("[syscall][id={}][SYS_FSTAT]", SYS_FSTAT);
|
||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
debug!("stat_buf_addr = 0x{:x}", stat_buf_ptr);
|
debug!("stat_buf_addr = 0x{:x}", stat_buf_ptr);
|
||||||
@ -19,8 +19,8 @@ pub fn sys_fstat(fd: u64, stat_buf_ptr: Vaddr) -> Result<isize> {
|
|||||||
vm_space
|
vm_space
|
||||||
.write_val(stat_buf_ptr, &stat)
|
.write_val(stat_buf_ptr, &stat)
|
||||||
.expect("Write value failed");
|
.expect("Write value failed");
|
||||||
return Ok(0);
|
return Ok(SyscallReturn::Return(0));
|
||||||
}
|
}
|
||||||
warn!("TODO: fstat only returns fake result now.");
|
warn!("TODO: fstat only returns fake result now.");
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::syscall::SyscallReturn;
|
||||||
use crate::{memory::read_val_from_user, syscall::SYS_FUTEX};
|
use crate::{memory::read_val_from_user, syscall::SYS_FUTEX};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -17,7 +18,7 @@ pub fn sys_futex(
|
|||||||
utime_addr: u64,
|
utime_addr: u64,
|
||||||
futex_new_addr: u64,
|
futex_new_addr: u64,
|
||||||
bitset: u64,
|
bitset: u64,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_FUTEX]", SYS_FUTEX);
|
debug!("[syscall][id={}][SYS_FUTEX]", SYS_FUTEX);
|
||||||
// FIXME: we current ignore futex flags
|
// FIXME: we current ignore futex flags
|
||||||
let (futex_op, futex_flags) = futex_op_and_flags_from_u32(futex_op as _).unwrap();
|
let (futex_op, futex_flags) = futex_op_and_flags_from_u32(futex_op as _).unwrap();
|
||||||
@ -69,7 +70,7 @@ pub fn sys_futex(
|
|||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Ok(res as _)
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// do futex wait
|
/// do futex wait
|
||||||
|
9
src/kxos-std/src/syscall/getegid.rs
Normal file
9
src/kxos-std/src/syscall/getegid.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use crate::{prelude::*, syscall::SYS_GETEGID};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_getegid() -> Result<SyscallReturn> {
|
||||||
|
debug!("[syscall][id={}][SYS_GETEGID]", SYS_GETEGID);
|
||||||
|
warn!("TODO: getegid only return a fake egid now");
|
||||||
|
Ok(SyscallReturn::Return(0))
|
||||||
|
}
|
9
src/kxos-std/src/syscall/geteuid.rs
Normal file
9
src/kxos-std/src/syscall/geteuid.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use crate::{prelude::*, syscall::SYS_GETEUID};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_geteuid() -> Result<SyscallReturn> {
|
||||||
|
debug!("[syscall][id={}][SYS_GETEUID]", SYS_GETEUID);
|
||||||
|
warn!("TODO: geteuid only return a fake euid now");
|
||||||
|
Ok(SyscallReturn::Return(0))
|
||||||
|
}
|
9
src/kxos-std/src/syscall/getgid.rs
Normal file
9
src/kxos-std/src/syscall/getgid.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use crate::{prelude::*, syscall::SYS_GETGID};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_getgid() -> Result<SyscallReturn> {
|
||||||
|
debug!("[syscall][id={}][SYS_GETGID]", SYS_GETGID);
|
||||||
|
warn!("TODO: getgid only return a fake gid now");
|
||||||
|
Ok(SyscallReturn::Return(0))
|
||||||
|
}
|
@ -2,9 +2,11 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::{process::Process, syscall::SYS_GETPID};
|
use crate::{process::Process, syscall::SYS_GETPID};
|
||||||
|
|
||||||
pub fn sys_getpid() -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_getpid() -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_GETPID]", SYS_GETPID);
|
debug!("[syscall][id={}][SYS_GETPID]", SYS_GETPID);
|
||||||
let pid = Process::current().pid();
|
let pid = Process::current().pid();
|
||||||
info!("[sys_getpid]: pid = {}", pid);
|
info!("[sys_getpid]: pid = {}", pid);
|
||||||
Ok(pid as _)
|
Ok(SyscallReturn::Return(pid as _))
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::{process::Process, syscall::SYS_GETTID};
|
use crate::{process::Process, syscall::SYS_GETTID};
|
||||||
|
|
||||||
pub fn sys_gettid() -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_gettid() -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_GETTID]", SYS_GETTID);
|
debug!("[syscall][id={}][SYS_GETTID]", SYS_GETTID);
|
||||||
// For single-thread process, tid is equal to pid
|
// For single-thread process, tid is equal to pid
|
||||||
let tid = Process::current().pid();
|
let tid = Process::current().pid();
|
||||||
Ok(tid as _)
|
Ok(SyscallReturn::Return(tid as _))
|
||||||
}
|
}
|
||||||
|
9
src/kxos-std/src/syscall/getuid.rs
Normal file
9
src/kxos-std/src/syscall/getuid.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use crate::{prelude::*, syscall::SYS_GETUID};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_getuid() -> Result<SyscallReturn> {
|
||||||
|
debug!("[syscall][id={}][SYS_GETUID]", SYS_GETUID);
|
||||||
|
warn!("TODO: getuid only return a fake uid now");
|
||||||
|
Ok(SyscallReturn::Return(0))
|
||||||
|
}
|
@ -7,12 +7,14 @@ use crate::{
|
|||||||
syscall::SYS_KILL,
|
syscall::SYS_KILL,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_kill(process_filter: u64, sig_num: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_KILL]", SYS_KILL);
|
debug!("[syscall][id={}][SYS_KILL]", SYS_KILL);
|
||||||
let process_filter = ProcessFilter::from_id(process_filter as _);
|
let process_filter = ProcessFilter::from_id(process_filter as _);
|
||||||
let sig_num = SigNum::try_from(sig_num as u8).unwrap();
|
let sig_num = SigNum::try_from(sig_num as u8).unwrap();
|
||||||
do_sys_kill(process_filter, sig_num)?;
|
do_sys_kill(process_filter, sig_num)?;
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_kill(process_filter: ProcessFilter, sig_num: SigNum) -> Result<()> {
|
pub fn do_sys_kill(process_filter: ProcessFilter, sig_num: SigNum) -> Result<()> {
|
||||||
|
@ -6,6 +6,8 @@ use kxos_frame::vm::VmPerm;
|
|||||||
|
|
||||||
use crate::{process::Process, syscall::SYS_MMAP};
|
use crate::{process::Process, syscall::SYS_MMAP};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
pub fn sys_mmap(
|
pub fn sys_mmap(
|
||||||
addr: u64,
|
addr: u64,
|
||||||
len: u64,
|
len: u64,
|
||||||
@ -13,7 +15,7 @@ pub fn sys_mmap(
|
|||||||
flags: u64,
|
flags: u64,
|
||||||
fd: u64,
|
fd: u64,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_MMAP]", SYS_MMAP);
|
debug!("[syscall][id={}][SYS_MMAP]", SYS_MMAP);
|
||||||
let perms = VmPerm::try_from(perms).unwrap();
|
let perms = VmPerm::try_from(perms).unwrap();
|
||||||
let flags = MMapFlags::try_from(flags).unwrap();
|
let flags = MMapFlags::try_from(flags).unwrap();
|
||||||
@ -25,7 +27,7 @@ pub fn sys_mmap(
|
|||||||
fd as usize,
|
fd as usize,
|
||||||
offset as usize,
|
offset as usize,
|
||||||
);
|
);
|
||||||
Ok(res as _)
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_mmap(
|
pub fn do_sys_mmap(
|
||||||
|
@ -1,33 +1,38 @@
|
|||||||
//! Read the Cpu context content then dispatch syscall to corrsponding handler
|
//! Read the Cpu context content then dispatch syscall to corrsponding handler
|
||||||
//! The each sub module contains functions that handle real syscall logic.
|
//! The each sub module contains functions that handle real syscall logic.
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::syscall::clone::sys_clone;
|
|
||||||
use crate::syscall::kill::sys_kill;
|
|
||||||
use crate::syscall::rt_sigprocmask::sys_rt_sigprocmask;
|
|
||||||
use alloc::borrow::ToOwned;
|
|
||||||
use kxos_frame::cpu::CpuContext;
|
|
||||||
|
|
||||||
use crate::syscall::access::sys_access;
|
use crate::syscall::access::sys_access;
|
||||||
use crate::syscall::arch_prctl::sys_arch_prctl;
|
use crate::syscall::arch_prctl::sys_arch_prctl;
|
||||||
use crate::syscall::brk::sys_brk;
|
use crate::syscall::brk::sys_brk;
|
||||||
|
use crate::syscall::clone::sys_clone;
|
||||||
use crate::syscall::execve::sys_execve;
|
use crate::syscall::execve::sys_execve;
|
||||||
use crate::syscall::exit::sys_exit;
|
use crate::syscall::exit::sys_exit;
|
||||||
use crate::syscall::exit_group::sys_exit_group;
|
use crate::syscall::exit_group::sys_exit_group;
|
||||||
use crate::syscall::fork::sys_fork;
|
use crate::syscall::fork::sys_fork;
|
||||||
use crate::syscall::fstat::sys_fstat;
|
use crate::syscall::fstat::sys_fstat;
|
||||||
use crate::syscall::futex::sys_futex;
|
use crate::syscall::futex::sys_futex;
|
||||||
|
use crate::syscall::getegid::sys_getegid;
|
||||||
|
use crate::syscall::geteuid::sys_geteuid;
|
||||||
|
use crate::syscall::getgid::sys_getgid;
|
||||||
use crate::syscall::getpid::sys_getpid;
|
use crate::syscall::getpid::sys_getpid;
|
||||||
use crate::syscall::gettid::sys_gettid;
|
use crate::syscall::gettid::sys_gettid;
|
||||||
|
use crate::syscall::getuid::sys_getuid;
|
||||||
|
use crate::syscall::kill::sys_kill;
|
||||||
use crate::syscall::mmap::sys_mmap;
|
use crate::syscall::mmap::sys_mmap;
|
||||||
use crate::syscall::mprotect::sys_mprotect;
|
use crate::syscall::mprotect::sys_mprotect;
|
||||||
use crate::syscall::readlink::sys_readlink;
|
use crate::syscall::readlink::sys_readlink;
|
||||||
|
use crate::syscall::rt_sigaction::sys_rt_sigaction;
|
||||||
|
use crate::syscall::rt_sigprocmask::sys_rt_sigprocmask;
|
||||||
|
use crate::syscall::rt_sigreturn::sys_rt_sigreturn;
|
||||||
|
use crate::syscall::sched_yield::sys_sched_yield;
|
||||||
use crate::syscall::tgkill::sys_tgkill;
|
use crate::syscall::tgkill::sys_tgkill;
|
||||||
use crate::syscall::uname::sys_uname;
|
use crate::syscall::uname::sys_uname;
|
||||||
use crate::syscall::wait4::sys_wait4;
|
use crate::syscall::wait4::sys_wait4;
|
||||||
use crate::syscall::waitid::sys_waitid;
|
use crate::syscall::waitid::sys_waitid;
|
||||||
use crate::syscall::write::sys_write;
|
use crate::syscall::write::sys_write;
|
||||||
use crate::syscall::writev::sys_writev;
|
use crate::syscall::writev::sys_writev;
|
||||||
|
use crate::{define_syscall_nums, syscall_handler};
|
||||||
|
use kxos_frame::cpu::CpuContext;
|
||||||
|
|
||||||
mod access;
|
mod access;
|
||||||
mod arch_prctl;
|
mod arch_prctl;
|
||||||
@ -40,13 +45,19 @@ mod exit_group;
|
|||||||
mod fork;
|
mod fork;
|
||||||
mod fstat;
|
mod fstat;
|
||||||
mod futex;
|
mod futex;
|
||||||
|
mod getegid;
|
||||||
|
mod geteuid;
|
||||||
|
mod getgid;
|
||||||
mod getpid;
|
mod getpid;
|
||||||
mod gettid;
|
mod gettid;
|
||||||
|
mod getuid;
|
||||||
mod kill;
|
mod kill;
|
||||||
mod mmap;
|
mod mmap;
|
||||||
mod mprotect;
|
mod mprotect;
|
||||||
mod readlink;
|
mod readlink;
|
||||||
|
mod rt_sigaction;
|
||||||
mod rt_sigprocmask;
|
mod rt_sigprocmask;
|
||||||
|
mod rt_sigreturn;
|
||||||
mod sched_yield;
|
mod sched_yield;
|
||||||
mod tgkill;
|
mod tgkill;
|
||||||
mod uname;
|
mod uname;
|
||||||
@ -55,41 +66,58 @@ mod waitid;
|
|||||||
mod write;
|
mod write;
|
||||||
mod writev;
|
mod writev;
|
||||||
|
|
||||||
const SYS_WRITE: u64 = 1;
|
define_syscall_nums!(
|
||||||
const SYS_FSTAT: u64 = 5;
|
SYS_WRITE = 1,
|
||||||
const SYS_MMAP: u64 = 9;
|
SYS_FSTAT = 5,
|
||||||
const SYS_MPROTECT: u64 = 10;
|
SYS_MMAP = 9,
|
||||||
const SYS_BRK: u64 = 12;
|
SYS_MPROTECT = 10,
|
||||||
const SYS_RT_SIGACTION: u64 = 13;
|
SYS_BRK = 12,
|
||||||
const SYS_RT_SIGPROCMASK: u64 = 14;
|
SYS_RT_SIGACTION = 13,
|
||||||
const SYS_WRITEV: u64 = 20;
|
SYS_RT_SIGPROCMASK = 14,
|
||||||
const SYS_ACCESS: u64 = 21;
|
SYS_RT_SIGRETRUN = 15,
|
||||||
const SYS_SCHED_YIELD: u64 = 24;
|
SYS_WRITEV = 20,
|
||||||
const SYS_GETPID: u64 = 39;
|
SYS_ACCESS = 21,
|
||||||
const SYS_CLONE: u64 = 56;
|
SYS_SCHED_YIELD = 24,
|
||||||
const SYS_FORK: u64 = 57;
|
SYS_IOCTL = 29,
|
||||||
const SYS_EXECVE: u64 = 59;
|
SYS_GETPID = 39,
|
||||||
const SYS_EXIT: u64 = 60;
|
SYS_CLONE = 56,
|
||||||
const SYS_WAIT4: u64 = 61;
|
SYS_FORK = 57,
|
||||||
const SYS_KILL: u64 = 62;
|
SYS_EXECVE = 59,
|
||||||
const SYS_UNAME: u64 = 63;
|
SYS_EXIT = 60,
|
||||||
const SYS_READLINK: u64 = 89;
|
SYS_WAIT4 = 61,
|
||||||
const SYS_GETUID: u64 = 102;
|
SYS_KILL = 62,
|
||||||
const SYS_GETGID: u64 = 104;
|
SYS_UNAME = 63,
|
||||||
const SYS_GETEUID: u64 = 107;
|
SYS_GETPPID = 64,
|
||||||
const SYS_GETEGID: u64 = 108;
|
SYS_FCNTL = 72,
|
||||||
const SYS_ARCH_PRCTL: u64 = 158;
|
SYS_READLINK = 89,
|
||||||
const SYS_GETTID: u64 = 186;
|
SYS_GETUID = 102,
|
||||||
const SYS_FUTEX: u64 = 202;
|
SYS_GETGID = 104,
|
||||||
const SYS_EXIT_GROUP: u64 = 231;
|
SYS_GETEUID = 107,
|
||||||
const SYS_TGKILL: u64 = 234;
|
SYS_GETEGID = 108,
|
||||||
const SYS_WAITID: u64 = 247;
|
SYS_GETPGRP = 111,
|
||||||
|
SYS_PRCTL = 157,
|
||||||
|
SYS_ARCH_PRCTL = 158,
|
||||||
|
SYS_GETCWD = 183,
|
||||||
|
SYS_GETTID = 186,
|
||||||
|
SYS_FUTEX = 202,
|
||||||
|
SYS_EXIT_GROUP = 231,
|
||||||
|
SYS_TGKILL = 234,
|
||||||
|
SYS_WAITID = 247
|
||||||
|
);
|
||||||
|
|
||||||
pub struct SyscallArgument {
|
pub struct SyscallArgument {
|
||||||
syscall_number: u64,
|
syscall_number: u64,
|
||||||
args: [u64; 6],
|
args: [u64; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Syscall return
|
||||||
|
pub enum SyscallReturn {
|
||||||
|
/// return isize, this value will be used to set rax
|
||||||
|
Return(isize),
|
||||||
|
/// does not need to set rax
|
||||||
|
NoReturn,
|
||||||
|
}
|
||||||
|
|
||||||
impl SyscallArgument {
|
impl SyscallArgument {
|
||||||
fn new_from_context(context: &CpuContext) -> Self {
|
fn new_from_context(context: &CpuContext) -> Self {
|
||||||
let syscall_number = context.gp_regs.rax;
|
let syscall_number = context.gp_regs.rax;
|
||||||
@ -114,92 +142,91 @@ pub fn handle_syscall(context: &mut CpuContext) {
|
|||||||
|
|
||||||
match syscall_return {
|
match syscall_return {
|
||||||
Ok(return_value) => {
|
Ok(return_value) => {
|
||||||
context.gp_regs.rax = return_value as u64;
|
if let SyscallReturn::Return(return_value) = return_value {
|
||||||
|
context.gp_regs.rax = return_value as u64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let errno = err.error() as i32;
|
let errno = err.error() as i32;
|
||||||
context.gp_regs.rax = (-errno) as u64
|
context.gp_regs.rax = (-errno) as u64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if let Syscal(return_value) = syscall_return {
|
|
||||||
// // FIXME: set return value?
|
|
||||||
// context.gp_regs.rax = return_value as u64;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syscall_dispatch(
|
pub fn syscall_dispatch(
|
||||||
syscall_number: u64,
|
syscall_number: u64,
|
||||||
args: [u64; 6],
|
args: [u64; 6],
|
||||||
context: &mut CpuContext,
|
context: &mut CpuContext,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
match syscall_number {
|
match syscall_number {
|
||||||
SYS_WRITE => sys_write(args[0], args[1], args[2]),
|
SYS_WRITE => syscall_handler!(3, sys_write, args),
|
||||||
SYS_FSTAT => sys_fstat(args[0], args[1] as _),
|
SYS_FSTAT => syscall_handler!(2, sys_fstat, args),
|
||||||
SYS_MMAP => sys_mmap(args[0], args[1], args[2], args[3], args[4], args[5]),
|
SYS_MMAP => syscall_handler!(6, sys_mmap, args),
|
||||||
SYS_MPROTECT => sys_mprotect(args[0], args[1], args[2]),
|
SYS_MPROTECT => syscall_handler!(3, sys_mprotect, args),
|
||||||
SYS_BRK => sys_brk(args[0]),
|
SYS_BRK => syscall_handler!(1, sys_brk, args),
|
||||||
SYS_RT_SIGACTION => sys_rt_sigaction(),
|
SYS_RT_SIGACTION => syscall_handler!(4, sys_rt_sigaction, args),
|
||||||
SYS_RT_SIGPROCMASK => {
|
SYS_RT_SIGPROCMASK => syscall_handler!(4, sys_rt_sigprocmask, args),
|
||||||
sys_rt_sigprocmask(args[0] as _, args[1] as _, args[2] as _, args[3] as _)
|
SYS_RT_SIGRETRUN => syscall_handler!(0, sys_rt_sigreturn, context),
|
||||||
}
|
SYS_WRITEV => syscall_handler!(3, sys_writev, args),
|
||||||
SYS_WRITEV => sys_writev(args[0], args[1], args[2]),
|
SYS_ACCESS => syscall_handler!(2, sys_access, args),
|
||||||
SYS_ACCESS => sys_access(args[0] as _, args[1]),
|
SYS_SCHED_YIELD => syscall_handler!(0, sys_sched_yield),
|
||||||
SYS_GETPID => sys_getpid(),
|
SYS_IOCTL => todo!(),
|
||||||
SYS_CLONE => sys_clone(
|
SYS_GETPID => syscall_handler!(0, sys_getpid),
|
||||||
args[0],
|
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
|
||||||
args[1] as _,
|
SYS_FORK => syscall_handler!(0, sys_fork, context.clone()),
|
||||||
args[2] as _,
|
SYS_EXECVE => syscall_handler!(3, sys_execve, args, context),
|
||||||
args[3] as _,
|
SYS_EXIT => syscall_handler!(1, sys_exit, args),
|
||||||
args[4] as _,
|
SYS_WAIT4 => syscall_handler!(3, sys_wait4, args),
|
||||||
context.to_owned(),
|
SYS_KILL => syscall_handler!(2, sys_kill, args),
|
||||||
),
|
SYS_UNAME => syscall_handler!(1, sys_uname, args),
|
||||||
SYS_FORK => sys_fork(context.to_owned()),
|
SYS_GETPPID => todo!(),
|
||||||
SYS_EXECVE => sys_execve(args[0] as _, args[1] as _, args[2] as _, context),
|
SYS_FCNTL => todo!(),
|
||||||
SYS_EXIT => sys_exit(args[0] as _),
|
SYS_READLINK => syscall_handler!(3, sys_readlink, args),
|
||||||
SYS_WAIT4 => sys_wait4(args[0], args[1], args[2]),
|
SYS_GETUID => syscall_handler!(0, sys_getuid),
|
||||||
SYS_KILL => sys_kill(args[0], args[1]),
|
SYS_GETGID => syscall_handler!(0, sys_getgid),
|
||||||
SYS_UNAME => sys_uname(args[0]),
|
SYS_GETEUID => syscall_handler!(0, sys_geteuid),
|
||||||
SYS_READLINK => sys_readlink(args[0], args[1], args[2]),
|
SYS_GETEGID => syscall_handler!(0, sys_getegid),
|
||||||
SYS_GETUID => sys_getuid(),
|
SYS_GETPGRP => todo!(),
|
||||||
SYS_GETGID => sys_getgid(),
|
SYS_PRCTL => todo!(),
|
||||||
SYS_GETEUID => sys_geteuid(),
|
SYS_ARCH_PRCTL => syscall_handler!(2, sys_arch_prctl, args, context),
|
||||||
SYS_GETEGID => sys_getegid(),
|
SYS_GETCWD => todo!(),
|
||||||
SYS_ARCH_PRCTL => sys_arch_prctl(args[0], args[1], context),
|
SYS_GETTID => syscall_handler!(0, sys_gettid),
|
||||||
SYS_GETTID => sys_gettid(),
|
SYS_FUTEX => syscall_handler!(6, sys_futex, args),
|
||||||
SYS_FUTEX => sys_futex(args[0], args[1], args[2], args[3], args[4], args[5]),
|
SYS_EXIT_GROUP => syscall_handler!(1, sys_exit_group, args),
|
||||||
SYS_EXIT_GROUP => sys_exit_group(args[0]),
|
SYS_TGKILL => syscall_handler!(3, sys_tgkill, args),
|
||||||
SYS_TGKILL => sys_tgkill(args[0], args[1], args[2]),
|
SYS_WAITID => syscall_handler!(5, sys_waitid, args),
|
||||||
SYS_WAITID => sys_waitid(args[0], args[1], args[2], args[3], args[4]),
|
|
||||||
_ => panic!("Unsupported syscall number: {}", syscall_number),
|
_ => panic!("Unsupported syscall number: {}", syscall_number),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_rt_sigaction() -> Result<isize> {
|
/// This macro is used to define syscall handler.
|
||||||
debug!("[syscall][id={}][SYS_RT_SIGACTION]", SYS_RT_SIGACTION);
|
/// The first param is ths number of parameters,
|
||||||
warn!("TODO: rt_sigaction only return a fake result");
|
/// The second param is the function name of syscall handler,
|
||||||
Ok(0)
|
/// The third is optional, means the args(if parameter number > 0),
|
||||||
|
/// The third is optional, means if cpu context is required.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! syscall_handler {
|
||||||
|
(0, $fn_name: ident) => { $fn_name() };
|
||||||
|
(0, $fn_name: ident, $context: expr) => { $fn_name($context) };
|
||||||
|
(1, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _) };
|
||||||
|
(1, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $context) };
|
||||||
|
(2, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _)};
|
||||||
|
(2, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $context)};
|
||||||
|
(3, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _)};
|
||||||
|
(3, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $context)};
|
||||||
|
(4, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _)};
|
||||||
|
(4, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _), $context};
|
||||||
|
(5, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _)};
|
||||||
|
(5, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $context)};
|
||||||
|
(6, $fn_name: ident, $args: ident) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _)};
|
||||||
|
(6, $fn_name: ident, $args: ident, $context: expr) => { $fn_name($args[0] as _, $args[1] as _, $args[2] as _, $args[3] as _, $args[4] as _, $args[5] as _, $context)};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_getuid() -> Result<isize> {
|
#[macro_export]
|
||||||
debug!("[syscall][id={}][SYS_GETUID]", SYS_GETUID);
|
macro_rules! define_syscall_nums {
|
||||||
warn!("TODO: getuid only return a fake uid now");
|
( $( $name: ident = $num: expr ),+ ) => {
|
||||||
Ok(0)
|
$(
|
||||||
}
|
const $name: u64 = $num;
|
||||||
|
)*
|
||||||
pub fn sys_getgid() -> Result<isize> {
|
}
|
||||||
debug!("[syscall][id={}][SYS_GETGID]", SYS_GETGID);
|
|
||||||
warn!("TODO: getgid only return a fake gid now");
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sys_geteuid() -> Result<isize> {
|
|
||||||
debug!("[syscall][id={}][SYS_GETEUID]", SYS_GETEUID);
|
|
||||||
warn!("TODO: geteuid only return a fake euid now");
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sys_getegid() -> Result<isize> {
|
|
||||||
debug!("[syscall][id={}][SYS_GETEGID]", SYS_GETEGID);
|
|
||||||
warn!("TODO: getegid only return a fake egid now");
|
|
||||||
Ok(0)
|
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,13 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::syscall::SYS_MPROTECT;
|
use crate::syscall::SYS_MPROTECT;
|
||||||
|
|
||||||
pub fn sys_mprotect(vaddr: u64, len: u64, perms: u64) -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_mprotect(vaddr: u64, len: u64, perms: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_MPROTECT]", SYS_MPROTECT);
|
debug!("[syscall][id={}][SYS_MPROTECT]", SYS_MPROTECT);
|
||||||
let perms = VmPerm::try_from(perms).unwrap();
|
let perms = VmPerm::try_from(perms).unwrap();
|
||||||
do_sys_mprotect(vaddr as Vaddr, len as usize, perms);
|
do_sys_mprotect(vaddr as Vaddr, len as usize, perms);
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_mprotect(addr: Vaddr, len: usize, perms: VmPerm) -> isize {
|
pub fn do_sys_mprotect(addr: Vaddr, len: usize, perms: VmPerm) -> isize {
|
||||||
|
@ -6,16 +6,22 @@ use crate::{
|
|||||||
syscall::SYS_READLINK,
|
syscall::SYS_READLINK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
const MAX_FILENAME_LEN: usize = 128;
|
const MAX_FILENAME_LEN: usize = 128;
|
||||||
|
|
||||||
pub fn sys_readlink(filename_ptr: u64, user_buf_ptr: u64, user_buf_len: u64) -> Result<isize> {
|
pub fn sys_readlink(
|
||||||
|
filename_ptr: u64,
|
||||||
|
user_buf_ptr: u64,
|
||||||
|
user_buf_len: u64,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_READLINK]", SYS_READLINK);
|
debug!("[syscall][id={}][SYS_READLINK]", SYS_READLINK);
|
||||||
let res = do_sys_readlink(
|
let res = do_sys_readlink(
|
||||||
filename_ptr as Vaddr,
|
filename_ptr as Vaddr,
|
||||||
user_buf_ptr as Vaddr,
|
user_buf_ptr as Vaddr,
|
||||||
user_buf_len as usize,
|
user_buf_len as usize,
|
||||||
);
|
);
|
||||||
Ok(res as _)
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// do sys readlink
|
/// do sys readlink
|
||||||
|
36
src/kxos-std/src/syscall/rt_sigaction.rs
Normal file
36
src/kxos-std/src/syscall/rt_sigaction.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use crate::{
|
||||||
|
memory::{read_val_from_user, write_val_to_user},
|
||||||
|
prelude::*,
|
||||||
|
process::signal::{c_types::sigaction_t, sig_action::SigAction, sig_num::SigNum},
|
||||||
|
syscall::SYS_RT_SIGACTION,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_rt_sigaction(
|
||||||
|
sig_num: u8,
|
||||||
|
sig_action_ptr: Vaddr,
|
||||||
|
old_sig_action_ptr: Vaddr,
|
||||||
|
sigset_size: u64,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
debug!("[syscall][id={}][SYS_RT_SIGACTION]", SYS_RT_SIGACTION);
|
||||||
|
let sig_num = SigNum::try_from(sig_num)?;
|
||||||
|
debug!("sig_num = {}", sig_num.sig_name());
|
||||||
|
debug!("sig_action_ptr = 0x{:x}", sig_action_ptr);
|
||||||
|
debug!("old_sig_action_ptr = 0x{:x}", old_sig_action_ptr);
|
||||||
|
debug!("sigset_size = {}", sigset_size);
|
||||||
|
let sig_action_c = read_val_from_user::<sigaction_t>(sig_action_ptr);
|
||||||
|
debug!("sig_action_c = {:?}", sig_action_c);
|
||||||
|
let sig_action = SigAction::try_from(sig_action_c).unwrap();
|
||||||
|
debug!("sig_action = {:x?}", sig_action);
|
||||||
|
|
||||||
|
let current = current!();
|
||||||
|
let mut sig_dispositions = current.sig_dispositions().lock();
|
||||||
|
let old_action = sig_dispositions.get(sig_num);
|
||||||
|
debug!("old_action = {:x?}", old_action);
|
||||||
|
let old_action_c = old_action.to_c();
|
||||||
|
debug!("old_action_c = {:x?}", old_action_c);
|
||||||
|
sig_dispositions.set(sig_num, sig_action);
|
||||||
|
write_val_to_user(old_sig_action_ptr, &old_action_c);
|
||||||
|
Ok(SyscallReturn::Return(0))
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
use kxos_frame::vm::VmIo;
|
use kxos_frame::vm::VmIo;
|
||||||
|
|
||||||
use crate::{prelude::*, syscall::SYS_RT_SIGPROCMASK};
|
use crate::{
|
||||||
|
prelude::*,
|
||||||
|
syscall::{SyscallReturn, SYS_RT_SIGPROCMASK},
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_rt_sigprocmask(
|
pub fn sys_rt_sigprocmask(
|
||||||
how: u32,
|
how: u32,
|
||||||
set_ptr: Vaddr,
|
set_ptr: Vaddr,
|
||||||
oldset_ptr: Vaddr,
|
oldset_ptr: Vaddr,
|
||||||
sigset_size: usize,
|
sigset_size: usize,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_RT_SIGPROCMASK]", SYS_RT_SIGPROCMASK);
|
debug!("[syscall][id={}][SYS_RT_SIGPROCMASK]", SYS_RT_SIGPROCMASK);
|
||||||
let mask_op = MaskOp::try_from(how).unwrap();
|
let mask_op = MaskOp::try_from(how).unwrap();
|
||||||
debug!("mask op = {:?}", mask_op);
|
debug!("mask op = {:?}", mask_op);
|
||||||
@ -18,7 +21,7 @@ pub fn sys_rt_sigprocmask(
|
|||||||
warn!("sigset size is not equal to 8");
|
warn!("sigset size is not equal to 8");
|
||||||
}
|
}
|
||||||
do_rt_sigprocmask(mask_op, set_ptr, oldset_ptr, sigset_size).unwrap();
|
do_rt_sigprocmask(mask_op, set_ptr, oldset_ptr, sigset_size).unwrap();
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_rt_sigprocmask(
|
fn do_rt_sigprocmask(
|
||||||
|
14
src/kxos-std/src/syscall/rt_sigreturn.rs
Normal file
14
src/kxos-std/src/syscall/rt_sigreturn.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
use kxos_frame::cpu::CpuContext;
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_rt_sigreturn(context: &mut CpuContext) -> Result<SyscallReturn> {
|
||||||
|
let current = current!();
|
||||||
|
let sig_context = current.sig_context().lock().as_ref().unwrap().clone();
|
||||||
|
*context = *sig_context.cpu_context();
|
||||||
|
// unblock sig mask
|
||||||
|
let sig_mask = sig_context.sig_mask();
|
||||||
|
current.sig_mask().lock().unblock(sig_mask.as_u64());
|
||||||
|
Ok(SyscallReturn::NoReturn)
|
||||||
|
}
|
@ -2,8 +2,10 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::{process::Process, syscall::SYS_SCHED_YIELD};
|
use crate::{process::Process, syscall::SYS_SCHED_YIELD};
|
||||||
|
|
||||||
pub fn sys_sched_yield() -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_sched_yield() -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_SCHED_YIELD]", SYS_SCHED_YIELD);
|
debug!("[syscall][id={}][SYS_SCHED_YIELD]", SYS_SCHED_YIELD);
|
||||||
Process::yield_now();
|
Process::yield_now();
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::syscall::SYS_TGKILL;
|
use crate::syscall::SYS_TGKILL;
|
||||||
|
|
||||||
pub fn sys_tgkill(tgid: u64, pid: u64, signal: u64) -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_tgkill(tgid: u64, pid: u64, signal: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_TGKILL]", SYS_TGKILL);
|
debug!("[syscall][id={}][SYS_TGKILL]", SYS_TGKILL);
|
||||||
debug!("tgid = {}", tgid);
|
debug!("tgid = {}", tgid);
|
||||||
debug!("pid = {}", pid);
|
debug!("pid = {}", pid);
|
||||||
warn!("TODO: tgkill do nothing now");
|
warn!("TODO: tgkill do nothing now");
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::{memory::write_val_to_user, syscall::SYS_UNAME};
|
use crate::{memory::write_val_to_user, syscall::SYS_UNAME};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
// We don't use the real name and version of our os here. Instead, we pick up fake values witch is the same as the ones of linux.
|
// We don't use the real name and version of our os here. Instead, we pick up fake values witch is the same as the ones of linux.
|
||||||
// The values are used to fool glibc since glibc will check the version and os name.
|
// The values are used to fool glibc since glibc will check the version and os name.
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -56,10 +58,10 @@ fn copy_cstring_to_u8_slice(src: &CStr, dst: &mut [u8]) {
|
|||||||
dst[..len].copy_from_slice(&src[..len]);
|
dst[..len].copy_from_slice(&src[..len]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_uname(old_uname_addr: u64) -> Result<isize> {
|
pub fn sys_uname(old_uname_addr: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_UNAME]", SYS_UNAME);
|
debug!("[syscall][id={}][SYS_UNAME]", SYS_UNAME);
|
||||||
do_sys_uname(old_uname_addr as Vaddr);
|
do_sys_uname(old_uname_addr as Vaddr);
|
||||||
Ok(0)
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_uname(old_uname_addr: Vaddr) -> usize {
|
pub fn do_sys_uname(old_uname_addr: Vaddr) -> usize {
|
||||||
|
@ -7,10 +7,12 @@ use crate::{
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::process::wait::WaitOptions;
|
use crate::process::wait::WaitOptions;
|
||||||
|
|
||||||
pub fn sys_wait4(wait_pid: u64, exit_status_ptr: u64, wait_options: u64) -> Result<isize> {
|
use super::SyscallReturn;
|
||||||
|
|
||||||
|
pub fn sys_wait4(wait_pid: u64, exit_status_ptr: u64, wait_options: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_WAIT4]", SYS_WAIT4);
|
debug!("[syscall][id={}][SYS_WAIT4]", SYS_WAIT4);
|
||||||
let wait_options = WaitOptions::from_bits(wait_options as u32).expect("Unknown wait options");
|
let wait_options = WaitOptions::from_bits(wait_options as u32).expect("Unknown wait options");
|
||||||
debug!("pid = {}", wait_pid as isize);
|
debug!("pid = {}", wait_pid as i32);
|
||||||
debug!("exit_status_ptr = {}", exit_status_ptr);
|
debug!("exit_status_ptr = {}", exit_status_ptr);
|
||||||
debug!("wait_options: {:?}", wait_options);
|
debug!("wait_options: {:?}", wait_options);
|
||||||
let process_filter = ProcessFilter::from_id(wait_pid as _);
|
let process_filter = ProcessFilter::from_id(wait_pid as _);
|
||||||
@ -18,6 +20,5 @@ pub fn sys_wait4(wait_pid: u64, exit_status_ptr: u64, wait_options: u64) -> Resu
|
|||||||
if return_pid != 0 && exit_status_ptr != 0 {
|
if return_pid != 0 && exit_status_ptr != 0 {
|
||||||
write_val_to_user(exit_status_ptr as _, &exit_code);
|
write_val_to_user(exit_status_ptr as _, &exit_code);
|
||||||
}
|
}
|
||||||
|
Ok(SyscallReturn::Return(return_pid as _))
|
||||||
Ok(return_pid as _)
|
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,18 @@ use crate::process::{process_filter::ProcessFilter, wait::wait_child_exit};
|
|||||||
|
|
||||||
use crate::process::wait::WaitOptions;
|
use crate::process::wait::WaitOptions;
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
pub fn sys_waitid(
|
pub fn sys_waitid(
|
||||||
which: u64,
|
which: u64,
|
||||||
upid: u64,
|
upid: u64,
|
||||||
infoq_addr: u64,
|
infoq_addr: u64,
|
||||||
options: u64,
|
options: u64,
|
||||||
rusage_addr: u64,
|
rusage_addr: u64,
|
||||||
) -> Result<isize> {
|
) -> Result<SyscallReturn> {
|
||||||
// FIXME: what does infoq and rusage use for?
|
// FIXME: what does infoq and rusage use for?
|
||||||
let process_filter = ProcessFilter::from_which_and_id(which, upid);
|
let process_filter = ProcessFilter::from_which_and_id(which, upid);
|
||||||
let wait_options = WaitOptions::from_bits(options as u32).expect("Unknown wait options");
|
let wait_options = WaitOptions::from_bits(options as u32).expect("Unknown wait options");
|
||||||
let (exit_code, pid) = wait_child_exit(process_filter, wait_options);
|
let (exit_code, pid) = wait_child_exit(process_filter, wait_options);
|
||||||
Ok(pid as _)
|
Ok(SyscallReturn::Return(pid as _))
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::{memory::read_bytes_from_user, syscall::SYS_WRITE};
|
use crate::{memory::read_bytes_from_user, syscall::SYS_WRITE};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
const STDOUT: u64 = 1;
|
const STDOUT: u64 = 1;
|
||||||
const STDERR: u64 = 2;
|
const STDERR: u64 = 2;
|
||||||
|
|
||||||
pub fn sys_write(fd: u64, user_buf_ptr: u64, user_buf_len: u64) -> Result<isize> {
|
pub fn sys_write(fd: u64, user_buf_ptr: u64, user_buf_len: u64) -> Result<SyscallReturn> {
|
||||||
// only suppprt STDOUT now.
|
// only suppprt STDOUT now.
|
||||||
debug!("[syscall][id={}][SYS_WRITE]", SYS_WRITE);
|
debug!("[syscall][id={}][SYS_WRITE]", SYS_WRITE);
|
||||||
|
|
||||||
@ -18,8 +20,7 @@ pub fn sys_write(fd: u64, user_buf_ptr: u64, user_buf_len: u64) -> Result<isize>
|
|||||||
} else {
|
} else {
|
||||||
info!("Error message from user mode: {:?}", content);
|
info!("Error message from user mode: {:?}", content);
|
||||||
}
|
}
|
||||||
|
Ok(SyscallReturn::Return(user_buf_len as _))
|
||||||
Ok(user_buf_len as _)
|
|
||||||
} else {
|
} else {
|
||||||
panic!("Unsupported fd number {}", fd);
|
panic!("Unsupported fd number {}", fd);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ use crate::{
|
|||||||
syscall::SYS_WRITEV,
|
syscall::SYS_WRITEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::SyscallReturn;
|
||||||
|
|
||||||
const IOVEC_MAX: usize = 256;
|
const IOVEC_MAX: usize = 256;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -14,10 +16,10 @@ pub struct IoVec {
|
|||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_writev(fd: u64, io_vec_ptr: u64, io_vec_count: u64) -> Result<isize> {
|
pub fn sys_writev(fd: u64, io_vec_ptr: u64, io_vec_count: u64) -> Result<SyscallReturn> {
|
||||||
debug!("[syscall][id={}][SYS_WRITEV]", SYS_WRITEV);
|
debug!("[syscall][id={}][SYS_WRITEV]", SYS_WRITEV);
|
||||||
let res = do_sys_writev(fd, io_vec_ptr as Vaddr, io_vec_count as usize);
|
let res = do_sys_writev(fd, io_vec_ptr as Vaddr, io_vec_count as usize);
|
||||||
Ok(res as _)
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_sys_writev(fd: u64, io_vec_ptr: Vaddr, io_vec_count: usize) -> usize {
|
pub fn do_sys_writev(fd: u64, io_vec_ptr: Vaddr, io_vec_count: usize) -> usize {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f98928f25e8223fd76d5d19db68e83913b48ea8b3cf6ae8d3120971e7271c93b
|
oid sha256:afc9465a8ae782da4e049d2b660a27b678394e683814c29a9601bc135126a0e5
|
||||||
size 871952
|
size 871952
|
||||||
|
@ -5,9 +5,10 @@ int main() {
|
|||||||
char* argv[] = { NULL };
|
char* argv[] = { NULL };
|
||||||
char* envp[] = { NULL };
|
char* envp[] = { NULL };
|
||||||
printf("Execve a new file ./hello:\n");
|
printf("Execve a new file ./hello:\n");
|
||||||
// flust the stdout content to ensure the content print to console
|
// flush the stdout content to ensure the content print to console
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
execve("./hello", argv, envp);
|
execve("./hello", argv, envp);
|
||||||
printf("Should not print\n");
|
printf("Should not print\n");
|
||||||
|
fflush(stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4f3b6fe8b52f200c469170223ea0cb2d06dbab6a5eb757e007eb0a751c5e1e81
|
oid sha256:ca7a77a72da160f11670a04a16b623944295b9059399da45f57668f121b00d11
|
||||||
size 877152
|
size 877152
|
||||||
|
@ -5,9 +5,9 @@ int main() {
|
|||||||
printf("before fork\n");
|
printf("before fork\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if(fork() == 0) {
|
if(fork() == 0) {
|
||||||
printf("after fork: Hello from parent\n");
|
|
||||||
} else {
|
|
||||||
printf("after fork: Hello from child\n");
|
printf("after fork: Hello from child\n");
|
||||||
|
} else {
|
||||||
|
printf("after fork: Hello from parent\n");
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:08b21d340c8d144c1bfb86097e46ceda6d690041269cf56fee5bd8918e8253fa
|
oid sha256:1938c6e8abd70c400780dd8aa089d768a8662d54bac2a658936790d5537e868c
|
||||||
size 877544
|
size 877544
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
int sigchld = 0;
|
int sigchld = 0;
|
||||||
|
|
||||||
void proc_exit() {
|
void proc_exit() {
|
||||||
sigchld = 999;
|
sigchld = sigchld + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user