session.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use super::{pid::Pid, ProcessControlBlock, ProcessManager, RawPid};
  2. use crate::{driver::tty::tty_job_control::TtyJobCtrlManager, process::pid::PidType};
  3. use alloc::sync::Arc;
  4. use system_error::SystemError;
  5. /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/sys.c#1225
  6. pub(super) fn ksys_setsid() -> Result<RawPid, SystemError> {
  7. let pcb = ProcessManager::current_pcb();
  8. let group_leader = pcb
  9. .threads_read_irqsave()
  10. .group_leader()
  11. .ok_or(SystemError::ESRCH)?;
  12. let sid = group_leader.pid();
  13. let session = sid.pid_vnr();
  14. // log::debug!(
  15. // "ksys_setsid: group_leader: {}",
  16. // group_leader.raw_pid().data()
  17. // );
  18. let siginfo_lock = group_leader.sig_info_upgradable();
  19. // Fail if pcb already a session leader
  20. if siginfo_lock.is_session_leader {
  21. return Err(SystemError::EPERM);
  22. }
  23. // Fail if a process group id already exists that equals the
  24. // proposed session id.
  25. if sid.pid_task(PidType::PGID).is_some() {
  26. return Err(SystemError::EPERM);
  27. }
  28. let mut siginfo_guard = siginfo_lock.upgrade();
  29. siginfo_guard.is_session_leader = true;
  30. set_special_pids(&group_leader, &sid);
  31. TtyJobCtrlManager::__proc_clear_tty(&mut siginfo_guard);
  32. return Ok(session);
  33. }
  34. fn set_special_pids(current_session_group_leader: &Arc<ProcessControlBlock>, sid: &Arc<Pid>) {
  35. let session = current_session_group_leader.task_session();
  36. let change_sid = match session {
  37. Some(s) => !Arc::ptr_eq(&s, sid),
  38. None => true,
  39. };
  40. let pgrp = current_session_group_leader.task_pgrp();
  41. let change_pgrp = match pgrp {
  42. Some(pg) => !Arc::ptr_eq(&pg, sid),
  43. None => true,
  44. };
  45. // log::debug!(
  46. // "leader: {}, change sid: {}, pgrp: {}, sid_raw: {}",
  47. // current_session_group_leader.raw_pid().data(),
  48. // change_sid,
  49. // change_pgrp,
  50. // sid.pid_vnr().data()
  51. // );
  52. if change_sid {
  53. current_session_group_leader.change_pid(PidType::SID, sid.clone());
  54. }
  55. if change_pgrp {
  56. current_session_group_leader.change_pid(PidType::PGID, sid.clone());
  57. }
  58. // log::debug!(
  59. // "after change, pgrp: {}",
  60. // current_session_group_leader
  61. // .task_pgrp()
  62. // .unwrap()
  63. // .pid_vnr()
  64. // .data()
  65. // );
  66. }