mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 09:23:25 +00:00
Refactor project structure
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
bd878dd1c9
commit
e3c227ae06
117
kernel/aster-nix/src/syscall/sigaltstack.rs
Normal file
117
kernel/aster-nix/src/syscall/sigaltstack.rs
Normal file
@ -0,0 +1,117 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use super::{SyscallReturn, SYS_SIGALTSTACK};
|
||||
use crate::{
|
||||
log_syscall_entry,
|
||||
prelude::*,
|
||||
process::{
|
||||
posix_thread::PosixThreadExt,
|
||||
signal::{SigStack, SigStackFlags},
|
||||
},
|
||||
util::{read_val_from_user, write_val_to_user},
|
||||
};
|
||||
|
||||
pub fn sys_sigaltstack(sig_stack_addr: Vaddr, old_sig_stack_addr: Vaddr) -> Result<SyscallReturn> {
|
||||
log_syscall_entry!(SYS_SIGALTSTACK);
|
||||
|
||||
debug!(
|
||||
"sig_stack_addr = 0x{:x}, old_sig_stack_addr: 0x{:x}",
|
||||
sig_stack_addr, old_sig_stack_addr
|
||||
);
|
||||
|
||||
let old_stack = {
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let sig_stack = posix_thread.sig_stack().lock();
|
||||
sig_stack.clone()
|
||||
};
|
||||
|
||||
get_old_stack(old_sig_stack_addr, old_stack.as_ref())?;
|
||||
set_new_stack(sig_stack_addr, old_stack.as_ref())?;
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
fn get_old_stack(old_sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Result<()> {
|
||||
if old_sig_stack_addr == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let Some(old_stack) = old_stack else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
debug!("old stack = {:?}", old_stack);
|
||||
|
||||
let stack = stack_t::from(old_stack.clone());
|
||||
write_val_to_user(old_sig_stack_addr, &stack)
|
||||
}
|
||||
|
||||
fn set_new_stack(sig_stack_addr: Vaddr, old_stack: Option<&SigStack>) -> Result<()> {
|
||||
if sig_stack_addr == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(old_stack) = old_stack
|
||||
&& old_stack.is_active()
|
||||
{
|
||||
return_errno_with_message!(Errno::EPERM, "the old stack is active now");
|
||||
}
|
||||
|
||||
let new_stack = {
|
||||
let stack = read_val_from_user::<stack_t>(sig_stack_addr)?;
|
||||
SigStack::try_from(stack)?
|
||||
};
|
||||
|
||||
debug!("new_stack = {:?}", new_stack);
|
||||
|
||||
let current_thread = current_thread!();
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
*posix_thread.sig_stack().lock() = Some(new_stack);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug, Clone, Copy, Pod)]
|
||||
#[repr(C)]
|
||||
struct stack_t {
|
||||
// Base address of stack
|
||||
sp: Vaddr,
|
||||
flags: i32,
|
||||
// Number of bytes in stack
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl TryFrom<stack_t> for SigStack {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(stack: stack_t) -> Result<Self> {
|
||||
if stack.flags < 0 {
|
||||
return_errno_with_message!(Errno::EINVAL, "negative flags");
|
||||
}
|
||||
|
||||
let flags = SigStackFlags::from_bits(stack.flags as u32)
|
||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?;
|
||||
|
||||
if stack.size < MINSTKSZ {
|
||||
return_errno_with_message!(Errno::ENOMEM, "stack size is less than MINSTKSZ");
|
||||
}
|
||||
|
||||
Ok(Self::new(stack.sp, flags, stack.size))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SigStack> for stack_t {
|
||||
fn from(stack: SigStack) -> Self {
|
||||
let flags = stack.flags().bits() as i32 | stack.status() as i32;
|
||||
Self {
|
||||
sp: stack.base(),
|
||||
flags,
|
||||
size: stack.size(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SIGSTKSZ: usize = 8192;
|
||||
const MINSTKSZ: usize = 2048;
|
Reference in New Issue
Block a user