1 use core::{ffi::c_void, ptr::null_mut, sync::atomic::compiler_fence}; 2 3 use alloc::boxed::Box; 4 5 use crate::{ 6 arch::asm::current::current_pcb, 7 include::bindings::bindings::{ 8 process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, 9 }, 10 ipc::{ 11 signal::{flush_signal_handlers, DEFAULT_SIGACTION}, 12 signal_types::{sigaction, sighand_struct, signal_struct, SigQueue}, 13 }, 14 libs::{ 15 atomic::atomic_set, 16 ffi_convert::FFIBind2Rust, 17 refcount::{refcount_inc, RefCount}, 18 spinlock::{spin_lock_irqsave, spin_unlock_irqrestore}, 19 }, 20 syscall::SystemError, 21 }; 22 23 #[no_mangle] 24 pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 { 25 // kdebug!("process_copy_sighand"); 26 27 if (clone_flags & (CLONE_SIGHAND as u64)) != 0 { 28 let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap(); 29 refcount_inc(r); 30 } 31 32 // 在这里使用Box::leak将动态申请的内存的生命周期转换为static的 33 let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default())); 34 if (sig as *mut sighand_struct) == null_mut() { 35 return SystemError::ENOMEM.to_posix_errno(); 36 } 37 38 // 将新的sighand赋值给pcb 39 unsafe { 40 (*pcb).sighand = sig as *mut sighand_struct as usize 41 as *mut crate::include::bindings::bindings::sighand_struct; 42 } 43 44 // kdebug!("DEFAULT_SIGACTION.sa_flags={}", DEFAULT_SIGACTION.sa_flags); 45 46 // 拷贝sigaction 47 let mut flags: u64 = 0; 48 49 spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags); 50 compiler_fence(core::sync::atomic::Ordering::SeqCst); 51 52 for (index, x) in unsafe { (*current_pcb().sighand).action } 53 .iter() 54 .enumerate() 55 { 56 compiler_fence(core::sync::atomic::Ordering::SeqCst); 57 if !(x as *const crate::include::bindings::bindings::sigaction).is_null() { 58 sig.action[index] = 59 *sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction) 60 .unwrap(); 61 } else { 62 sig.action[index] = DEFAULT_SIGACTION; 63 } 64 } 65 compiler_fence(core::sync::atomic::Ordering::SeqCst); 66 67 spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags); 68 compiler_fence(core::sync::atomic::Ordering::SeqCst); 69 70 // 将信号的处理函数设置为default(除了那些被手动屏蔽的) 71 if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 { 72 compiler_fence(core::sync::atomic::Ordering::SeqCst); 73 74 flush_signal_handlers(pcb, false); 75 compiler_fence(core::sync::atomic::Ordering::SeqCst); 76 } 77 compiler_fence(core::sync::atomic::Ordering::SeqCst); 78 79 return 0; 80 } 81 82 #[no_mangle] 83 pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 { 84 // kdebug!("process_copy_signal"); 85 // 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号) 86 if (clone_flags & (CLONE_THREAD as u64)) != 0 { 87 return 0; 88 } 89 let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default())); 90 if (sig as *mut signal_struct) == null_mut() { 91 return SystemError::ENOMEM.to_posix_errno(); 92 } 93 atomic_set(&mut sig.sig_cnt, 1); 94 // 将sig赋值给pcb中的字段 95 unsafe { 96 (*pcb).signal = sig as *mut signal_struct as usize 97 as *mut crate::include::bindings::bindings::signal_struct; 98 } 99 100 // 创建新的sig_pending->sigqueue 101 unsafe { 102 (*pcb).sig_pending.signal = 0; 103 (*pcb).sig_pending.sigqueue = 104 Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void; 105 } 106 return 0; 107 } 108 109 #[no_mangle] 110 pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) { 111 // 回收进程的信号结构体 112 unsafe { 113 // 回收sighand 114 let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct); 115 116 drop(sighand); 117 (*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct; 118 119 // 回收sigqueue 120 let queue = Box::from_raw((*pcb).sig_pending.sigqueue as *mut SigQueue); 121 drop(queue); 122 } 123 } 124 125 #[no_mangle] 126 pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) { 127 // todo: 回收进程的sighand结构体 128 unsafe { 129 let sig = Box::from_raw((*pcb).signal as *mut signal_struct); 130 drop(sig); 131 (*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct; 132 } 133 } 134