1 use core::ptr::null_mut; 2 3 use alloc::boxed::Box; 4 5 use crate::{ 6 arch::x86_64::asm::current::current_pcb, 7 include::{ 8 bindings::bindings::{ 9 process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, ENOMEM, 10 }, 11 DragonOS::signal::{sigaction, sighand_struct, signal_struct}, 12 }, 13 ipc::signal::DEFAULT_SIGACTION, 14 kdebug, 15 libs::{ 16 atomic::atomic_set, 17 ffi_convert::FFIBind2Rust, 18 refcount::{refcount_inc, RefCount}, 19 spinlock::{spin_lock_irqsave, spin_unlock_irqrestore}, 20 }, 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 if (clone_flags & (CLONE_SIGHAND as u64)) != 0 { 27 let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap(); 28 refcount_inc(r); 29 } 30 // 在这里使用Box::leak将动态申请的内存的生命周期转换为static的 31 let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default())); 32 if (sig as *mut sighand_struct) == null_mut() { 33 return -(ENOMEM as i32); 34 } 35 // 将新的sighand赋值给pcb 36 unsafe { 37 (*pcb).sighand = sig as *mut sighand_struct as usize 38 as *mut crate::include::bindings::bindings::sighand_struct; 39 } 40 41 // 拷贝sigaction 42 let mut flags: u64 = 0; 43 spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags); 44 for (index, x) in unsafe { (*current_pcb().sighand).action } 45 .iter() 46 .enumerate() 47 { 48 if !(x as *const crate::include::bindings::bindings::sigaction).is_null() { 49 sig.action[index] = 50 *sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction) 51 .unwrap(); 52 } else { 53 sig.action[index] = DEFAULT_SIGACTION; 54 } 55 } 56 57 spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags); 58 59 // 将所有屏蔽的信号的处理函数设置为default 60 if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 { 61 todo!(); 62 } 63 64 return 0; 65 } 66 67 #[no_mangle] 68 pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 { 69 kdebug!("process_copy_signal"); 70 // 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号) 71 if (clone_flags & (CLONE_THREAD as u64)) != 0 { 72 return 0; 73 } 74 let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default())); 75 if (sig as *mut signal_struct) == null_mut() { 76 return -(ENOMEM as i32); 77 } 78 atomic_set(&mut sig.sig_cnt, 1); 79 // 将sig赋值给pcb中的字段 80 unsafe { 81 (*pcb).signal = sig as *mut signal_struct as usize 82 as *mut crate::include::bindings::bindings::signal_struct; 83 } 84 return 0; 85 } 86 87 #[no_mangle] 88 pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) { 89 // 回收进程的信号结构体 90 unsafe { 91 let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct); 92 drop(sighand); 93 (*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct; 94 } 95 } 96 97 #[no_mangle] 98 pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) { 99 // todo: 回收进程的sighand结构体 100 unsafe { 101 let sig = Box::from_raw((*pcb).signal as *mut signal_struct); 102 drop(sig); 103 (*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct; 104 } 105 } 106