1use core::ffi::c_int;
2
3use crate::bindings;
4use crate::const_conversions;
5use crate::stat::SFlag;
6
7pub const SHMMIN: usize = const_conversions::usize_from_u32(bindings::LINUX_SHMMIN);
9pub const SHMMNI: usize = const_conversions::usize_from_u32(bindings::LINUX_SHMMNI);
11pub const SHMSEG: usize = const_conversions::usize_from_u32(bindings::LINUX_SHMSEG);
13pub use bindings::LINUX_SHM_HUGE_SHIFT as SHM_HUGE_SHIFT;
17
18pub use bindings::linux_shmid64_ds as shmid64_ds;
20
21use num_enum::IntoPrimitive;
22use num_enum::TryFromPrimitive;
23
24bitflags::bitflags! {
25 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
31 pub struct ShmgetFlags: i32 {
32 const IPC_CREAT = const_conversions::i32_from_u32(bindings::LINUX_IPC_CREAT);
34 const IPC_EXCL = const_conversions::i32_from_u32(bindings::LINUX_IPC_EXCL);
36 const SHM_HUGETLB = const_conversions::i32_from_u32(bindings::LINUX_SHM_HUGETLB);
38 const SHM_NORESERVE = const_conversions::i32_from_u32(bindings::LINUX_SHM_NORESERVE);
40 }
41}
42
43#[derive(Copy, Clone, Debug, Eq, PartialEq)]
45pub struct ShmgetFlagsParts {
46 pub flags: ShmgetFlags,
48 pub tlb_size_log_2: u32,
50 pub perms: SFlag,
52}
53
54impl ShmgetFlagsParts {
55 pub fn from_shmflg(shmflg: c_int) -> Self {
57 let tlb_size_shift = SHM_HUGE_SHIFT;
58 let tlb_size_mask = 0b11_1111 << tlb_size_shift;
59
60 let perms_shift = 0;
61 let perms_mask = 0b1_1111_1111;
62 Self {
63 tlb_size_log_2: (shmflg & tlb_size_mask) as u32 >> tlb_size_shift,
65 perms: SFlag::from_bits_retain((shmflg & perms_mask) as u32 >> perms_shift),
66 flags: ShmgetFlags::from_bits_retain(shmflg & !tlb_size_mask & !perms_mask),
67 }
68 }
69
70 #[cfg(test)]
78 fn unchecked_to_shmflg(self) -> c_int {
79 self.flags.bits()
80 | (self.tlb_size_log_2 << SHM_HUGE_SHIFT) as i32
81 | self.perms.bits() as i32
82 }
83}
84
85bitflags::bitflags! {
86 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
88 pub struct ShmatFlags: i32 {
89 const SHM_RND = const_conversions::i32_from_u32(bindings::LINUX_SHM_RND);
90 const SHM_EXEC= const_conversions::i32_from_u32(bindings::LINUX_SHM_EXEC);
91 const SHM_RDONLY= const_conversions::i32_from_u32(bindings::LINUX_SHM_RDONLY);
92 const SHM_REMAP= const_conversions::i32_from_u32(bindings::LINUX_SHM_REMAP);
93 }
94}
95
96#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
98#[repr(i32)]
99#[allow(non_camel_case_types)]
100pub enum ShmctlCmd {
101 IPC_RMID = const_conversions::i32_from_u32(bindings::LINUX_IPC_RMID),
102 IPC_SET = const_conversions::i32_from_u32(bindings::LINUX_IPC_SET),
103 IPC_STAT = const_conversions::i32_from_u32(bindings::LINUX_IPC_STAT),
104 IPC_INFO = const_conversions::i32_from_u32(bindings::LINUX_IPC_INFO),
105 SHM_LOCK = const_conversions::i32_from_u32(bindings::LINUX_SHM_LOCK),
106 SHM_UNLOCK = const_conversions::i32_from_u32(bindings::LINUX_SHM_UNLOCK),
107 SHM_STAT = const_conversions::i32_from_u32(bindings::LINUX_SHM_STAT),
108 SHM_INFO = const_conversions::i32_from_u32(bindings::LINUX_SHM_INFO),
109 SHM_STAT_ANY = const_conversions::i32_from_u32(bindings::LINUX_SHM_STAT_ANY),
110}
111
112#[cfg(test)]
113mod test {
114 use super::*;
115 use crate::stat::SFlag;
116
117 fn test_shmgetflags_value_roundtrip(shmflgs: core::ffi::c_int) {
118 let parts = ShmgetFlagsParts::from_shmflg(shmflgs);
119 let shmflgs2 = parts.unchecked_to_shmflg();
120 assert_eq!(shmflgs2, shmflgs)
121 }
122
123 #[test]
124 fn test_shmgetflags_values_roundtrips() {
125 test_shmgetflags_value_roundtrip(0);
126 test_shmgetflags_value_roundtrip(0xdeadbeefu32 as i32);
127 test_shmgetflags_value_roundtrip(0xfedcba98u32 as i32);
128 test_shmgetflags_value_roundtrip(0x01234567u32 as i32);
129 test_shmgetflags_value_roundtrip(
130 (bindings::LINUX_IPC_CREAT|bindings::LINUX_IPC_EXCL|bindings::LINUX_SHM_HUGETLB|bindings::LINUX_SHM_NORESERVE) as i32
132 | bindings::LINUX_SHM_HUGE_2MB as i32
134 | (bindings::LINUX_S_IRUSR | bindings::LINUX_S_IWUSR) as i32,
136 )
137 }
138
139 #[test]
140 fn test_parse_shmgetflgs() {
141 let shmflg =
142 (bindings::LINUX_IPC_CREAT|bindings::LINUX_IPC_EXCL|bindings::LINUX_SHM_HUGETLB|bindings::LINUX_SHM_NORESERVE) as i32
144 | bindings::LINUX_SHM_HUGE_2MB as i32
146 | (bindings::LINUX_S_IRUSR | bindings::LINUX_S_IWUSR) as i32;
148 let parts = ShmgetFlagsParts::from_shmflg(shmflg);
149 assert_eq!(
150 parts.flags,
151 ShmgetFlags::IPC_CREAT
152 | ShmgetFlags::IPC_EXCL
153 | ShmgetFlags::SHM_HUGETLB
154 | ShmgetFlags::SHM_NORESERVE
155 );
156 assert_eq!(parts.tlb_size_log_2, 21);
157 assert_eq!(parts.perms, SFlag::S_IRUSR | SFlag::S_IWUSR);
158 }
159}