mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 17:33:23 +00:00
add syscall rt_procmask
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -4,3 +4,5 @@ src/kxos-user/hello_c/hello filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/execve/execve filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/execve/hello filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/fork_c/fork filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/signal_c/divide_zero filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/signal_c/sig_procmask filter=lfs diff=lfs merge=lfs -text
|
@ -5,17 +5,19 @@ pub struct SigMask {
|
||||
bits: u64,
|
||||
}
|
||||
|
||||
impl SigMask {
|
||||
pub const fn from_u64(bits: u64) -> Self {
|
||||
impl From<u64> for SigMask {
|
||||
fn from(bits: u64) -> Self {
|
||||
SigMask { bits }
|
||||
}
|
||||
|
||||
pub const fn new_empty() -> Self {
|
||||
SigMask::from_u64(0)
|
||||
}
|
||||
|
||||
pub const fn new_full() -> Self {
|
||||
SigMask::from_u64(!0)
|
||||
impl SigMask {
|
||||
pub fn new_empty() -> Self {
|
||||
SigMask::from(0u64)
|
||||
}
|
||||
|
||||
pub fn new_full() -> Self {
|
||||
SigMask::from(!0u64)
|
||||
}
|
||||
|
||||
pub const fn as_u64(&self) -> u64 {
|
||||
@ -30,6 +32,18 @@ impl SigMask {
|
||||
self.bits == !0
|
||||
}
|
||||
|
||||
pub fn block(&mut self, block_sets: u64) {
|
||||
self.bits |= block_sets;
|
||||
}
|
||||
|
||||
pub fn unblock(&mut self, unblock_sets: u64) {
|
||||
self.bits &= !unblock_sets;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, new_set:u64) {
|
||||
self.bits = new_set;
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize {
|
||||
self.bits.count_ones() as usize
|
||||
}
|
||||
|
@ -1,15 +1,27 @@
|
||||
use super::constants::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct SigNum {
|
||||
sig_num: u8,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for SigNum {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(sig_num: u8) -> Result<Self> {
|
||||
if sig_num > MAX_RT_SIG_NUM || sig_num < MIN_STD_SIG_NUM {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid signal number");
|
||||
}
|
||||
Ok(SigNum { sig_num })
|
||||
}
|
||||
}
|
||||
|
||||
impl SigNum {
|
||||
// Safety: This function should only be used when signum is ensured to be valid.
|
||||
/// Caller must ensure the sig_num is valid. otherweise, use try_from will check sig_num and does not panic.
|
||||
pub const fn from_u8(sig_num: u8) -> Self {
|
||||
if sig_num > MAX_RT_SIG_NUM || sig_num < MIN_STD_SIG_NUM {
|
||||
unreachable!()
|
||||
panic!("invalid signal number")
|
||||
}
|
||||
SigNum { sig_num }
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ impl SigQueues {
|
||||
// process, they are delivered starting with the lowest-numbered
|
||||
// signal. (I.e., low-numbered signals have highest priority.)
|
||||
for signum in MIN_RT_SIG_NUM..=MAX_RT_SIG_NUM {
|
||||
let signum = SigNum::from_u8(signum);
|
||||
let signum = SigNum::try_from(signum).unwrap();
|
||||
if blocked.contains(signum) {
|
||||
continue;
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ use crate::prelude::*;
|
||||
|
||||
use crate::syscall::{SyscallResult, SYS_FSTAT};
|
||||
|
||||
pub fn sys_fstat(fd: u64, stat_buf_addr: Vaddr) -> SyscallResult {
|
||||
pub fn sys_fstat(fd: u64, stat_buf_ptr: Vaddr) -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_FSTAT]", SYS_FSTAT);
|
||||
debug!("fd = {}", fd);
|
||||
debug!("stat_buf_addr = 0x{:x}", stat_buf_addr);
|
||||
debug!("stat_buf_addr = 0x{:x}", stat_buf_ptr);
|
||||
|
||||
let current = current!();
|
||||
let vm_space = current
|
||||
@ -17,7 +17,7 @@ pub fn sys_fstat(fd: u64, stat_buf_addr: Vaddr) -> SyscallResult {
|
||||
if fd == 1 {
|
||||
let stat = Stat::stdout_stat();
|
||||
vm_space
|
||||
.write_val(stat_buf_addr, &stat)
|
||||
.write_val(stat_buf_ptr, &stat)
|
||||
.expect("Write value failed");
|
||||
return SyscallResult::Return(0);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use super::SyscallResult;
|
||||
pub fn sys_kill(process_filter: u64, sig_num: u64) -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_KILL]", SYS_KILL);
|
||||
let process_filter = ProcessFilter::from_id(process_filter as _);
|
||||
let sig_num = SigNum::from_u8(sig_num as _);
|
||||
let sig_num = SigNum::try_from(sig_num as u8).unwrap();
|
||||
let _ = do_sys_kill(process_filter, sig_num);
|
||||
SyscallResult::Return(0)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
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;
|
||||
|
||||
@ -52,6 +53,7 @@ mod wait4;
|
||||
mod waitid;
|
||||
mod write;
|
||||
mod writev;
|
||||
mod rt_sigprocmask;
|
||||
|
||||
const SYS_WRITE: u64 = 1;
|
||||
const SYS_FSTAT: u64 = 5;
|
||||
@ -133,7 +135,7 @@ pub fn syscall_dispatch(
|
||||
SYS_MPROTECT => sys_mprotect(args[0], args[1], args[2]),
|
||||
SYS_BRK => sys_brk(args[0]),
|
||||
SYS_RT_SIGACTION => sys_rt_sigaction(),
|
||||
SYS_RT_SIGPROCMASK => sys_rt_sigprocmask(),
|
||||
SYS_RT_SIGPROCMASK => sys_rt_sigprocmask(args[0] as _, args[1] as _, args[2] as _, args[3] as _),
|
||||
SYS_WRITEV => sys_writev(args[0], args[1], args[2]),
|
||||
SYS_ACCESS => sys_access(args[0] as _, args[1]),
|
||||
SYS_GETPID => sys_getpid(),
|
||||
@ -172,12 +174,6 @@ pub fn sys_rt_sigaction() -> SyscallResult {
|
||||
SyscallResult::Return(0)
|
||||
}
|
||||
|
||||
pub fn sys_rt_sigprocmask() -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_RT_SIGPROCMASK]", SYS_RT_SIGPROCMASK);
|
||||
warn!("TODO: rt_sigprocmask only return a fake result");
|
||||
SyscallResult::Return(0)
|
||||
}
|
||||
|
||||
pub fn sys_getuid() -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_GETUID]", SYS_GETUID);
|
||||
warn!("TODO: getuid only return a fake uid now");
|
||||
|
63
src/kxos-std/src/syscall/rt_sigprocmask.rs
Normal file
63
src/kxos-std/src/syscall/rt_sigprocmask.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use kxos_frame::vm::VmIo;
|
||||
|
||||
use crate::{prelude::*, syscall::SYS_RT_SIGPROCMASK};
|
||||
|
||||
use super::SyscallResult;
|
||||
pub fn sys_rt_sigprocmask(how: u32, set_ptr: Vaddr, oldset_ptr: Vaddr, sigset_size: usize) -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_RT_SIGPROCMASK]", SYS_RT_SIGPROCMASK);
|
||||
let mask_op = MaskOp::try_from(how).unwrap();
|
||||
debug!("mask op = {:?}", mask_op);
|
||||
debug!("set_ptr = 0x{:x}", set_ptr);
|
||||
debug!("oldset_ptr = 0x{:x}", oldset_ptr);
|
||||
debug!("sigset_size = {}", sigset_size);
|
||||
if sigset_size != 8 {
|
||||
warn!("sigset size is not equal to 8");
|
||||
}
|
||||
do_rt_sigprocmask(mask_op, set_ptr, oldset_ptr, sigset_size).unwrap();
|
||||
SyscallResult::Return(0)
|
||||
}
|
||||
|
||||
fn do_rt_sigprocmask(mask_op: MaskOp, set_ptr: Vaddr, oldset_ptr: Vaddr, sigset_size: usize) -> Result<()>{
|
||||
let current = current!();
|
||||
let vm_space = current.vm_space().unwrap();
|
||||
let mut sig_mask = current.sig_mask().lock();
|
||||
let old_sig_mask_value = sig_mask.as_u64();
|
||||
debug!("old sig mask value: 0x{:x}", old_sig_mask_value);
|
||||
if oldset_ptr != 0 {
|
||||
vm_space.write_val(oldset_ptr, &old_sig_mask_value)?;
|
||||
}
|
||||
if set_ptr != 0 {
|
||||
let new_set = vm_space.read_val::<u64>(set_ptr)?;
|
||||
debug!("new set = 0x{:x}", new_set);
|
||||
match mask_op {
|
||||
MaskOp::Block => sig_mask.block(new_set ),
|
||||
MaskOp::Unblock => sig_mask.unblock(new_set),
|
||||
MaskOp::SetMask => sig_mask.set(new_set),
|
||||
}
|
||||
}
|
||||
debug!("new set = {:x?}", &sig_mask);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum MaskOp {
|
||||
Block = 0,
|
||||
Unblock = 1,
|
||||
SetMask = 2,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for MaskOp {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self> {
|
||||
let op = match value {
|
||||
0 => MaskOp::Block,
|
||||
1 => MaskOp::Unblock,
|
||||
2 => MaskOp::SetMask,
|
||||
_ => return_errno_with_message!(Errno::EINVAL, "invalid mask op"),
|
||||
};
|
||||
Ok(op)
|
||||
}
|
||||
}
|
@ -16,19 +16,19 @@ pub struct IoVec {
|
||||
len: usize,
|
||||
}
|
||||
|
||||
pub fn sys_writev(fd: u64, io_vec_addr: u64, io_vec_count: u64) -> SyscallResult {
|
||||
pub fn sys_writev(fd: u64, io_vec_ptr: u64, io_vec_count: u64) -> SyscallResult {
|
||||
debug!("[syscall][id={}][SYS_WRITEV]", SYS_WRITEV);
|
||||
let res = do_sys_writev(fd, io_vec_addr as Vaddr, io_vec_count as usize);
|
||||
let res = do_sys_writev(fd, io_vec_ptr as Vaddr, io_vec_count as usize);
|
||||
SyscallResult::Return(res as _)
|
||||
}
|
||||
|
||||
pub fn do_sys_writev(fd: u64, io_vec_addr: Vaddr, io_vec_count: usize) -> usize {
|
||||
pub fn do_sys_writev(fd: u64, io_vec_ptr: Vaddr, io_vec_count: usize) -> usize {
|
||||
debug!("fd = {}", fd);
|
||||
debug!("io_vec_addr = 0x{:x}", io_vec_addr);
|
||||
debug!("io_vec_ptr = 0x{:x}", io_vec_ptr);
|
||||
debug!("io_vec_counter = 0x{:x}", io_vec_count);
|
||||
let mut write_len = 0;
|
||||
for i in 0..io_vec_count {
|
||||
let io_vec = read_val_from_user::<IoVec>(io_vec_addr + i * 8);
|
||||
let io_vec = read_val_from_user::<IoVec>(io_vec_ptr + i * 8);
|
||||
let base = io_vec.base;
|
||||
let len = io_vec.len;
|
||||
debug!("base = 0x{:x}", base);
|
||||
|
@ -24,7 +24,7 @@ impl UserApp {
|
||||
}
|
||||
|
||||
pub fn get_all_apps() -> Vec<UserApp> {
|
||||
let mut res = Vec::new();
|
||||
let mut res = Vec::with_capacity(16);
|
||||
|
||||
// Most simple hello world, written in assembly
|
||||
let app1 = UserApp::new("hello_world", read_hello_world_content());
|
||||
@ -48,6 +48,10 @@ pub fn get_all_apps() -> Vec<UserApp> {
|
||||
let app5 = UserApp::new("/fork", read_fork_c_content());
|
||||
res.push(app5);
|
||||
|
||||
// Set sig procmask
|
||||
let app6 = UserApp::new("/sig_procmask", read_sig_procmask());
|
||||
res.push(app6);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
@ -74,3 +78,7 @@ pub fn read_execve_hello_content() -> &'static [u8] {
|
||||
fn read_fork_c_content() -> &'static [u8] {
|
||||
include_bytes!("../../kxos-user/fork_c/fork")
|
||||
}
|
||||
|
||||
fn read_sig_procmask() -> &'static [u8] {
|
||||
include_bytes!("../../kxos-user/signal_c/sig_procmask")
|
||||
}
|
||||
|
9
src/kxos-user/signal_c/Makefile
Normal file
9
src/kxos-user/signal_c/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
.PHONY: build clean run
|
||||
build: divide_zero.c sig_procmask.c
|
||||
@gcc -static divide_zero.c -o divide_zero
|
||||
@gcc -static sig_procmask.c -o sig_procmask
|
||||
clean:
|
||||
@rm divide_zero sig_procmask
|
||||
run: build
|
||||
@./sig_procmask
|
||||
@./divide_zero
|
3
src/kxos-user/signal_c/divide_zero
Executable file
3
src/kxos-user/signal_c/divide_zero
Executable file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:07eb07c6387a9afd68a5b8a8bba9b48e1362b9c3b8f18ce30e744640a4dfa546
|
||||
size 871776
|
7
src/kxos-user/signal_c/divide_zero.c
Normal file
7
src/kxos-user/signal_c/divide_zero.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include<stdio.h>
|
||||
|
||||
int main() {
|
||||
int a = 2 - 2;
|
||||
int b = 1 / a;
|
||||
return 0;
|
||||
}
|
0
src/kxos-user/signal_c/sig_action.c
Normal file
0
src/kxos-user/signal_c/sig_action.c
Normal file
3
src/kxos-user/signal_c/sig_procmask
Executable file
3
src/kxos-user/signal_c/sig_procmask
Executable file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6faf986f058a2480297fb323a536319f9c7dde76efe4ed0472f09a4ad2960c9b
|
||||
size 871848
|
19
src/kxos-user/signal_c/sig_procmask.c
Normal file
19
src/kxos-user/signal_c/sig_procmask.c
Normal file
@ -0,0 +1,19 @@
|
||||
/// This code is from CSAPP
|
||||
/// We use this codes to test sigprocmask
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
int main() {
|
||||
sigset_t mask, prev_mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
|
||||
/* Block SIGINT and save previous blocked set */
|
||||
sigprocmask(SIG_BLOCK, &mask, &prev_mask);
|
||||
|
||||
// Code region that will not be interrupted by SIGINT and SIGCHILD
|
||||
/* Restore previous blocked set, unblocking SIGINT */
|
||||
sigprocmask(SIG_SETMASK, &prev_mask, NULL);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user