xref: /DragonOS/kernel/src/process/fork.rs (revision 0274cd6eeec01885232e7418a501857cb76da69e)
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