linux_api/
prctl.rs

1use crate::{bindings, const_conversions};
2
3/// Options for `man 2 prctl`.
4// We want to allow unknown values since newer kernel versions may add new options, and we may want
5// to gracefully handle these options (for example to pass them on to the kernel). Linux also uses
6// the same namespace ("PR_") for both options and argument flags (for example the `option`
7// `PR_SET_FP_MODE` and the bitflag arguments `PR_FP_MODE_FR` and `PR_FP_MODE_FRE` in `arg2`). We
8// don't want bitflags in this struct, so when adding new "PR_" entries, make sure they correspond
9// with prctl "options" and not "arguments".
10#[derive(PartialEq, Eq)]
11pub struct PrctlOp(i32);
12
13impl PrctlOp {
14    pub const PR_SET_PDEATHSIG: Self = Self::from_u32(bindings::LINUX_PR_SET_PDEATHSIG);
15    pub const PR_GET_PDEATHSIG: Self = Self::from_u32(bindings::LINUX_PR_GET_PDEATHSIG);
16    pub const PR_GET_DUMPABLE: Self = Self::from_u32(bindings::LINUX_PR_GET_DUMPABLE);
17    pub const PR_SET_DUMPABLE: Self = Self::from_u32(bindings::LINUX_PR_SET_DUMPABLE);
18    pub const PR_GET_UNALIGN: Self = Self::from_u32(bindings::LINUX_PR_GET_UNALIGN);
19    pub const PR_SET_UNALIGN: Self = Self::from_u32(bindings::LINUX_PR_SET_UNALIGN);
20    pub const PR_GET_KEEPCAPS: Self = Self::from_u32(bindings::LINUX_PR_GET_KEEPCAPS);
21    pub const PR_SET_KEEPCAPS: Self = Self::from_u32(bindings::LINUX_PR_SET_KEEPCAPS);
22    pub const PR_GET_FPEMU: Self = Self::from_u32(bindings::LINUX_PR_GET_FPEMU);
23    pub const PR_SET_FPEMU: Self = Self::from_u32(bindings::LINUX_PR_SET_FPEMU);
24    pub const PR_GET_FPEXC: Self = Self::from_u32(bindings::LINUX_PR_GET_FPEXC);
25    pub const PR_SET_FPEXC: Self = Self::from_u32(bindings::LINUX_PR_SET_FPEXC);
26    pub const PR_GET_TIMING: Self = Self::from_u32(bindings::LINUX_PR_GET_TIMING);
27    pub const PR_SET_TIMING: Self = Self::from_u32(bindings::LINUX_PR_SET_TIMING);
28    pub const PR_SET_NAME: Self = Self::from_u32(bindings::LINUX_PR_SET_NAME);
29    pub const PR_GET_NAME: Self = Self::from_u32(bindings::LINUX_PR_GET_NAME);
30    pub const PR_GET_ENDIAN: Self = Self::from_u32(bindings::LINUX_PR_GET_ENDIAN);
31    pub const PR_SET_ENDIAN: Self = Self::from_u32(bindings::LINUX_PR_SET_ENDIAN);
32    pub const PR_GET_SECCOMP: Self = Self::from_u32(bindings::LINUX_PR_GET_SECCOMP);
33    pub const PR_SET_SECCOMP: Self = Self::from_u32(bindings::LINUX_PR_SET_SECCOMP);
34    pub const PR_CAPBSET_READ: Self = Self::from_u32(bindings::LINUX_PR_CAPBSET_READ);
35    pub const PR_CAPBSET_DROP: Self = Self::from_u32(bindings::LINUX_PR_CAPBSET_DROP);
36    pub const PR_GET_TSC: Self = Self::from_u32(bindings::LINUX_PR_GET_TSC);
37    pub const PR_SET_TSC: Self = Self::from_u32(bindings::LINUX_PR_SET_TSC);
38    pub const PR_GET_SECUREBITS: Self = Self::from_u32(bindings::LINUX_PR_GET_SECUREBITS);
39    pub const PR_SET_SECUREBITS: Self = Self::from_u32(bindings::LINUX_PR_SET_SECUREBITS);
40    pub const PR_SET_TIMERSLACK: Self = Self::from_u32(bindings::LINUX_PR_SET_TIMERSLACK);
41    pub const PR_GET_TIMERSLACK: Self = Self::from_u32(bindings::LINUX_PR_GET_TIMERSLACK);
42    pub const PR_TASK_PERF_EVENTS_DISABLE: Self =
43        Self::from_u32(bindings::LINUX_PR_TASK_PERF_EVENTS_DISABLE);
44    pub const PR_TASK_PERF_EVENTS_ENABLE: Self =
45        Self::from_u32(bindings::LINUX_PR_TASK_PERF_EVENTS_ENABLE);
46    pub const PR_MCE_KILL: Self = Self::from_u32(bindings::LINUX_PR_MCE_KILL);
47    pub const PR_SET_MM: Self = Self::from_u32(bindings::LINUX_PR_SET_MM);
48    pub const PR_MCE_KILL_GET: Self = Self::from_u32(bindings::LINUX_PR_MCE_KILL_GET);
49    pub const PR_SET_PTRACER: Self = Self::from_u32(bindings::LINUX_PR_SET_PTRACER);
50    pub const PR_SET_CHILD_SUBREAPER: Self = Self::from_u32(bindings::LINUX_PR_SET_CHILD_SUBREAPER);
51    pub const PR_GET_CHILD_SUBREAPER: Self = Self::from_u32(bindings::LINUX_PR_GET_CHILD_SUBREAPER);
52    pub const PR_SET_NO_NEW_PRIVS: Self = Self::from_u32(bindings::LINUX_PR_SET_NO_NEW_PRIVS);
53    pub const PR_GET_NO_NEW_PRIVS: Self = Self::from_u32(bindings::LINUX_PR_GET_NO_NEW_PRIVS);
54    pub const PR_GET_TID_ADDRESS: Self = Self::from_u32(bindings::LINUX_PR_GET_TID_ADDRESS);
55    pub const PR_SET_THP_DISABLE: Self = Self::from_u32(bindings::LINUX_PR_SET_THP_DISABLE);
56    pub const PR_GET_THP_DISABLE: Self = Self::from_u32(bindings::LINUX_PR_GET_THP_DISABLE);
57    pub const PR_MPX_ENABLE_MANAGEMENT: Self =
58        Self::from_u32(bindings::LINUX_PR_MPX_ENABLE_MANAGEMENT);
59    pub const PR_MPX_DISABLE_MANAGEMENT: Self =
60        Self::from_u32(bindings::LINUX_PR_MPX_DISABLE_MANAGEMENT);
61    pub const PR_SET_FP_MODE: Self = Self::from_u32(bindings::LINUX_PR_SET_FP_MODE);
62    pub const PR_GET_FP_MODE: Self = Self::from_u32(bindings::LINUX_PR_GET_FP_MODE);
63    pub const PR_CAP_AMBIENT: Self = Self::from_u32(bindings::LINUX_PR_CAP_AMBIENT);
64    pub const PR_SVE_SET_VL: Self = Self::from_u32(bindings::LINUX_PR_SVE_SET_VL);
65    pub const PR_SVE_GET_VL: Self = Self::from_u32(bindings::LINUX_PR_SVE_GET_VL);
66    pub const PR_GET_SPECULATION_CTRL: Self =
67        Self::from_u32(bindings::LINUX_PR_GET_SPECULATION_CTRL);
68    pub const PR_SET_SPECULATION_CTRL: Self =
69        Self::from_u32(bindings::LINUX_PR_SET_SPECULATION_CTRL);
70    pub const PR_PAC_RESET_KEYS: Self = Self::from_u32(bindings::LINUX_PR_PAC_RESET_KEYS);
71    pub const PR_SET_TAGGED_ADDR_CTRL: Self =
72        Self::from_u32(bindings::LINUX_PR_SET_TAGGED_ADDR_CTRL);
73    pub const PR_GET_TAGGED_ADDR_CTRL: Self =
74        Self::from_u32(bindings::LINUX_PR_GET_TAGGED_ADDR_CTRL);
75    pub const PR_SET_IO_FLUSHER: Self = Self::from_u32(bindings::LINUX_PR_SET_IO_FLUSHER);
76    pub const PR_GET_IO_FLUSHER: Self = Self::from_u32(bindings::LINUX_PR_GET_IO_FLUSHER);
77    pub const PR_SET_SYSCALL_USER_DISPATCH: Self =
78        Self::from_u32(bindings::LINUX_PR_SET_SYSCALL_USER_DISPATCH);
79    pub const PR_PAC_SET_ENABLED_KEYS: Self =
80        Self::from_u32(bindings::LINUX_PR_PAC_SET_ENABLED_KEYS);
81    pub const PR_PAC_GET_ENABLED_KEYS: Self =
82        Self::from_u32(bindings::LINUX_PR_PAC_GET_ENABLED_KEYS);
83    pub const PR_SCHED_CORE: Self = Self::from_u32(bindings::LINUX_PR_SCHED_CORE);
84    pub const PR_SME_SET_VL: Self = Self::from_u32(bindings::LINUX_PR_SME_SET_VL);
85    pub const PR_SME_GET_VL: Self = Self::from_u32(bindings::LINUX_PR_SME_GET_VL);
86    pub const PR_SET_MDWE: Self = Self::from_u32(bindings::LINUX_PR_SET_MDWE);
87    pub const PR_GET_MDWE: Self = Self::from_u32(bindings::LINUX_PR_GET_MDWE);
88    pub const PR_SET_VMA: Self = Self::from_u32(bindings::LINUX_PR_SET_VMA);
89    pub const PR_GET_AUXV: Self = Self::from_u32(bindings::LINUX_PR_GET_AUXV);
90    pub const PR_SET_MEMORY_MERGE: Self = Self::from_u32(bindings::LINUX_PR_SET_MEMORY_MERGE);
91    pub const PR_GET_MEMORY_MERGE: Self = Self::from_u32(bindings::LINUX_PR_GET_MEMORY_MERGE);
92    pub const PR_RISCV_V_SET_CONTROL: Self = Self::from_u32(bindings::LINUX_PR_RISCV_V_SET_CONTROL);
93    pub const PR_RISCV_V_GET_CONTROL: Self = Self::from_u32(bindings::LINUX_PR_RISCV_V_GET_CONTROL);
94    pub const PR_RISCV_SET_ICACHE_FLUSH_CTX: Self =
95        Self::from_u32(bindings::LINUX_PR_RISCV_SET_ICACHE_FLUSH_CTX);
96    pub const PR_PPC_GET_DEXCR: Self = Self::from_u32(bindings::LINUX_PR_PPC_GET_DEXCR);
97    pub const PR_PPC_SET_DEXCR: Self = Self::from_u32(bindings::LINUX_PR_PPC_SET_DEXCR);
98    // NOTE: only add prctl options here (not prctl args), and add new entries to `to_str` below
99
100    pub const fn new(val: i32) -> Self {
101        Self(val)
102    }
103
104    pub const fn val(&self) -> i32 {
105        self.0
106    }
107
108    const fn from_u32(val: u32) -> Self {
109        Self::new(const_conversions::i32_from_u32(val))
110    }
111
112    pub const fn to_str(&self) -> Option<&'static str> {
113        match *self {
114            Self::PR_SET_PDEATHSIG => Some("PR_SET_PDEATHSIG"),
115            Self::PR_GET_PDEATHSIG => Some("PR_GET_PDEATHSIG"),
116            Self::PR_GET_DUMPABLE => Some("PR_GET_DUMPABLE"),
117            Self::PR_SET_DUMPABLE => Some("PR_SET_DUMPABLE"),
118            Self::PR_GET_UNALIGN => Some("PR_GET_UNALIGN"),
119            Self::PR_SET_UNALIGN => Some("PR_SET_UNALIGN"),
120            Self::PR_GET_KEEPCAPS => Some("PR_GET_KEEPCAPS"),
121            Self::PR_SET_KEEPCAPS => Some("PR_SET_KEEPCAPS"),
122            Self::PR_GET_FPEMU => Some("PR_GET_FPEMU"),
123            Self::PR_SET_FPEMU => Some("PR_SET_FPEMU"),
124            Self::PR_GET_FPEXC => Some("PR_GET_FPEXC"),
125            Self::PR_SET_FPEXC => Some("PR_SET_FPEXC"),
126            Self::PR_GET_TIMING => Some("PR_GET_TIMING"),
127            Self::PR_SET_TIMING => Some("PR_SET_TIMING"),
128            Self::PR_SET_NAME => Some("PR_SET_NAME"),
129            Self::PR_GET_NAME => Some("PR_GET_NAME"),
130            Self::PR_GET_ENDIAN => Some("PR_GET_ENDIAN"),
131            Self::PR_SET_ENDIAN => Some("PR_SET_ENDIAN"),
132            Self::PR_GET_SECCOMP => Some("PR_GET_SECCOMP"),
133            Self::PR_SET_SECCOMP => Some("PR_SET_SECCOMP"),
134            Self::PR_CAPBSET_READ => Some("PR_CAPBSET_READ"),
135            Self::PR_CAPBSET_DROP => Some("PR_CAPBSET_DROP"),
136            Self::PR_GET_TSC => Some("PR_GET_TSC"),
137            Self::PR_SET_TSC => Some("PR_SET_TSC"),
138            Self::PR_GET_SECUREBITS => Some("PR_GET_SECUREBITS"),
139            Self::PR_SET_SECUREBITS => Some("PR_SET_SECUREBITS"),
140            Self::PR_SET_TIMERSLACK => Some("PR_SET_TIMERSLACK"),
141            Self::PR_GET_TIMERSLACK => Some("PR_GET_TIMERSLACK"),
142            Self::PR_TASK_PERF_EVENTS_DISABLE => Some("PR_TASK_PERF_EVENTS_DISABLE"),
143            Self::PR_TASK_PERF_EVENTS_ENABLE => Some("PR_TASK_PERF_EVENTS_ENABLE"),
144            Self::PR_MCE_KILL => Some("PR_MCE_KILL"),
145            Self::PR_SET_MM => Some("PR_SET_MM"),
146            Self::PR_SET_PTRACER => Some("PR_SET_PTRACER"),
147            Self::PR_SET_CHILD_SUBREAPER => Some("PR_SET_CHILD_SUBREAPER"),
148            Self::PR_GET_CHILD_SUBREAPER => Some("PR_GET_CHILD_SUBREAPER"),
149            Self::PR_SET_NO_NEW_PRIVS => Some("PR_SET_NO_NEW_PRIVS"),
150            Self::PR_GET_NO_NEW_PRIVS => Some("PR_GET_NO_NEW_PRIVS"),
151            Self::PR_GET_TID_ADDRESS => Some("PR_GET_TID_ADDRESS"),
152            Self::PR_SET_THP_DISABLE => Some("PR_SET_THP_DISABLE"),
153            Self::PR_GET_THP_DISABLE => Some("PR_GET_THP_DISABLE"),
154            Self::PR_MPX_ENABLE_MANAGEMENT => Some("PR_MPX_ENABLE_MANAGEMENT"),
155            Self::PR_MPX_DISABLE_MANAGEMENT => Some("PR_MPX_DISABLE_MANAGEMENT"),
156            Self::PR_SET_FP_MODE => Some("PR_SET_FP_MODE"),
157            Self::PR_GET_FP_MODE => Some("PR_GET_FP_MODE"),
158            Self::PR_CAP_AMBIENT => Some("PR_CAP_AMBIENT"),
159            Self::PR_SVE_SET_VL => Some("PR_SVE_SET_VL"),
160            Self::PR_SVE_GET_VL => Some("PR_SVE_GET_VL"),
161            Self::PR_GET_SPECULATION_CTRL => Some("PR_GET_SPECULATION_CTRL"),
162            Self::PR_SET_SPECULATION_CTRL => Some("PR_SET_SPECULATION_CTRL"),
163            Self::PR_PAC_RESET_KEYS => Some("PR_PAC_RESET_KEYS"),
164            Self::PR_SET_TAGGED_ADDR_CTRL => Some("PR_SET_TAGGED_ADDR_CTRL"),
165            Self::PR_GET_TAGGED_ADDR_CTRL => Some("PR_GET_TAGGED_ADDR_CTRL"),
166            Self::PR_SET_IO_FLUSHER => Some("PR_SET_IO_FLUSHER"),
167            Self::PR_GET_IO_FLUSHER => Some("PR_GET_IO_FLUSHER"),
168            Self::PR_SET_SYSCALL_USER_DISPATCH => Some("PR_SET_SYSCALL_USER_DISPATCH"),
169            Self::PR_PAC_SET_ENABLED_KEYS => Some("PR_PAC_SET_ENABLED_KEYS"),
170            Self::PR_PAC_GET_ENABLED_KEYS => Some("PR_PAC_GET_ENABLED_KEYS"),
171            Self::PR_SCHED_CORE => Some("PR_SCHED_CORE"),
172            Self::PR_SME_SET_VL => Some("PR_SME_SET_VL"),
173            Self::PR_SME_GET_VL => Some("PR_SME_GET_VL"),
174            Self::PR_SET_MDWE => Some("PR_SET_MDWE"),
175            Self::PR_GET_MDWE => Some("PR_GET_MDWE"),
176            Self::PR_SET_VMA => Some("PR_SET_VMA"),
177            Self::PR_GET_AUXV => Some("PR_GET_AUXV"),
178            Self::PR_SET_MEMORY_MERGE => Some("PR_SET_MEMORY_MERGE"),
179            Self::PR_GET_MEMORY_MERGE => Some("PR_GET_MEMORY_MERGE"),
180            Self::PR_RISCV_V_SET_CONTROL => Some("PR_RISCV_V_SET_CONTROL"),
181            Self::PR_RISCV_V_GET_CONTROL => Some("PR_RISCV_V_GET_CONTROL"),
182            Self::PR_RISCV_SET_ICACHE_FLUSH_CTX => Some("PR_RISCV_SET_ICACHE_FLUSH_CTX"),
183            Self::PR_PPC_GET_DEXCR => Some("PR_PPC_GET_DEXCR"),
184            Self::PR_PPC_SET_DEXCR => Some("PR_PPC_SET_DEXCR"),
185            _ => None,
186        }
187    }
188}
189
190impl core::fmt::Display for PrctlOp {
191    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
192        match self.to_str() {
193            Some(s) => formatter.write_str(s),
194            None => write!(formatter, "(unknown prctl option {})", self.0),
195        }
196    }
197}
198
199impl core::fmt::Debug for PrctlOp {
200    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
201        match self.to_str() {
202            Some(s) => write!(formatter, "PrctlOp::{s}"),
203            None => write!(formatter, "PrctlOp::<{}>", self.0),
204        }
205    }
206}
207
208impl From<PrctlOp> for i32 {
209    #[inline]
210    fn from(val: PrctlOp) -> Self {
211        val.0
212    }
213}
214
215impl From<i32> for PrctlOp {
216    #[inline]
217    fn from(val: i32) -> Self {
218        Self::new(val)
219    }
220}