Skip to main content

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}