xref: /DragonOS/kernel/src/process/fork.rs (revision 7f439c5ddbd2ecffc112149d16983975f523052c)
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::x86_64::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]
23 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]
82 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]
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]
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