sys_shmctl.rs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use crate::alloc::vec::Vec;
  2. use crate::{
  3. arch::syscall::nr::SYS_SHMCTL,
  4. ipc::shm::{shm_manager_lock, ShmCtlCmd, ShmId},
  5. syscall::table::{FormattedSyscallParam, Syscall},
  6. };
  7. use syscall_table_macros::declare_syscall;
  8. use system_error::SystemError;
  9. pub struct SysShmctlHandle;
  10. /// # SYS_SHMCTL系统调用函数,用于管理共享内存段
  11. ///
  12. /// ## 参数
  13. ///
  14. /// - `id`: 共享内存id
  15. /// - `cmd`: 操作码
  16. /// - `user_buf`: 用户缓冲区
  17. /// - `from_user`: buf_vaddr是否来自用户地址空间
  18. ///
  19. /// ## 返回值
  20. ///
  21. /// 成功:0
  22. /// 失败:错误码
  23. pub(super) fn do_kernel_shmctl(
  24. id: ShmId,
  25. cmd: ShmCtlCmd,
  26. user_buf: *const u8,
  27. from_user: bool,
  28. ) -> Result<usize, SystemError> {
  29. let mut shm_manager_guard = shm_manager_lock();
  30. match cmd {
  31. // 查看共享内存元信息
  32. ShmCtlCmd::IpcInfo => shm_manager_guard.ipc_info(user_buf, from_user),
  33. // 查看共享内存使用信息
  34. ShmCtlCmd::ShmInfo => shm_manager_guard.shm_info(user_buf, from_user),
  35. // 查看id对应的共享内存信息
  36. ShmCtlCmd::ShmStat | ShmCtlCmd::ShmtStatAny | ShmCtlCmd::IpcStat => {
  37. shm_manager_guard.shm_stat(id, cmd, user_buf, from_user)
  38. }
  39. // 设置KernIpcPerm
  40. ShmCtlCmd::IpcSet => shm_manager_guard.ipc_set(id, user_buf, from_user),
  41. // 将共享内存段设置为可回收状态
  42. ShmCtlCmd::IpcRmid => shm_manager_guard.ipc_rmid(id),
  43. // 锁住共享内存段,不允许内存置换
  44. ShmCtlCmd::ShmLock => shm_manager_guard.shm_lock(id),
  45. // 解锁共享内存段,允许内存置换
  46. ShmCtlCmd::ShmUnlock => shm_manager_guard.shm_unlock(id),
  47. // 无效操作码
  48. ShmCtlCmd::Default => Err(SystemError::EINVAL),
  49. }
  50. }
  51. impl SysShmctlHandle {
  52. #[inline(always)]
  53. fn id(args: &[usize]) -> ShmId {
  54. ShmId::new(args[0]) // Assuming ShmId::new takes usize or can infer from args[0]
  55. }
  56. #[inline(always)]
  57. fn cmd(args: &[usize]) -> ShmCtlCmd {
  58. ShmCtlCmd::from(args[1])
  59. }
  60. #[inline(always)]
  61. fn user_buf(args: &[usize]) -> *const u8 {
  62. args[2] as *const u8 // Assuming args[2] is a pointer to user buffer
  63. }
  64. }
  65. impl Syscall for SysShmctlHandle {
  66. fn num_args(&self) -> usize {
  67. 3
  68. }
  69. fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
  70. vec![
  71. FormattedSyscallParam::new("shmid", format!("{}", Self::id(args).data())),
  72. FormattedSyscallParam::new("cmd", format!("{}", Self::cmd(args))),
  73. FormattedSyscallParam::new("buf", format!("{:#x}", Self::user_buf(args) as usize)),
  74. ]
  75. }
  76. fn handle(&self, args: &[usize], from_user: bool) -> Result<usize, SystemError> {
  77. let id = Self::id(args);
  78. let cmd = Self::cmd(args);
  79. let user_buf = Self::user_buf(args);
  80. do_kernel_shmctl(id, cmd, user_buf, from_user)
  81. }
  82. }
  83. declare_syscall!(SYS_SHMCTL, SysShmctlHandle);