sys_shmget.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. use crate::alloc::vec::Vec;
  2. use crate::syscall::table::FormattedSyscallParam;
  3. use crate::{
  4. arch::syscall::nr::SYS_SHMGET,
  5. ipc::shm::{shm_manager_lock, ShmFlags, ShmKey, IPC_PRIVATE},
  6. syscall::table::Syscall,
  7. };
  8. use log::error;
  9. use syscall_table_macros::declare_syscall;
  10. use system_error::SystemError;
  11. pub struct SysShmgetHandle;
  12. /// # SYS_SHMGET系统调用函数,用于获取共享内存
  13. ///
  14. /// ## 参数
  15. ///
  16. /// - `key`: 共享内存键值
  17. /// - `size`: 共享内存大小(bytes)
  18. /// - `shmflg`: 共享内存标志
  19. ///
  20. /// ## 返回值
  21. ///
  22. /// 成功:共享内存id
  23. /// 失败:错误码
  24. pub(super) fn do_kernel_shmget(
  25. key: ShmKey,
  26. size: usize,
  27. shmflg: ShmFlags,
  28. ) -> Result<usize, SystemError> {
  29. // 暂不支持巨页
  30. if shmflg.contains(ShmFlags::SHM_HUGETLB) {
  31. error!("shmget: not support huge page");
  32. return Err(SystemError::ENOSYS);
  33. }
  34. let mut shm_manager_guard = shm_manager_lock();
  35. match key {
  36. // 创建共享内存段
  37. IPC_PRIVATE => shm_manager_guard.add(key, size, shmflg),
  38. _ => {
  39. // 查找key对应的共享内存段是否存在
  40. let id = shm_manager_guard.contains_key(&key);
  41. if let Some(id) = id {
  42. // 不能重复创建
  43. if shmflg.contains(ShmFlags::IPC_CREAT | ShmFlags::IPC_EXCL) {
  44. return Err(SystemError::EEXIST);
  45. }
  46. // key值存在,说明有对应共享内存,返回该共享内存id
  47. return Ok(id.data());
  48. } else {
  49. // key不存在且shm_flags不包含IPC_CREAT创建IPC对象标志,则返回错误码
  50. if !shmflg.contains(ShmFlags::IPC_CREAT) {
  51. return Err(SystemError::ENOENT);
  52. }
  53. // 存在创建IPC对象标志
  54. return shm_manager_guard.add(key, size, shmflg);
  55. }
  56. }
  57. }
  58. }
  59. impl SysShmgetHandle {
  60. #[inline(always)]
  61. fn key(args: &[usize]) -> ShmKey {
  62. // 第一个参数是共享内存的key
  63. // In the old code: ShmKey::new(args[0])
  64. // ShmKey is likely a type alias for i32 or similar, args[0] is usize
  65. ShmKey::new(args[0]) // Assuming ShmKey::new takes i32
  66. }
  67. #[inline(always)]
  68. fn size(args: &[usize]) -> usize {
  69. // 第二个参数是共享内存的大小
  70. args[1]
  71. }
  72. #[inline(always)]
  73. fn shmflg(args: &[usize]) -> ShmFlags {
  74. // 第三个参数是共享内存的标志
  75. // In the old code: ShmFlags::from_bits_truncate(args[2] as u32)
  76. ShmFlags::from_bits_truncate(args[2] as u32)
  77. }
  78. }
  79. impl Syscall for SysShmgetHandle {
  80. fn num_args(&self) -> usize {
  81. 3 // key, size, shmflg
  82. }
  83. fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
  84. let key = Self::key(args);
  85. let size = Self::size(args);
  86. let shmflg = Self::shmflg(args);
  87. do_kernel_shmget(key, size, shmflg)
  88. }
  89. fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
  90. vec![
  91. FormattedSyscallParam::new("key", format!("{}", Self::key(args).data())),
  92. // 使用 format! 宏将 usize 类型的 size 转换为 String
  93. FormattedSyscallParam::new("size", format!("{}", Self::size(args))),
  94. FormattedSyscallParam::new("shmflg", format!("{:#x}", Self::shmflg(args).bits())),
  95. ]
  96. }
  97. }
  98. declare_syscall!(SYS_SHMGET, SysShmgetHandle);