shm.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. use crate::{
  2. arch::mm::LockedFrameAllocator,
  3. filesystem::vfs::syscall::ModeType,
  4. libs::{
  5. align::page_align_up,
  6. spinlock::{SpinLock, SpinLockGuard},
  7. },
  8. mm::{
  9. allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame},
  10. page::{page_manager_lock_irqsave, Page},
  11. PhysAddr,
  12. },
  13. process::{Pid, ProcessManager},
  14. syscall::user_access::{UserBufferReader, UserBufferWriter},
  15. time::PosixTimeSpec,
  16. };
  17. use alloc::{sync::Arc, vec::Vec};
  18. use core::sync::atomic::{compiler_fence, Ordering};
  19. use hashbrown::{HashMap, HashSet};
  20. use ida::IdAllocator;
  21. use log::info;
  22. use num::ToPrimitive;
  23. use system_error::SystemError;
  24. pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None;
  25. /// 用于创建新的私有IPC对象
  26. pub const IPC_PRIVATE: ShmKey = ShmKey::new(0);
  27. /// 初始化SHM_MANAGER
  28. pub fn shm_manager_init() {
  29. info!("shm_manager_init");
  30. let shm_manager = SpinLock::new(ShmManager::new());
  31. compiler_fence(Ordering::SeqCst);
  32. unsafe { SHM_MANAGER = Some(shm_manager) };
  33. compiler_fence(Ordering::SeqCst);
  34. info!("shm_manager_init done");
  35. }
  36. pub fn shm_manager_lock() -> SpinLockGuard<'static, ShmManager> {
  37. unsafe { SHM_MANAGER.as_ref().unwrap().lock() }
  38. }
  39. int_like!(ShmId, usize);
  40. int_like!(ShmKey, usize);
  41. bitflags! {
  42. pub struct ShmFlags:u32{
  43. const SHM_RDONLY = 0o10000;
  44. const SHM_RND = 0o20000;
  45. const SHM_REMAP = 0o40000;
  46. const SHM_EXEC = 0o100000;
  47. const SHM_HUGETLB = 0o4000;
  48. const IPC_CREAT = 0o1000;
  49. const IPC_EXCL = 0o2000;
  50. const SHM_DEST = 0o1000;
  51. const SHM_LOCKED = 0o2000;
  52. }
  53. }
  54. /// 管理共享内存段信息的操作码
  55. #[derive(Eq, Clone, Copy)]
  56. pub enum ShmCtlCmd {
  57. /// 删除共享内存段
  58. IpcRmid = 0,
  59. /// 设置KernIpcPerm选项
  60. IpcSet = 1,
  61. /// 获取ShmIdDs
  62. IpcStat = 2,
  63. /// 查看ShmMetaData
  64. IpcInfo = 3,
  65. /// 不允许共享内存段被置换出物理内存
  66. ShmLock = 11,
  67. /// 允许共享内存段被置换出物理内存
  68. ShmUnlock = 12,
  69. /// 查看ShmMetaData
  70. ShmStat = 13,
  71. /// 查看ShmInfo
  72. ShmInfo = 14,
  73. /// 查看ShmMetaData
  74. ShmtStatAny = 15,
  75. Default,
  76. }
  77. impl From<usize> for ShmCtlCmd {
  78. fn from(cmd: usize) -> ShmCtlCmd {
  79. match cmd {
  80. 0 => Self::IpcRmid,
  81. 1 => Self::IpcSet,
  82. 2 => Self::IpcStat,
  83. 3 => Self::IpcInfo,
  84. 11 => Self::ShmLock,
  85. 12 => Self::ShmUnlock,
  86. 13 => Self::ShmStat,
  87. 14 => Self::ShmInfo,
  88. 15 => Self::ShmtStatAny,
  89. _ => Self::Default,
  90. }
  91. }
  92. }
  93. impl PartialEq for ShmCtlCmd {
  94. fn eq(&self, other: &ShmCtlCmd) -> bool {
  95. *self as usize == *other as usize
  96. }
  97. }
  98. /// 共享内存管理器
  99. #[derive(Debug)]
  100. pub struct ShmManager {
  101. /// ShmId分配器
  102. id_allocator: IdAllocator,
  103. /// ShmId映射共享内存信息表
  104. id2shm: HashMap<ShmId, KernelShm>,
  105. /// ShmKey映射ShmId表
  106. key2id: HashMap<ShmKey, ShmId>,
  107. }
  108. impl ShmManager {
  109. pub fn new() -> Self {
  110. ShmManager {
  111. id_allocator: IdAllocator::new(0, usize::MAX - 1),
  112. id2shm: HashMap::new(),
  113. key2id: HashMap::new(),
  114. }
  115. }
  116. /// # 添加共享内存段
  117. ///
  118. /// ## 参数
  119. ///
  120. /// - `key`: 共享内存键值
  121. /// - `size`: 共享内存大小
  122. /// - `shmflg`: 共享内存标志
  123. ///
  124. /// ## 返回值
  125. ///
  126. /// 成功:共享内存id
  127. /// 失败:对应错误码
  128. pub fn add(
  129. &mut self,
  130. key: ShmKey,
  131. size: usize,
  132. shmflg: ShmFlags,
  133. ) -> Result<usize, SystemError> {
  134. // 判断共享内存大小是否过小或溢出
  135. if !(PosixShmMetaInfo::SHMMIN..=PosixShmMetaInfo::SHMMAX).contains(&size) {
  136. return Err(SystemError::EINVAL);
  137. }
  138. let id = self.id_allocator.alloc().expect("No more id to allocate.");
  139. let shm_id = ShmId::new(id);
  140. // 分配共享内存页面
  141. let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap();
  142. let phys_page =
  143. unsafe { LockedFrameAllocator.allocate(page_count) }.ok_or(SystemError::EINVAL)?;
  144. // 创建共享内存page,并添加到PAGE_MANAGER中
  145. let mut page_manager_guard = page_manager_lock_irqsave();
  146. let mut cur_phys = PhysPageFrame::new(phys_page.0);
  147. for _ in 0..page_count.data() {
  148. let page = Arc::new(Page::new(true, cur_phys));
  149. page.write().set_shm_id(shm_id);
  150. let paddr = cur_phys.phys_address();
  151. page_manager_guard.insert(paddr, &page);
  152. cur_phys = cur_phys.next();
  153. }
  154. // 创建共享内存信息结构体
  155. let paddr = phys_page.0;
  156. let kern_ipc_perm = KernIpcPerm {
  157. id: shm_id,
  158. key,
  159. uid: 0,
  160. gid: 0,
  161. _cuid: 0,
  162. _cgid: 0,
  163. mode: shmflg & ShmFlags::from_bits_truncate(ModeType::S_IRWXUGO.bits()),
  164. _seq: 0,
  165. };
  166. let shm_kernel = KernelShm::new(kern_ipc_perm, paddr, size);
  167. // 将key、id及其对应KernelShm添加到表中
  168. self.id2shm.insert(shm_id, shm_kernel);
  169. self.key2id.insert(key, shm_id);
  170. return Ok(shm_id.data());
  171. }
  172. pub fn contains_key(&self, key: &ShmKey) -> Option<&ShmId> {
  173. self.key2id.get(key)
  174. }
  175. pub fn get_mut(&mut self, id: &ShmId) -> Option<&mut KernelShm> {
  176. self.id2shm.get_mut(id)
  177. }
  178. pub fn free_key(&mut self, key: &ShmKey) {
  179. self.key2id.remove(key);
  180. }
  181. pub fn free_id(&mut self, id: &ShmId) {
  182. self.id2shm.remove(id);
  183. self.id_allocator.free(id.0);
  184. }
  185. pub fn ipc_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
  186. let mut user_buffer_writer = UserBufferWriter::new(
  187. user_buf as *mut u8,
  188. core::mem::size_of::<PosixShmMetaInfo>(),
  189. from_user,
  190. )?;
  191. let shm_meta_info = PosixShmMetaInfo::new();
  192. user_buffer_writer.copy_one_to_user(&shm_meta_info, 0)?;
  193. return Ok(0);
  194. }
  195. pub fn shm_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
  196. // 已使用id数量
  197. let used_ids = self.id2shm.len().to_i32().unwrap();
  198. // 共享内存总和
  199. let shm_tot = self.id2shm.iter().fold(0, |acc, (_, kernel_shm)| {
  200. acc + PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size))
  201. .unwrap()
  202. .data()
  203. });
  204. let shm_info = PosixShmInfo::new(used_ids, shm_tot, 0, 0, 0, 0);
  205. let mut user_buffer_writer = UserBufferWriter::new(
  206. user_buf as *mut u8,
  207. core::mem::size_of::<PosixShmInfo>(),
  208. from_user,
  209. )?;
  210. user_buffer_writer.copy_one_to_user(&shm_info, 0)?;
  211. return Ok(0);
  212. }
  213. pub fn shm_stat(
  214. &self,
  215. id: ShmId,
  216. cmd: ShmCtlCmd,
  217. user_buf: *const u8,
  218. from_user: bool,
  219. ) -> Result<usize, SystemError> {
  220. let kernel_shm = self.id2shm.get(&id).ok_or(SystemError::EINVAL)?;
  221. let key = kernel_shm.kern_ipc_perm.key.data().to_i32().unwrap();
  222. let mode = kernel_shm.kern_ipc_perm.mode.bits();
  223. let shm_perm = PosixIpcPerm::new(key, 0, 0, 0, 0, mode);
  224. let shm_segsz = kernel_shm.shm_size;
  225. let shm_atime = kernel_shm.shm_atim.total_nanos();
  226. let shm_dtime = kernel_shm.shm_dtim.total_nanos();
  227. let shm_ctime = kernel_shm.shm_ctim.total_nanos();
  228. let shm_cpid = kernel_shm.shm_cprid.data().to_u32().unwrap();
  229. let shm_lpid = kernel_shm.shm_lprid.data().to_u32().unwrap();
  230. let shm_map_count = kernel_shm.map_count();
  231. let shm_id_ds = PosixShmIdDs {
  232. shm_perm,
  233. shm_segsz,
  234. shm_atime,
  235. shm_dtime,
  236. shm_ctime,
  237. shm_cpid,
  238. shm_lpid,
  239. shm_map_count,
  240. _unused1: 0,
  241. _unused2: 0,
  242. };
  243. let mut user_buffer_writer = UserBufferWriter::new(
  244. user_buf as *mut u8,
  245. core::mem::size_of::<PosixShmIdDs>(),
  246. from_user,
  247. )?;
  248. user_buffer_writer.copy_one_to_user(&shm_id_ds, 0)?;
  249. let r: usize = if cmd == ShmCtlCmd::IpcStat {
  250. 0
  251. } else {
  252. id.data()
  253. };
  254. return Ok(r);
  255. }
  256. pub fn ipc_set(
  257. &mut self,
  258. id: ShmId,
  259. user_buf: *const u8,
  260. from_user: bool,
  261. ) -> Result<usize, SystemError> {
  262. let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
  263. let user_buffer_reader =
  264. UserBufferReader::new(user_buf, core::mem::size_of::<PosixShmIdDs>(), from_user)?;
  265. let mut shm_id_ds = PosixShmIdDs::default();
  266. user_buffer_reader.copy_one_from_user(&mut shm_id_ds, 0)?;
  267. kernel_shm.copy_from(shm_id_ds);
  268. return Ok(0);
  269. }
  270. pub fn ipc_rmid(&mut self, id: ShmId) -> Result<usize, SystemError> {
  271. let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
  272. kernel_shm.set_mode(ShmFlags::SHM_DEST, true);
  273. let mut cur_phys = PhysPageFrame::new(kernel_shm.shm_start_paddr);
  274. let count = PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size)).unwrap();
  275. let key = kernel_shm.kern_ipc_perm.key;
  276. let id = kernel_shm.kern_ipc_perm.id;
  277. let map_count = kernel_shm.map_count();
  278. let mut page_manager_guard = page_manager_lock_irqsave();
  279. if map_count > 0 {
  280. // 设置共享内存物理页当映射计数等于0时可被回收
  281. for _ in 0..count.data() {
  282. let page = page_manager_guard.get_unwrap(&cur_phys.phys_address());
  283. page.write().set_dealloc_when_zero(true);
  284. cur_phys = cur_phys.next();
  285. }
  286. // 释放key,不让后续进程连接
  287. self.free_key(&key);
  288. } else {
  289. // 释放共享内存物理页
  290. for _ in 0..count.data() {
  291. let paddr = cur_phys.phys_address();
  292. unsafe {
  293. LockedFrameAllocator.free(paddr, PageFrameCount::new(1));
  294. }
  295. // 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
  296. page_manager_guard.remove_page(&paddr);
  297. cur_phys = cur_phys.next();
  298. }
  299. // 释放key和id
  300. self.free_id(&id);
  301. self.free_key(&key)
  302. }
  303. return Ok(0);
  304. }
  305. pub fn shm_lock(&mut self, id: ShmId) -> Result<usize, SystemError> {
  306. let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
  307. kernel_shm.set_mode(ShmFlags::SHM_LOCKED, true);
  308. return Ok(0);
  309. }
  310. pub fn shm_unlock(&mut self, id: ShmId) -> Result<usize, SystemError> {
  311. let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
  312. kernel_shm.set_mode(ShmFlags::SHM_LOCKED, false);
  313. return Ok(0);
  314. }
  315. }
  316. /// 共享内存信息
  317. #[derive(Debug)]
  318. pub struct KernelShm {
  319. /// 权限信息
  320. kern_ipc_perm: KernIpcPerm,
  321. /// 共享内存起始物理地址
  322. shm_start_paddr: PhysAddr,
  323. /// 共享内存大小(bytes),注意是用户指定的大小(未经过页面对齐)
  324. shm_size: usize,
  325. /// 最后一次连接的时间
  326. shm_atim: PosixTimeSpec,
  327. /// 最后一次断开连接的时间
  328. shm_dtim: PosixTimeSpec,
  329. /// 最后一次更改信息的时间
  330. shm_ctim: PosixTimeSpec,
  331. /// 创建者进程id
  332. shm_cprid: Pid,
  333. /// 最后操作者进程id
  334. shm_lprid: Pid,
  335. }
  336. impl KernelShm {
  337. pub fn new(kern_ipc_perm: KernIpcPerm, shm_start_paddr: PhysAddr, shm_size: usize) -> Self {
  338. let shm_cprid = ProcessManager::current_pid();
  339. KernelShm {
  340. kern_ipc_perm,
  341. shm_start_paddr,
  342. shm_size,
  343. shm_atim: PosixTimeSpec::new(0, 0),
  344. shm_dtim: PosixTimeSpec::new(0, 0),
  345. shm_ctim: PosixTimeSpec::now(),
  346. shm_cprid,
  347. shm_lprid: shm_cprid,
  348. }
  349. }
  350. pub fn start_paddr(&self) -> PhysAddr {
  351. self.shm_start_paddr
  352. }
  353. pub fn size(&self) -> usize {
  354. self.shm_size
  355. }
  356. /// 更新最后连接时间
  357. pub fn update_atim(&mut self) {
  358. // 更新最后一次连接时间
  359. self.shm_atim = PosixTimeSpec::now();
  360. // 更新最后操作当前共享内存的进程ID
  361. self.shm_lprid = ProcessManager::current_pid();
  362. }
  363. /// 更新最后断开连接时间
  364. pub fn update_dtim(&mut self) {
  365. // 更新最后一次断开连接时间
  366. self.shm_dtim = PosixTimeSpec::now();
  367. // 更新最后操作当前共享内存的进程ID
  368. self.shm_lprid = ProcessManager::current_pid();
  369. }
  370. /// 更新最后一次修改信息的时间
  371. pub fn update_ctim(&mut self) {
  372. // 更新最后一次修改信息的时间
  373. self.shm_ctim = PosixTimeSpec::now();
  374. }
  375. /// 共享内存段的映射计数(有多少个不同的VMA映射)
  376. pub fn map_count(&self) -> usize {
  377. let page_manager_guard = page_manager_lock_irqsave();
  378. let mut id_set: HashSet<usize> = HashSet::new();
  379. let mut cur_phys = PhysPageFrame::new(self.shm_start_paddr);
  380. let page_count = PageFrameCount::from_bytes(page_align_up(self.shm_size)).unwrap();
  381. for _ in 0..page_count.data() {
  382. let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap();
  383. id_set.extend(
  384. page.read()
  385. .anon_vma()
  386. .iter()
  387. .map(|vma| vma.id())
  388. .collect::<Vec<_>>(),
  389. );
  390. cur_phys = cur_phys.next();
  391. }
  392. // 由于LockedVMA的id是独一无二的,因此有多少个不同的id,就代表着有多少个不同的VMA映射到共享内存段
  393. return id_set.len();
  394. }
  395. pub fn copy_from(&mut self, shm_id_ds: PosixShmIdDs) {
  396. self.kern_ipc_perm.uid = shm_id_ds.uid() as usize;
  397. self.kern_ipc_perm.gid = shm_id_ds.gid() as usize;
  398. self.kern_ipc_perm.mode = ShmFlags::from_bits_truncate(shm_id_ds.mode());
  399. self.update_ctim();
  400. }
  401. pub fn set_mode(&mut self, shmflg: ShmFlags, set: bool) {
  402. if set {
  403. self.kern_ipc_perm.mode.insert(shmflg);
  404. } else {
  405. self.kern_ipc_perm.mode.remove(shmflg);
  406. }
  407. self.update_ctim();
  408. }
  409. }
  410. /// 共享内存权限信息
  411. #[derive(Debug)]
  412. pub struct KernIpcPerm {
  413. /// 共享内存id
  414. id: ShmId,
  415. /// 共享内存键值,由创建共享内存用户指定
  416. key: ShmKey,
  417. /// 共享内存拥有者用户id
  418. uid: usize,
  419. /// 共享内存拥有者所在组id
  420. gid: usize,
  421. /// 共享内存创建者用户id
  422. _cuid: usize,
  423. /// 共享内存创建者所在组id
  424. _cgid: usize,
  425. /// 共享内存区权限模式
  426. mode: ShmFlags,
  427. _seq: usize,
  428. }
  429. /// 共享内存元信息,符合POSIX标准
  430. #[repr(C)]
  431. #[derive(Debug, Clone, Copy)]
  432. pub struct PosixShmMetaInfo {
  433. /// 最大共享内存段的大小(bytes)
  434. shmmax: usize,
  435. /// 最小共享内存段的大小(bytes)
  436. shmmin: usize,
  437. /// 最大共享内存标识符数量
  438. shmmni: usize,
  439. /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
  440. shmseg: usize,
  441. /// 所有共享内存段总共可以使用的最大内存量(pages)
  442. shmall: usize,
  443. _unused1: usize,
  444. _unused2: usize,
  445. _unused3: usize,
  446. _unused4: usize,
  447. }
  448. impl PosixShmMetaInfo {
  449. /// 最小共享内存段的大小(bytes)
  450. pub const SHMMIN: usize = 1;
  451. /// 最大共享内存标识符数量
  452. pub const SHMMNI: usize = 4096;
  453. /// 最大共享内存段的大小(bytes)
  454. pub const SHMMAX: usize = usize::MAX - (1 << 24);
  455. /// 所有共享内存段总共可以使用的最大内存量(pages)
  456. pub const SHMALL: usize = usize::MAX - (1 << 24);
  457. /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
  458. pub const SHMSEG: usize = 4096;
  459. pub fn new() -> Self {
  460. PosixShmMetaInfo {
  461. shmmax: Self::SHMMAX,
  462. shmmin: Self::SHMMIN,
  463. shmmni: Self::SHMMNI,
  464. shmseg: Self::SHMSEG,
  465. shmall: Self::SHMALL,
  466. _unused1: 0,
  467. _unused2: 0,
  468. _unused3: 0,
  469. _unused4: 0,
  470. }
  471. }
  472. }
  473. /// 共享内存信息,符合POSIX标准
  474. #[repr(C)]
  475. #[derive(Clone, Copy)]
  476. pub struct PosixShmInfo {
  477. /// 已使用id数
  478. used_ids: i32,
  479. /// 共享内存总量(pages)
  480. shm_tot: usize,
  481. /// 保留在内存中的共享内存大小
  482. shm_rss: usize,
  483. /// 被置换出的共享内存大小
  484. shm_swp: usize,
  485. /// 尝试置换次数
  486. swap_attempts: usize,
  487. /// 成功置换次数
  488. swap_successes: usize,
  489. }
  490. impl PosixShmInfo {
  491. pub fn new(
  492. used_ids: i32,
  493. shm_tot: usize,
  494. shm_rss: usize,
  495. shm_swp: usize,
  496. swap_attempts: usize,
  497. swap_successes: usize,
  498. ) -> Self {
  499. PosixShmInfo {
  500. used_ids,
  501. shm_tot,
  502. shm_rss,
  503. shm_swp,
  504. swap_attempts,
  505. swap_successes,
  506. }
  507. }
  508. }
  509. /// 共享内存段属性信息,符合POSIX标准
  510. #[repr(C)]
  511. #[derive(Debug, Clone, Copy, Default)]
  512. pub struct PosixShmIdDs {
  513. /// 共享内存段权限
  514. shm_perm: PosixIpcPerm,
  515. /// 共享内存大小(bytes)
  516. shm_segsz: usize,
  517. /// 最后一次连接的时间
  518. shm_atime: i64,
  519. /// 最后一次断开连接的时间
  520. shm_dtime: i64,
  521. /// 最后一次更改信息的时间
  522. shm_ctime: i64,
  523. /// 创建者进程id
  524. shm_cpid: u32,
  525. /// 最后操作者进程id
  526. shm_lpid: u32,
  527. /// 链接数
  528. shm_map_count: usize,
  529. _unused1: usize,
  530. _unused2: usize,
  531. }
  532. impl PosixShmIdDs {
  533. pub fn uid(&self) -> u32 {
  534. self.shm_perm.uid
  535. }
  536. pub fn gid(&self) -> u32 {
  537. self.shm_perm.gid
  538. }
  539. pub fn mode(&self) -> u32 {
  540. self.shm_perm.mode
  541. }
  542. }
  543. /// 共享内存段权限,符合POSIX标准
  544. #[repr(C)]
  545. #[derive(Debug, Clone, Copy, Default)]
  546. pub struct PosixIpcPerm {
  547. /// IPC对象键值
  548. key: i32,
  549. /// 当前用户id
  550. uid: u32,
  551. /// 当前用户组id
  552. gid: u32,
  553. /// 创建者用户id
  554. cuid: u32,
  555. /// 创建者组id
  556. cgid: u32,
  557. /// 权限
  558. mode: u32,
  559. /// 序列号
  560. seq: i32,
  561. _pad1: i32,
  562. _unused1: usize,
  563. _unused2: usize,
  564. }
  565. impl PosixIpcPerm {
  566. pub fn new(key: i32, uid: u32, gid: u32, cuid: u32, cgid: u32, mode: u32) -> Self {
  567. PosixIpcPerm {
  568. key,
  569. uid,
  570. gid,
  571. cuid,
  572. cgid,
  573. mode,
  574. seq: 0,
  575. _pad1: 0,
  576. _unused1: 0,
  577. _unused2: 0,
  578. }
  579. }
  580. }