xref: /DragonOS/kernel/src/process/fork.rs (revision 40fe15e0953f989ccfeb74826d61621d43dea6bb)
11a2eaa40Slogin use core::{ffi::c_void, ptr::null_mut, sync::atomic::compiler_fence};
2c8025a88Slogin 
3c8025a88Slogin use alloc::boxed::Box;
4c8025a88Slogin 
5c8025a88Slogin use crate::{
6adc1846bSlogin     arch::asm::current::current_pcb,
76cb769c4Slogin     include::bindings::bindings::{
8676b8ef6SMork         process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD,
9c8025a88Slogin     },
106cb769c4Slogin     ipc::{
111a2eaa40Slogin         signal::{flush_signal_handlers, DEFAULT_SIGACTION},
121a2eaa40Slogin         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},
1978bf93f0SYJwu2023     },
2078bf93f0SYJwu2023     syscall::SystemError,
21c8025a88Slogin };
2266f67c6aSlogin 
2366f67c6aSlogin #[no_mangle]
2466f67c6aSlogin pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
251a2eaa40Slogin     // kdebug!("process_copy_sighand");
261a2eaa40Slogin 
2766f67c6aSlogin     if (clone_flags & (CLONE_SIGHAND as u64)) != 0 {
28c8025a88Slogin         let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap();
2966f67c6aSlogin         refcount_inc(r);
3066f67c6aSlogin     }
311a2eaa40Slogin 
32c8025a88Slogin     // 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
33c8025a88Slogin     let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
34c8025a88Slogin     if (sig as *mut sighand_struct) == null_mut() {
35676b8ef6SMork         return SystemError::ENOMEM.to_posix_errno();
36c8025a88Slogin     }
371a2eaa40Slogin 
38c8025a88Slogin     // 将新的sighand赋值给pcb
39c8025a88Slogin     unsafe {
40c8025a88Slogin         (*pcb).sighand = sig as *mut sighand_struct as usize
41c8025a88Slogin             as *mut crate::include::bindings::bindings::sighand_struct;
42c8025a88Slogin     }
43c8025a88Slogin 
441a2eaa40Slogin     // kdebug!("DEFAULT_SIGACTION.sa_flags={}", DEFAULT_SIGACTION.sa_flags);
451a2eaa40Slogin 
46c8025a88Slogin     // 拷贝sigaction
47*40fe15e0SLoGin     let mut flags: usize = 0;
481a2eaa40Slogin 
49c8025a88Slogin     spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
501a2eaa40Slogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
511a2eaa40Slogin 
52c8025a88Slogin     for (index, x) in unsafe { (*current_pcb().sighand).action }
53c8025a88Slogin         .iter()
54c8025a88Slogin         .enumerate()
55c8025a88Slogin     {
561a2eaa40Slogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
57c8025a88Slogin         if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
58c8025a88Slogin             sig.action[index] =
59c8025a88Slogin                 *sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
60c8025a88Slogin                     .unwrap();
61c8025a88Slogin         } else {
62c8025a88Slogin             sig.action[index] = DEFAULT_SIGACTION;
63c8025a88Slogin         }
64c8025a88Slogin     }
651a2eaa40Slogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
66c8025a88Slogin 
67*40fe15e0SLoGin     spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, flags);
681a2eaa40Slogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
69c8025a88Slogin 
701a2eaa40Slogin     // 将信号的处理函数设置为default(除了那些被手动屏蔽的)
71c8025a88Slogin     if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
721a2eaa40Slogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
731a2eaa40Slogin 
741a2eaa40Slogin         flush_signal_handlers(pcb, false);
751a2eaa40Slogin         compiler_fence(core::sync::atomic::Ordering::SeqCst);
76c8025a88Slogin     }
771a2eaa40Slogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
78c8025a88Slogin 
79c8025a88Slogin     return 0;
8066f67c6aSlogin }
8166f67c6aSlogin 
8266f67c6aSlogin #[no_mangle]
8366f67c6aSlogin pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
841a2eaa40Slogin     // kdebug!("process_copy_signal");
85c8025a88Slogin     // 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
86c8025a88Slogin     if (clone_flags & (CLONE_THREAD as u64)) != 0 {
87c8025a88Slogin         return 0;
88c8025a88Slogin     }
89c8025a88Slogin     let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default()));
90c8025a88Slogin     if (sig as *mut signal_struct) == null_mut() {
91676b8ef6SMork         return SystemError::ENOMEM.to_posix_errno();
92c8025a88Slogin     }
93c8025a88Slogin     atomic_set(&mut sig.sig_cnt, 1);
94c8025a88Slogin     // 将sig赋值给pcb中的字段
95c8025a88Slogin     unsafe {
96c8025a88Slogin         (*pcb).signal = sig as *mut signal_struct as usize
97c8025a88Slogin             as *mut crate::include::bindings::bindings::signal_struct;
98c8025a88Slogin     }
991a2eaa40Slogin 
1001a2eaa40Slogin     // 创建新的sig_pending->sigqueue
1011a2eaa40Slogin     unsafe {
1021a2eaa40Slogin         (*pcb).sig_pending.signal = 0;
1031a2eaa40Slogin         (*pcb).sig_pending.sigqueue =
1041a2eaa40Slogin             Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
1051a2eaa40Slogin     }
106c8025a88Slogin     return 0;
10766f67c6aSlogin }
10866f67c6aSlogin 
10966f67c6aSlogin #[no_mangle]
11066f67c6aSlogin pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
111c8025a88Slogin     // 回收进程的信号结构体
112c8025a88Slogin     unsafe {
1131a2eaa40Slogin         // 回收sighand
1140274cd6eSlogin         let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct);
1151a2eaa40Slogin 
1160274cd6eSlogin         drop(sighand);
117c8025a88Slogin         (*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
1181a2eaa40Slogin 
1191a2eaa40Slogin         // 回收sigqueue
1201a2eaa40Slogin         let queue = Box::from_raw((*pcb).sig_pending.sigqueue as *mut SigQueue);
1211a2eaa40Slogin         drop(queue);
122c8025a88Slogin     }
12366f67c6aSlogin }
12466f67c6aSlogin 
12566f67c6aSlogin #[no_mangle]
12666f67c6aSlogin pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) {
12766f67c6aSlogin     // todo: 回收进程的sighand结构体
128c8025a88Slogin     unsafe {
1290274cd6eSlogin         let sig = Box::from_raw((*pcb).signal as *mut signal_struct);
1300274cd6eSlogin         drop(sig);
131c8025a88Slogin         (*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct;
132c8025a88Slogin     }
13366f67c6aSlogin }
134*40fe15e0SLoGin 
135*40fe15e0SLoGin /// 拷贝进程的地址空间
136*40fe15e0SLoGin ///
137*40fe15e0SLoGin /// ## 参数
138*40fe15e0SLoGin ///
139*40fe15e0SLoGin /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
140*40fe15e0SLoGin /// - `new_pcb`: 新进程的pcb
141*40fe15e0SLoGin ///
142*40fe15e0SLoGin /// ## 返回值
143*40fe15e0SLoGin ///
144*40fe15e0SLoGin /// - 成功:返回Ok(())
145*40fe15e0SLoGin /// - 失败:返回Err(SystemError)
146*40fe15e0SLoGin ///
147*40fe15e0SLoGin /// ## Panic
148*40fe15e0SLoGin ///
149*40fe15e0SLoGin /// - 如果当前进程没有用户地址空间,则panic
150*40fe15e0SLoGin pub fn copy_mm(clone_vm: bool, new_pcb: &mut process_control_block) -> Result<(), SystemError> {
151*40fe15e0SLoGin     // kdebug!("copy_mm, clone_vm: {}", clone_vm);
152*40fe15e0SLoGin     let old_address_space = current_pcb()
153*40fe15e0SLoGin         .address_space()
154*40fe15e0SLoGin         .expect("copy_mm: Failed to get address space of current process.");
155*40fe15e0SLoGin 
156*40fe15e0SLoGin     if clone_vm {
157*40fe15e0SLoGin         unsafe { new_pcb.set_address_space(old_address_space) };
158*40fe15e0SLoGin         return Ok(());
159*40fe15e0SLoGin     }
160*40fe15e0SLoGin 
161*40fe15e0SLoGin     let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
162*40fe15e0SLoGin         panic!(
163*40fe15e0SLoGin             "copy_mm: Failed to clone address space of current process, current pid: [{}], new pid: [{}]. Error: {:?}",
164*40fe15e0SLoGin             current_pcb().pid, new_pcb.pid, e
165*40fe15e0SLoGin         )
166*40fe15e0SLoGin     });
167*40fe15e0SLoGin     unsafe { new_pcb.set_address_space(new_address_space) };
168*40fe15e0SLoGin     return Ok(());
169*40fe15e0SLoGin }
170