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/execve filter=lfs diff=lfs merge=lfs -text
|
||||||
src/kxos-user/execve/hello 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/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,
|
bits: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SigMask {
|
impl From<u64> for SigMask {
|
||||||
pub const fn from_u64(bits: u64) -> Self {
|
fn from(bits: u64) -> Self {
|
||||||
SigMask { bits }
|
SigMask { bits }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn new_empty() -> Self {
|
impl SigMask {
|
||||||
SigMask::from_u64(0)
|
pub fn new_empty() -> Self {
|
||||||
|
SigMask::from(0u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn new_full() -> Self {
|
pub fn new_full() -> Self {
|
||||||
SigMask::from_u64(!0)
|
SigMask::from(!0u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn as_u64(&self) -> u64 {
|
pub const fn as_u64(&self) -> u64 {
|
||||||
@ -30,6 +32,18 @@ impl SigMask {
|
|||||||
self.bits == !0
|
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 {
|
pub fn count(&self) -> usize {
|
||||||
self.bits.count_ones() as usize
|
self.bits.count_ones() as usize
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
use super::constants::*;
|
use super::constants::*;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct SigNum {
|
pub struct SigNum {
|
||||||
sig_num: u8,
|
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 {
|
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 {
|
pub const fn from_u8(sig_num: u8) -> Self {
|
||||||
if sig_num > MAX_RT_SIG_NUM || sig_num < MIN_STD_SIG_NUM {
|
if sig_num > MAX_RT_SIG_NUM || sig_num < MIN_STD_SIG_NUM {
|
||||||
unreachable!()
|
panic!("invalid signal number")
|
||||||
}
|
}
|
||||||
SigNum { sig_num }
|
SigNum { sig_num }
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ impl SigQueues {
|
|||||||
// process, they are delivered starting with the lowest-numbered
|
// process, they are delivered starting with the lowest-numbered
|
||||||
// signal. (I.e., low-numbered signals have highest priority.)
|
// signal. (I.e., low-numbered signals have highest priority.)
|
||||||
for signum in MIN_RT_SIG_NUM..=MAX_RT_SIG_NUM {
|
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) {
|
if blocked.contains(signum) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::syscall::{SyscallResult, SYS_FSTAT};
|
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!("[syscall][id={}][SYS_FSTAT]", SYS_FSTAT);
|
||||||
debug!("fd = {}", fd);
|
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 current = current!();
|
||||||
let vm_space = current
|
let vm_space = current
|
||||||
@ -17,7 +17,7 @@ pub fn sys_fstat(fd: u64, stat_buf_addr: Vaddr) -> SyscallResult {
|
|||||||
if fd == 1 {
|
if fd == 1 {
|
||||||
let stat = Stat::stdout_stat();
|
let stat = Stat::stdout_stat();
|
||||||
vm_space
|
vm_space
|
||||||
.write_val(stat_buf_addr, &stat)
|
.write_val(stat_buf_ptr, &stat)
|
||||||
.expect("Write value failed");
|
.expect("Write value failed");
|
||||||
return SyscallResult::Return(0);
|
return SyscallResult::Return(0);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use super::SyscallResult;
|
|||||||
pub fn sys_kill(process_filter: u64, sig_num: u64) -> SyscallResult {
|
pub fn sys_kill(process_filter: u64, sig_num: u64) -> SyscallResult {
|
||||||
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::from_u8(sig_num as _);
|
let sig_num = SigNum::try_from(sig_num as u8).unwrap();
|
||||||
let _ = do_sys_kill(process_filter, sig_num);
|
let _ = do_sys_kill(process_filter, sig_num);
|
||||||
SyscallResult::Return(0)
|
SyscallResult::Return(0)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::syscall::clone::sys_clone;
|
use crate::syscall::clone::sys_clone;
|
||||||
use crate::syscall::kill::sys_kill;
|
use crate::syscall::kill::sys_kill;
|
||||||
|
use crate::syscall::rt_sigprocmask::sys_rt_sigprocmask;
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use kxos_frame::cpu::CpuContext;
|
use kxos_frame::cpu::CpuContext;
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ mod wait4;
|
|||||||
mod waitid;
|
mod waitid;
|
||||||
mod write;
|
mod write;
|
||||||
mod writev;
|
mod writev;
|
||||||
|
mod rt_sigprocmask;
|
||||||
|
|
||||||
const SYS_WRITE: u64 = 1;
|
const SYS_WRITE: u64 = 1;
|
||||||
const SYS_FSTAT: u64 = 5;
|
const SYS_FSTAT: u64 = 5;
|
||||||
@ -133,7 +135,7 @@ pub fn syscall_dispatch(
|
|||||||
SYS_MPROTECT => sys_mprotect(args[0], args[1], args[2]),
|
SYS_MPROTECT => sys_mprotect(args[0], args[1], args[2]),
|
||||||
SYS_BRK => sys_brk(args[0]),
|
SYS_BRK => sys_brk(args[0]),
|
||||||
SYS_RT_SIGACTION => sys_rt_sigaction(),
|
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_WRITEV => sys_writev(args[0], args[1], args[2]),
|
||||||
SYS_ACCESS => sys_access(args[0] as _, args[1]),
|
SYS_ACCESS => sys_access(args[0] as _, args[1]),
|
||||||
SYS_GETPID => sys_getpid(),
|
SYS_GETPID => sys_getpid(),
|
||||||
@ -172,12 +174,6 @@ pub fn sys_rt_sigaction() -> SyscallResult {
|
|||||||
SyscallResult::Return(0)
|
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 {
|
pub fn sys_getuid() -> SyscallResult {
|
||||||
debug!("[syscall][id={}][SYS_GETUID]", SYS_GETUID);
|
debug!("[syscall][id={}][SYS_GETUID]", SYS_GETUID);
|
||||||
warn!("TODO: getuid only return a fake uid now");
|
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,
|
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);
|
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 _)
|
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!("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);
|
debug!("io_vec_counter = 0x{:x}", io_vec_count);
|
||||||
let mut write_len = 0;
|
let mut write_len = 0;
|
||||||
for i in 0..io_vec_count {
|
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 base = io_vec.base;
|
||||||
let len = io_vec.len;
|
let len = io_vec.len;
|
||||||
debug!("base = 0x{:x}", base);
|
debug!("base = 0x{:x}", base);
|
||||||
|
@ -24,7 +24,7 @@ impl UserApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_apps() -> Vec<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
|
// Most simple hello world, written in assembly
|
||||||
let app1 = UserApp::new("hello_world", read_hello_world_content());
|
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());
|
let app5 = UserApp::new("/fork", read_fork_c_content());
|
||||||
res.push(app5);
|
res.push(app5);
|
||||||
|
|
||||||
|
// Set sig procmask
|
||||||
|
let app6 = UserApp::new("/sig_procmask", read_sig_procmask());
|
||||||
|
res.push(app6);
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,3 +78,7 @@ pub fn read_execve_hello_content() -> &'static [u8] {
|
|||||||
fn read_fork_c_content() -> &'static [u8] {
|
fn read_fork_c_content() -> &'static [u8] {
|
||||||
include_bytes!("../../kxos-user/fork_c/fork")
|
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