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