fork.rs 3.5 KB

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