1use super::*;
3use libc::c_int;
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Default)]
7pub enum Perm
8{
9#[default]
10 ReadWrite,
11 Readonly,
12 Writeonly,
13 RX,
14 WRX,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Default)]
19pub enum Flags
20{
21#[default]
22 Shared,
23 Private,
24}
25
26impl Flags
27{
28 #[inline]
38 pub unsafe fn chain_with(self, flags: impl MapFlags) -> impl MapFlags
39 {
40 struct Chained<T: ?Sized>(Flags, T);
41
42 unsafe impl<T: ?Sized> MapFlags for Chained<T>
43 where T: MapFlags
44 {
45 #[inline(always)]
46 fn get_mmap_flags(&self) -> c_int {
47 self.0.get_flags() | self.1.get_mmap_flags()
48 }
49 }
50
51 Chained(self, flags)
52 }
53 #[inline]
58 pub const fn with_hugetlb(self, hugetlb: HugePage) -> impl MapFlags + Send + Sync + 'static
59 {
60 #[derive(Debug)]
61 struct HugeTLBFlags(Flags, HugePage);
62 unsafe impl MapFlags for HugeTLBFlags
63 {
64 #[inline(always)]
65 fn get_mmap_flags(&self) -> c_int {
66 self.0.get_flags() | self.1.compute_huge().map(MapHugeFlag::get_mask).unwrap_or(0)
67 }
68 }
69
70 HugeTLBFlags(self, hugetlb)
71 }
72}
73
74pub unsafe trait MapFlags
82{
83 fn get_mmap_flags(&self) -> c_int;
84}
85
86unsafe impl MapFlags for ()
87{
88 #[inline]
89 fn get_mmap_flags(&self) -> c_int {
90 Flags::default().get_flags()
91 }
92}
93
94unsafe impl MapFlags for Flags
95{
96 #[inline(always)]
97 fn get_mmap_flags(&self) -> c_int {
98 self.get_flags()
99 }
100}
101
102impl Flags
103{
104#[inline(always)]
105 pub(super) const fn get_flags(self) -> c_int
106 {
107 use libc::{
108 MAP_SHARED,
109 MAP_PRIVATE,
110 };
111 match self {
112 Self::Shared => MAP_SHARED,
113 Self::Private => MAP_PRIVATE,
114 }
115 }
116#[inline(always)]
117 pub(super) const fn requires_write_access(&self) -> bool
118 {
119 match self {
120 Self::Shared => true,
121 _ => false
122 }
123 }
124}
125
126impl Perm
127{
128#[inline(always)]
129 pub(super) const fn get_prot(self) -> c_int
130 {
131 use libc::{
132 PROT_READ, PROT_WRITE, PROT_EXEC,
133 };
134 match self {
135 Self::ReadWrite => PROT_READ | PROT_WRITE,
136 Self::Readonly => PROT_READ,
137 Self::Writeonly => PROT_WRITE,
138 Self::RX => PROT_READ | PROT_EXEC,
139 Self::WRX => PROT_READ | PROT_WRITE | PROT_EXEC,
140 }
141 }
142#[inline(always)]
143 pub(super) const fn open_rw(&self, flags: Flags) -> (bool, bool)
144 {
145 let wr = flags.requires_write_access();
146 match self {
147 Self::ReadWrite | Self::WRX => (true, wr),
148 Self::Readonly | Self::RX => (true, false),
149 Self::Writeonly => (false, wr),
150 }
151 }
152}
153
154#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Default)]
156pub enum Flush
157{
158#[default]
159 Wait,
160 Async,
161 Invalidate,
162 InvalidateAsync,
163}
164
165impl Flush
166{
167#[inline(always)]
168 pub(super) const fn get_ms(self) -> c_int
169 {
170 use libc::{
171 MS_SYNC, MS_ASYNC,
172 MS_INVALIDATE,
173 };
174 match self {
175 Self::Wait => MS_SYNC,
176 Self::Async => MS_ASYNC,
177 Self::Invalidate => MS_SYNC | MS_INVALIDATE,
178 Self::InvalidateAsync => MS_ASYNC | MS_INVALIDATE,
179 }
180 }
181}
182
183#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Default)]
185pub enum Advice {
186#[default]
187 Normal,
188 Sequential,
189 RandomAccess,
190}
191
192impl Advice
193{
194#[inline(always)]
195 pub(crate) const fn get_madv(self) -> c_int
196 {
197 use libc::{
198 MADV_NORMAL,
199 MADV_SEQUENTIAL,
200 MADV_RANDOM,
201 };
202 match self {
203 Self::Normal => MADV_NORMAL,
204 Self::Sequential => MADV_SEQUENTIAL,
205 Self::RandomAccess => MADV_RANDOM,
206 }
207 }
208}