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::asm::current::current_pcb,
7 include::bindings::bindings::{
8 process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD,
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 syscall::SystemError,
21 };
22
23 #[no_mangle]
process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i3224 pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
25 // kdebug!("process_copy_sighand");
26
27 if (clone_flags & (CLONE_SIGHAND as u64)) != 0 {
28 let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap();
29 refcount_inc(r);
30 }
31
32 // 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
33 let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
34 if (sig as *mut sighand_struct) == null_mut() {
35 return SystemError::ENOMEM.to_posix_errno();
36 }
37
38 // 将新的sighand赋值给pcb
39 unsafe {
40 (*pcb).sighand = sig as *mut sighand_struct as usize
41 as *mut crate::include::bindings::bindings::sighand_struct;
42 }
43
44 // kdebug!("DEFAULT_SIGACTION.sa_flags={}", DEFAULT_SIGACTION.sa_flags);
45
46 // 拷贝sigaction
47 let mut flags: usize = 0;
48
49 spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
50 compiler_fence(core::sync::atomic::Ordering::SeqCst);
51
52 for (index, x) in unsafe { (*current_pcb().sighand).action }
53 .iter()
54 .enumerate()
55 {
56 compiler_fence(core::sync::atomic::Ordering::SeqCst);
57 if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
58 sig.action[index] =
59 *sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
60 .unwrap();
61 } else {
62 sig.action[index] = DEFAULT_SIGACTION;
63 }
64 }
65 compiler_fence(core::sync::atomic::Ordering::SeqCst);
66
67 spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, flags);
68 compiler_fence(core::sync::atomic::Ordering::SeqCst);
69
70 // 将信号的处理函数设置为default(除了那些被手动屏蔽的)
71 if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
72 compiler_fence(core::sync::atomic::Ordering::SeqCst);
73
74 flush_signal_handlers(pcb, false);
75 compiler_fence(core::sync::atomic::Ordering::SeqCst);
76 }
77 compiler_fence(core::sync::atomic::Ordering::SeqCst);
78
79 return 0;
80 }
81
82 #[no_mangle]
process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i3283 pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
84 // kdebug!("process_copy_signal");
85 // 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
86 if (clone_flags & (CLONE_THREAD as u64)) != 0 {
87 return 0;
88 }
89 let sig: &mut signal_struct = Box::leak(Box::new(signal_struct::default()));
90 if (sig as *mut signal_struct) == null_mut() {
91 return SystemError::ENOMEM.to_posix_errno();
92 }
93 atomic_set(&mut sig.sig_cnt, 1);
94 // 将sig赋值给pcb中的字段
95 unsafe {
96 (*pcb).signal = sig as *mut signal_struct as usize
97 as *mut crate::include::bindings::bindings::signal_struct;
98 }
99
100 // 创建新的sig_pending->sigqueue
101 unsafe {
102 (*pcb).sig_pending.signal = 0;
103 (*pcb).sig_pending.sigqueue =
104 Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
105 }
106 return 0;
107 }
108
109 #[no_mangle]
process_exit_signal(pcb: *mut process_control_block)110 pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
111 // 回收进程的信号结构体
112 unsafe {
113 // 回收sighand
114 let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct);
115
116 drop(sighand);
117 (*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
118
119 // 回收sigqueue
120 let queue = Box::from_raw((*pcb).sig_pending.sigqueue as *mut SigQueue);
121 drop(queue);
122 }
123 }
124
125 #[no_mangle]
process_exit_sighand(pcb: *mut process_control_block)126 pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block) {
127 // todo: 回收进程的sighand结构体
128 unsafe {
129 let sig = Box::from_raw((*pcb).signal as *mut signal_struct);
130 drop(sig);
131 (*pcb).signal = 0 as *mut crate::include::bindings::bindings::signal_struct;
132 }
133 }
134
135 /// 拷贝进程的地址空间
136 ///
137 /// ## 参数
138 ///
139 /// - `clone_vm`: 是否与父进程共享地址空间。true表示共享
140 /// - `new_pcb`: 新进程的pcb
141 ///
142 /// ## 返回值
143 ///
144 /// - 成功:返回Ok(())
145 /// - 失败:返回Err(SystemError)
146 ///
147 /// ## Panic
148 ///
149 /// - 如果当前进程没有用户地址空间,则panic
copy_mm(clone_vm: bool, new_pcb: &mut process_control_block) -> Result<(), SystemError>150 pub fn copy_mm(clone_vm: bool, new_pcb: &mut process_control_block) -> Result<(), SystemError> {
151 // kdebug!("copy_mm, clone_vm: {}", clone_vm);
152 let old_address_space = current_pcb()
153 .address_space()
154 .expect("copy_mm: Failed to get address space of current process.");
155
156 if clone_vm {
157 unsafe { new_pcb.set_address_space(old_address_space) };
158 return Ok(());
159 }
160
161 let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
162 panic!(
163 "copy_mm: Failed to clone address space of current process, current pid: [{}], new pid: [{}]. Error: {:?}",
164 current_pcb().pid, new_pcb.pid, e
165 )
166 });
167 unsafe { new_pcb.set_address_space(new_address_space) };
168 return Ok(());
169 }
170