relibc/header/spawn/spawn_attr.rs
1use core::{
2 ffi::{c_int, c_short},
3 mem::zeroed,
4};
5
6use bitflags;
7
8use crate::header::{
9 bits_sigset_t::sigset_t,
10 errno::EINVAL,
11 sched::{SCHED_FIFO, SCHED_OTHER, SCHED_RR, sched_param},
12 sys_types_internal::pid_t,
13};
14
15bitflags::bitflags! {
16 pub struct Flags: c_short
17 {
18 const POSIX_SPAWN_RESETIDS = 1;
19 const POSIX_SPAWN_SETPGROUP = 2;
20 const POSIX_SPAWN_SETSIGDEF = 3;
21 const POSIX_SPAWN_SETSIGMASK = 4;
22 const POSIX_SPAWN_SETSCHEDPARAM = 5;
23 const POSIX_SPAWN_SETSCHEDULER = 6;
24 const POSIX_SPAWN_SETSID = 7;
25 }
26}
27
28pub const POSIX_SPAWN_RESETIDS: c_short = 1;
29pub const POSIX_SPAWN_SETPGROUP: c_short = 2;
30pub const POSIX_SPAWN_SETSIGDEF: c_short = 3;
31pub const POSIX_SPAWN_SETSIGMASK: c_short = 4;
32pub const POSIX_SPAWN_SETSCHEDPARAM: c_short = 5;
33pub const POSIX_SPAWN_SETSCHEDULER: c_short = 6;
34pub const POSIX_SPAWN_SETSID: c_short = 7;
35
36/// A spawn attributes object.
37#[repr(C)]
38pub struct posix_spawnattr_t {
39 pub param: sched_param,
40 pub flags: c_short,
41 pub pgroup: c_int,
42 policy: c_int,
43 pub sigdefault: sigset_t,
44 pub sigmask: sigset_t,
45}
46
47/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_init.html>.
48///
49/// Initializes a spawn attributes object `attr` with a default value for all
50/// the individual attributes used by the implementation.
51///
52/// Upon success, returns `0`. Upon failure, an error number is returned.
53///
54/// # Panics
55/// Panics if `attr` is `NULL`.
56#[unsafe(no_mangle)]
57pub extern "C" fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> c_int {
58 unsafe {
59 let attr = attr.as_mut().expect("posix_spawnattr_t cannot be NULL");
60 *attr = zeroed();
61 }
62 0
63}
64
65/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_destroy.html>.
66///
67/// Destroys a spawn attributes object.
68///
69/// Upon success, returns `0`. Upon failure, an error number is returned.
70///
71/// # Panics
72/// Panics if `attr` is `NULL`.
73///
74/// # Safety
75/// `attr` must be a pointer to `posix_spawnattr_t` and must at least be
76/// initialised.
77#[unsafe(no_mangle)]
78pub unsafe extern "C" fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> c_int {
79 unsafe {
80 // TODO should we be returning EINVAL when `attr` is invalid?
81 let attr = attr.as_mut().expect("posix_spawnattr_t cannot be NULL");
82 *attr = zeroed();
83 }
84 0
85}
86
87/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setschedparam.html>.
88///
89/// Sets the spawn-schedparam attribute in an initialized attributes object
90/// referenced by `attr`.
91///
92/// Upon success, returns `0`. Upon failure, an error number is returned.
93///
94/// # Panics
95/// Panics if `attr` or `schedparam` is `NULL`.
96///
97/// # Safety
98/// `attr` must be initialised.
99#[unsafe(no_mangle)]
100pub unsafe extern "C" fn posix_spawnattr_setschedparam(
101 attr: *mut posix_spawnattr_t,
102 schedparam: *const sched_param,
103) -> c_int {
104 // TODO should we be returning EINVAL when `attr` is invalid?
105 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
106 let schedparam = unsafe { schedparam.as_ref().expect("schedparam cannot be NULL") };
107 attr.param = *schedparam;
108 0
109}
110
111/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getschedparam.html>.
112///
113/// Obtains the value of the spawn-schedparam attribute from the attributes
114/// object referenced by `attr`.
115///
116/// Upon success, returns `0` and stores the value of the spawn-schedparam
117/// attribute of `attr` into the object referenced by `schedparam`. Upon
118/// failure, an error number is returned.
119///
120/// # Panics
121/// Panics if `attr` or `schedparam` is `NULL`.
122///
123/// # Safety
124/// `attr` must be initialised.
125#[unsafe(no_mangle)]
126pub unsafe extern "C" fn posix_spawnattr_getschedparam(
127 attr: *const posix_spawnattr_t,
128 schedparam: *mut sched_param,
129) -> c_int {
130 // TODO should we be returning EINVAL when `attr` is invalid?
131 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
132 let schedparam = unsafe { schedparam.as_mut().expect("schedparam cannot be NULL") };
133 *schedparam = attr.param;
134 0
135}
136
137/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setschedpolicy.html>.
138///
139/// Sets the spawn-schedpolicy attribute in an initialized attributes object
140/// referenced by `attr`.
141///
142/// Upon success, returns `0`. Upon failure, an error number is returned.
143///
144/// # Panics
145/// Panics if `attr` is `NULL`.
146///
147/// # Safety
148/// `attr` must be initialised.
149#[unsafe(no_mangle)]
150pub unsafe extern "C" fn posix_spawnattr_setschedpolicy(
151 attr: *mut posix_spawnattr_t,
152 schedpolicy: c_int,
153) -> c_int {
154 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
155 match schedpolicy {
156 SCHED_FIFO | SCHED_RR | SCHED_OTHER => attr.policy = schedpolicy,
157 _ => return EINVAL,
158 }
159
160 0
161}
162
163/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getschedpolicy.html>.
164///
165/// Obtains the value of the spawn-schedpolicy attribute from the attributes
166/// object referenced by `attr`.
167///
168/// Upon success, returns `0` and stores the value of the spawn-schedpolicy
169/// attribute of `attr` into the object referenced by `schedpolicy`. Upon
170/// failure, an error number is returned.
171///
172/// # Panics
173/// Panics if `attr` or `schedpolicy` is `NULL`.
174///
175/// # Safety
176/// `attr` must be initialised.
177#[unsafe(no_mangle)]
178pub unsafe extern "C" fn posix_spawnattr_getschedpolicy(
179 attr: *const posix_spawnattr_t,
180 schedpolicy: *mut c_int,
181) -> c_int {
182 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
183 let schedpolicy = unsafe { schedpolicy.as_mut().expect("schedpolicy cannot be NULL") };
184 *schedpolicy = attr.policy;
185 0
186}
187
188/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigdefault.html>.
189///
190/// Sets the spawn-sigdefault attribute in an initialized attributes object
191/// referenced by `attr`.
192///
193/// Upon success, returns `0`. Upon failure, an error number is returned.
194///
195/// # Panics
196/// Panics if `attr` or `sigdefault` is `NULL`.
197///
198/// # Safety
199/// `attr` must be initialised.
200#[unsafe(no_mangle)]
201pub unsafe extern "C" fn posix_spawnattr_setsigdefault(
202 attr: *mut posix_spawnattr_t,
203 sigdefault: *const sigset_t,
204) -> c_int {
205 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
206 let sigdefault = unsafe { sigdefault.as_ref().expect("sigdefault cannot be NULL") };
207 attr.sigdefault = *sigdefault;
208 0
209}
210
211/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigdefault.html>.
212///
213/// Obtains the value of the spawn-sigdefault attribute from the attributes
214/// object referenced by `attr`.
215///
216/// Upon success, returns `0` and stores the value of the spawn-sigdefault
217/// attribute of `attr` into the object referenced by `sigdefault`. Upon
218/// failure, an error number is returned.
219///
220/// # Panics
221/// Panics if `attr` or `sigdefault` is `NULL`.
222///
223/// # Safety
224/// `attr` must be initialised.
225#[unsafe(no_mangle)]
226pub unsafe extern "C" fn posix_spawnattr_getsigdefault(
227 attr: *const posix_spawnattr_t,
228 sigdefault: *mut sigset_t,
229) -> c_int {
230 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
231 let sigdefault = unsafe { sigdefault.as_mut().expect("sigdefault cannot be NULL") };
232 *sigdefault = attr.sigdefault;
233 0
234}
235
236/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigmask.html>.
237///
238/// Sets the spawn-sigmask attribute in an initialized attributes object
239/// referenced by `attr`.
240///
241/// Upon success, returns `0`. Upon failure, an error number is returned.
242///
243/// # Panics
244/// Panics if `attr` or `sigmask` is `NULL`.
245///
246/// # Safety
247/// `attr` must be initialised.
248#[unsafe(no_mangle)]
249pub unsafe extern "C" fn posix_spawnattr_setsigmask(
250 attr: *mut posix_spawnattr_t,
251 sigmask: *const sigset_t,
252) -> c_int {
253 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
254 let sigmask = unsafe { sigmask.as_ref().expect("sigmask cannot be NULL") };
255 attr.sigmask = *sigmask;
256 0
257}
258
259/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigmask.html>.
260///
261/// Obtains the value of the spawn-sigmask attribute from the attributes
262/// object referenced by `attr`.
263///
264/// Upon success, returns `0` and stores the value of the spawn-sigmask
265/// attribute of `attr` into the object referenced by `sigmask`. Upon
266/// failure, an error number is returned.
267///
268/// # Panics
269/// Panics if `attr` or `sigmask` is `NULL`.
270///
271/// # Safety
272/// `attr` must be initialised.
273#[unsafe(no_mangle)]
274pub unsafe extern "C" fn posix_spawnattr_getsigmask(
275 attr: *const posix_spawnattr_t,
276 sigmask: *mut sigset_t,
277) -> c_int {
278 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
279 let sigmask = unsafe { sigmask.as_mut().expect("sigmask cannot be NULL") };
280 *sigmask = attr.sigmask;
281 0
282}
283
284/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setflags.html>.
285///
286/// Sets the spawn-flags attribute in an initialized attributes object
287/// referenced by `attr`.
288///
289/// Upon success, returns `0`. Upon failure, an error number is returned.
290///
291/// # Panics
292/// Panics if `attr` is `NULL`.
293///
294/// # Safety
295/// `attr` must be initialised.
296#[unsafe(no_mangle)]
297pub unsafe extern "C" fn posix_spawnattr_setflags(
298 attr: *mut posix_spawnattr_t,
299 flags: c_short,
300) -> c_int {
301 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
302 match Flags::from_bits(flags) {
303 Some(v) => attr.flags = v.bits(),
304 None => {
305 return EINVAL;
306 }
307 }
308
309 0
310}
311
312/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getflags.html>.
313///
314/// Obtains the value of the spawn-flags attribute from the attributes
315/// object referenced by `attr`.
316///
317/// Upon success, returns `0` and stores the value of the spawn-flags
318/// attribute of `attr` into the object referenced by `flags`. Upon
319/// failure, an error number is returned.
320///
321/// # Panics
322/// Panics if `attr` or `flags` is `NULL`.
323///
324/// # Safety
325/// `attr` must be initialised.
326#[unsafe(no_mangle)]
327pub unsafe extern "C" fn posix_spawnattr_getflags(
328 attr: *const posix_spawnattr_t,
329 flags: *mut c_short,
330) -> c_int {
331 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
332 let flags = unsafe { flags.as_mut().expect("flags cannot be NULL") };
333
334 *flags = attr.flags;
335 0
336}
337
338/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setpgroup.html>.
339///
340/// Sets the spawn-pgroup attribute in an initialized attributes object
341/// referenced by `attr`.
342///
343/// Upon success, returns `0`. Upon failure, an error number is returned.
344///
345/// # Panics
346/// Panics if `attr` is `NULL`.
347///
348/// # Safety
349/// `attr` must be initialised.
350#[unsafe(no_mangle)]
351pub unsafe extern "C" fn posix_spawnattr_setpgroup(
352 attr: *mut posix_spawnattr_t,
353 pgroup: pid_t,
354) -> c_int {
355 let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
356 attr.pgroup = pgroup;
357 0
358}
359
360/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getpgroup.html>.
361///
362/// Obtains the value of the spawn-pgroup attribute from the attributes
363/// object referenced by `attr`.
364///
365/// Upon success, returns `0` and stores the value of the spawn-pgroup
366/// attribute of `attr` into the object referenced by `pgroup`. Upon
367/// failure, an error number is returned.
368///
369/// # Panics
370/// Panics if `attr` or `pgroup` is `NULL`.
371///
372/// # Safety
373/// `attr` must be initialised.
374#[unsafe(no_mangle)]
375pub unsafe extern "C" fn posix_spawnattr_getpgroup(
376 attr: *const posix_spawnattr_t,
377 pgroup: *mut pid_t,
378) -> c_int {
379 let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
380 let pgroup = unsafe { pgroup.as_mut().expect("pgroup cannot be NULL") };
381 *pgroup = attr.pgroup;
382 0
383}