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