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