Merge branch 'spawn' into 'master'
Add support for `posix_spawn` and `posix_spawnp` (Redox OS) Closes #192 See merge request redox-os/relibc!1333
This commit is contained in:
+1
-1
@@ -126,7 +126,7 @@ pub mod setjmp;
|
||||
pub mod sgtty;
|
||||
pub mod shadow;
|
||||
pub mod signal;
|
||||
// TODO: spawn.h
|
||||
pub mod spawn;
|
||||
// TODO: stdalign.h (likely C implementation)
|
||||
pub mod stdarg;
|
||||
// stdatomic.h implemented in C
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# POSIX header spec: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/spawn.h.html
|
||||
#
|
||||
# Spec quotations relating to includes:
|
||||
# - "The <spawn.h> header shall define the mode_t and pid_t types as described in <sys/types.h>."
|
||||
# - "The <spawn.h> header shall define the sigset_t type as described in <signal.h>."
|
||||
# - "The tag sched_param shall be declared as naming an incomplete structure type, the contents of which are described in the <sched.h> header."
|
||||
# - "Inclusion of the <spawn.h> header may make visible symbols defined in the <sched.h> and <signal.h> headers."
|
||||
#
|
||||
# shed.h brings in pid_t
|
||||
# size_t would have been brought in by signal.h so we can include it here directly
|
||||
sys_includes = ["sched.h", "bits/sigset-t.h", "bits/mode-t.h", "bits/size-t.h"]
|
||||
include_guard = "_RELIBC_SPAWN_H"
|
||||
language = "C"
|
||||
cpp_compat = true
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
|
||||
[export.rename]
|
||||
"sched_param" = "struct sched_param"
|
||||
@@ -0,0 +1,221 @@
|
||||
use alloc::{ffi::CString, vec::Vec};
|
||||
use core::ptr;
|
||||
|
||||
use crate::{
|
||||
header::errno::EBADF,
|
||||
platform::types::{c_char, c_int, c_uchar, mode_t, size_t},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Action {
|
||||
Open {
|
||||
fd: c_int,
|
||||
path: CString,
|
||||
flag: c_int,
|
||||
mode: mode_t,
|
||||
},
|
||||
Close(c_int),
|
||||
Chdir(CString),
|
||||
FChdir(c_int),
|
||||
Dup2(c_int, c_int),
|
||||
}
|
||||
|
||||
struct FileActions(Vec<Action>);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct posix_spawn_file_actions_t {
|
||||
__relibc_internal_size: [c_uchar; 24],
|
||||
__relibc_internal_align: size_t,
|
||||
}
|
||||
|
||||
impl posix_spawn_file_actions_t {
|
||||
pub fn add_action(&mut self, action: Action) {
|
||||
let v = ptr::from_mut(self).cast::<FileActions>();
|
||||
unsafe {
|
||||
(*v).0.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FileActionsIter {
|
||||
actions: posix_spawn_file_actions_t,
|
||||
curr: usize,
|
||||
}
|
||||
|
||||
impl Iterator for FileActionsIter {
|
||||
type Item = Action;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let actions = unsafe {
|
||||
ptr::from_mut(&mut self.actions)
|
||||
.cast::<FileActions>()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
};
|
||||
let e = actions.0.get(self.curr)?;
|
||||
self.curr += 1;
|
||||
Some((*e).clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a posix_spawn_file_actions_t {
|
||||
type Item = Action;
|
||||
|
||||
type IntoIter = FileActionsIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
FileActionsIter {
|
||||
actions: (*self).clone(),
|
||||
curr: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_init.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn posix_spawn_file_actions_init(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
) -> c_int {
|
||||
if file_actions.is_null() {
|
||||
panic!("file_actions cannot be NULL");
|
||||
}
|
||||
let v = Vec::new();
|
||||
let actions = FileActions(v);
|
||||
unsafe {
|
||||
ptr::write(file_actions.cast::<FileActions>(), actions);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_destroy.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// If `file_actions` is not `NULL`, then it must be a pointer to a `file_actions` object that was initialised by calling `posix_spawn_file_actions_init`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_destroy(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
) -> c_int {
|
||||
if file_actions.is_null() {
|
||||
panic!("file_actions cannot be NULL");
|
||||
}
|
||||
unsafe {
|
||||
let _ = *(file_actions.cast::<FileActions>());
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addopen.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `path` must be a valid null-terminated C string.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addopen(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
path: *const c_char,
|
||||
oflag: c_int,
|
||||
mode: mode_t,
|
||||
) -> c_int {
|
||||
let file_actions = unsafe { file_actions.as_mut().expect("file_actions cannot be NULL") };
|
||||
if fd < 0 {
|
||||
return EBADF;
|
||||
}
|
||||
file_actions.add_action(Action::Open {
|
||||
fd,
|
||||
path: if path.is_null() {
|
||||
CString::new("").unwrap()
|
||||
} else {
|
||||
unsafe { CString::from_raw(path as *mut c_char) }
|
||||
},
|
||||
flag: oflag,
|
||||
mode,
|
||||
});
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addclose.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addclose(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
) -> c_int {
|
||||
let file_actions = unsafe { file_actions.as_mut().expect("file_actions cannot be NULL") };
|
||||
if fd < 0 {
|
||||
return EBADF;
|
||||
}
|
||||
file_actions.add_action(Action::Close(fd));
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` must be initialised and `path` must be a valid null-terminated C string.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addchdir(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
path: *const c_char,
|
||||
) -> c_int {
|
||||
let file_actions = unsafe { file_actions.as_mut().expect("file_actions cannot be NULL") };
|
||||
file_actions.add_action(Action::Chdir(unsafe {
|
||||
if path.is_null() {
|
||||
CString::new("").unwrap()
|
||||
} else {
|
||||
CString::from_raw(path as *mut c_char)
|
||||
}
|
||||
}));
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addfchdir.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addfchdir(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
) -> c_int {
|
||||
let file_actions = unsafe { file_actions.as_mut().expect("file_actions cannot be NULL") };
|
||||
if fd < 0 {
|
||||
return EBADF;
|
||||
}
|
||||
file_actions.add_action(Action::FChdir(fd));
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_adddup2.html>
|
||||
///
|
||||
/// Panics if `file_actions` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_adddup2(
|
||||
file_actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
new: c_int,
|
||||
) -> c_int {
|
||||
let file_actions = unsafe { file_actions.as_mut().expect("file_actions cannot be NULL") };
|
||||
if fd < 0 || new < 0 {
|
||||
return EBADF;
|
||||
}
|
||||
file_actions.add_action(Action::Dup2(fd, new));
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
//! `spawn.h` implementation
|
||||
//!
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/spawn.h.html>.
|
||||
|
||||
mod file_actions;
|
||||
mod spawn_attr;
|
||||
|
||||
use core::str::FromStr;
|
||||
|
||||
use alloc::{
|
||||
ffi::CString,
|
||||
string::{String, ToString},
|
||||
};
|
||||
pub use file_actions::{Action, posix_spawn_file_actions_t};
|
||||
pub use spawn_attr::{Flags, posix_spawnattr_t};
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
error::{Errno, Result},
|
||||
header::{
|
||||
dirent::{opendir, readdir},
|
||||
errno::{ENOENT, ENOTDIR},
|
||||
limits::PATH_MAX,
|
||||
stdlib::getenv,
|
||||
unistd::{chdir, getcwd},
|
||||
},
|
||||
iter::NulTerminated,
|
||||
platform::{
|
||||
self, ERRNO, Pal,
|
||||
types::{c_char, c_int, pid_t},
|
||||
},
|
||||
};
|
||||
|
||||
unsafe fn spawn(
|
||||
pid: Option<&mut pid_t>,
|
||||
mut program: String,
|
||||
file_actions: Option<&posix_spawn_file_actions_t>,
|
||||
spawn_attr: Option<&posix_spawnattr_t>,
|
||||
argv: NulTerminated<*mut c_char>,
|
||||
envp: Option<NulTerminated<*mut c_char>>,
|
||||
use_path: bool,
|
||||
) -> Result<()> {
|
||||
let mut original_cwd = [0 as c_char; PATH_MAX];
|
||||
assert!(
|
||||
unsafe { !getcwd(original_cwd.as_mut_ptr() as *mut c_char, PATH_MAX).is_null() },
|
||||
"Error getting cwd: {}",
|
||||
ERRNO.get()
|
||||
);
|
||||
|
||||
let mut path_path = None;
|
||||
if use_path {
|
||||
let path = unsafe { getenv(c"PATH".as_ptr()) };
|
||||
let path_env = unsafe { CStr::from_nullable_ptr(path).unwrap().to_str().unwrap() };
|
||||
let path_elements = path_env.split(':');
|
||||
let mut flag = false;
|
||||
|
||||
'a: for path_element in path_elements {
|
||||
let pe = CString::from_str(path_element).unwrap();
|
||||
let dir = if let Some(dir) =
|
||||
unsafe { opendir(pe.as_bytes_with_nul().as_ptr() as *const c_char).as_mut() }
|
||||
{
|
||||
dir
|
||||
} else if ERRNO.get() == 0 || ERRNO.get() == ENOTDIR || ERRNO.get() == ENOENT {
|
||||
continue;
|
||||
} else {
|
||||
return Err(Errno(ERRNO.get()));
|
||||
};
|
||||
|
||||
while let Some(dir_ent) = unsafe { readdir(dir).as_ref() } {
|
||||
let dir_ent_name = unsafe {
|
||||
CStr::from_ptr(dir_ent.d_name.as_ptr() as *const c_char)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
};
|
||||
if dir_ent_name == program {
|
||||
flag = true;
|
||||
program = format!("{}/{}", path_element, program);
|
||||
path_path = Some(path_element.to_string());
|
||||
break 'a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !flag {
|
||||
return Err(Errno(ENOENT));
|
||||
}
|
||||
}
|
||||
|
||||
let program = CString::from_str(program.as_str()).unwrap();
|
||||
|
||||
unsafe {
|
||||
platform::Sys::spawn(
|
||||
CStr::from_bytes_with_nul(program.as_bytes_with_nul()).unwrap(),
|
||||
file_actions,
|
||||
spawn_attr,
|
||||
argv,
|
||||
envp,
|
||||
path_path,
|
||||
)
|
||||
.map(|v| {
|
||||
if let Some(pid) = pid {
|
||||
*pid = v;
|
||||
}
|
||||
})
|
||||
.map_err(|e| {
|
||||
let status = chdir(original_cwd.as_ptr() as *const c_char);
|
||||
if status != 0 {
|
||||
panic!("Error switching back to original cwd: {}", ERRNO.get());
|
||||
}
|
||||
e
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn.html>
|
||||
///
|
||||
/// `argv` must **not** be `NULL` and must contain atleast the program name. `path` must also be **not** `NULL`. Failure to ensure any of this will result in a panic.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` and `attrp` must either be `NULL` or be pointers to properly initialised objects. Doing otherwise is undefined behaviour.
|
||||
///
|
||||
/// `path` and the elements in `argv` must be a pointers to valid null-terminated character arrays. Failure to ensure any of this will result in undefined behaviour.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn(
|
||||
pid: *mut pid_t,
|
||||
path: *const c_char,
|
||||
file_actions: *const posix_spawn_file_actions_t,
|
||||
attrp: *const posix_spawnattr_t,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
let argv = {
|
||||
if argv.is_null() {
|
||||
panic!("argv cannot be NULL")
|
||||
} else {
|
||||
if unsafe { (*argv).is_null() } {
|
||||
panic!("argv must contain the program name");
|
||||
}
|
||||
unsafe { NulTerminated::new(argv).unwrap() }
|
||||
}
|
||||
};
|
||||
let envp = unsafe { NulTerminated::new(envp) };
|
||||
let program = unsafe {
|
||||
CStr::from_ptr(path)
|
||||
.to_str()
|
||||
.expect("path cannot be NULL")
|
||||
.to_string()
|
||||
};
|
||||
|
||||
if let Err(e) = unsafe {
|
||||
spawn(
|
||||
pid.as_mut(),
|
||||
program,
|
||||
file_actions.as_ref(),
|
||||
attrp.as_ref(),
|
||||
argv,
|
||||
envp,
|
||||
false,
|
||||
)
|
||||
} {
|
||||
return e.0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnp.html>
|
||||
///
|
||||
/// `argv` must **not** be `NULL` and must contain atleast the program name. `path` must also be **not** `NULL`. Failure to ensure any of this will result in a panic.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `file_actions` and `attrp` must either be `NULL` or be pointers to properly initialised objects. Doing otherwise is undefined behaviour.
|
||||
///
|
||||
/// `path` and the elements in `argv` must be a pointers to valid null-terminated character arrays. Failure to ensure any of this will result in undefined behaviour.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnp(
|
||||
pid: *mut pid_t,
|
||||
path: *const c_char,
|
||||
file_actions: *const posix_spawn_file_actions_t,
|
||||
attrp: *const posix_spawnattr_t,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
let argv = {
|
||||
if argv.is_null() {
|
||||
panic!("argv cannot be NULL")
|
||||
} else {
|
||||
if unsafe { (*argv).is_null() } {
|
||||
panic!("argv must contain the program name");
|
||||
}
|
||||
unsafe { NulTerminated::new(argv).unwrap() }
|
||||
}
|
||||
};
|
||||
let envp = unsafe { NulTerminated::new(envp) };
|
||||
let program = unsafe {
|
||||
CStr::from_ptr(path)
|
||||
.to_str()
|
||||
.expect("path cannot be NULL")
|
||||
.to_string()
|
||||
};
|
||||
|
||||
if let Err(e) = unsafe {
|
||||
spawn(
|
||||
pid.as_mut(),
|
||||
program.clone(),
|
||||
file_actions.as_ref(),
|
||||
attrp.as_ref(),
|
||||
argv,
|
||||
envp,
|
||||
if program.contains('/') { false } else { true },
|
||||
)
|
||||
} {
|
||||
return e.0;
|
||||
}
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
use core::{
|
||||
ffi::{c_int, c_short},
|
||||
mem::zeroed,
|
||||
};
|
||||
|
||||
use bitflags;
|
||||
|
||||
use crate::header::{
|
||||
bits_sigset_t::sigset_t,
|
||||
errno::EINVAL,
|
||||
sched::{SCHED_FIFO, SCHED_OTHER, SCHED_RR, sched_param},
|
||||
sys_types_internal::pid_t,
|
||||
};
|
||||
|
||||
bitflags::bitflags! {
|
||||
pub struct Flags: c_short
|
||||
{
|
||||
const POSIX_SPAWN_RESETIDS = 1;
|
||||
const POSIX_SPAWN_SETPGROUP = 2;
|
||||
const POSIX_SPAWN_SETSIGDEF = 3;
|
||||
const POSIX_SPAWN_SETSIGMASK = 4;
|
||||
const POSIX_SPAWN_SETSCHEDPARAM = 5;
|
||||
const POSIX_SPAWN_SETSCHEDULER = 6;
|
||||
}
|
||||
}
|
||||
|
||||
pub const POSIX_SPAWN_RESETIDS: c_short = 1;
|
||||
pub const POSIX_SPAWN_SETPGROUP: c_short = 2;
|
||||
pub const POSIX_SPAWN_SETSIGDEF: c_short = 3;
|
||||
pub const POSIX_SPAWN_SETSIGMASK: c_short = 4;
|
||||
pub const POSIX_SPAWN_SETSCHEDPARAM: c_short = 5;
|
||||
pub const POSIX_SPAWN_SETSCHEDULER: c_short = 6;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct posix_spawnattr_t {
|
||||
pub param: sched_param,
|
||||
pub flags: c_short,
|
||||
pub pgroup: c_int,
|
||||
policy: c_int,
|
||||
pub sigdefault: sigset_t,
|
||||
pub sigmask: sigset_t,
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_init.html>
|
||||
///
|
||||
/// Panics is `attr` is `NULL`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> c_int {
|
||||
unsafe {
|
||||
let attr = attr.as_mut().expect("posix_spawnattr_t cannot be NULL");
|
||||
*attr = zeroed();
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_destroy.html>
|
||||
///
|
||||
/// Panics is `attr` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be a pointer to `posix_spawnattr_t` and must at least be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> c_int {
|
||||
unsafe {
|
||||
let attr = attr.as_mut().expect("posix_spawnattr_t cannot be NULL");
|
||||
*attr = zeroed();
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setschedparam.html>
|
||||
///
|
||||
/// Panics if `attr` or `schedparam` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setschedparam(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
schedparam: *const sched_param,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let schedparam = unsafe { schedparam.as_ref().expect("schedparam cannot be NULL") };
|
||||
(*attr).param = *schedparam;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getschedparam.html>
|
||||
///
|
||||
/// Panics if `attr` or `schedparam` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getschedparam(
|
||||
attr: *const posix_spawnattr_t,
|
||||
schedparam: *mut sched_param,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let schedparam = unsafe { schedparam.as_mut().expect("schedparam cannot be NULL") };
|
||||
*schedparam = (*attr).param;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setschedpolicy.html>
|
||||
///
|
||||
/// Panics if `attr` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setschedpolicy(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
schedpolicy: c_int,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
match schedpolicy {
|
||||
SCHED_FIFO | SCHED_RR | SCHED_OTHER => (*attr).policy = schedpolicy,
|
||||
_ => return EINVAL,
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getschedpolicy.html>
|
||||
///
|
||||
/// Panics if `attr` or `schedpolicy` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getschedpolicy(
|
||||
attr: *const posix_spawnattr_t,
|
||||
schedpolicy: *mut c_int,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let schedpolicy = unsafe { schedpolicy.as_mut().expect("schedpolicy cannot be NULL") };
|
||||
*schedpolicy = (*attr).policy;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigdefault.html>
|
||||
///
|
||||
/// Panics if `attr` or `sigdefault` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setsigdefault(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
sigdefault: *const sigset_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let sigdefault = unsafe { sigdefault.as_ref().expect("sigdefault cannot be NULL") };
|
||||
(*attr).sigdefault = *sigdefault;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigdefault.html>
|
||||
///
|
||||
/// Panics if `attr` or `sigdefault` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getsigdefault(
|
||||
attr: *const posix_spawnattr_t,
|
||||
sigdefault: *mut sigset_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let sigdefault = unsafe { sigdefault.as_mut().expect("sigdefault cannot be NULL") };
|
||||
*sigdefault = (*attr).sigdefault;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigmask.html>
|
||||
///
|
||||
/// Panics if `attr` or `sigmask` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setsigmask(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
sigmask: *const sigset_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let sigmask = unsafe { sigmask.as_ref().expect("sigmask cannot be NULL") };
|
||||
(*attr).sigmask = *sigmask;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigmask.html>
|
||||
///
|
||||
/// Panics if `attr` or `sigmask` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getsigmask(
|
||||
attr: *const posix_spawnattr_t,
|
||||
sigmask: *mut sigset_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let sigmask = unsafe { sigmask.as_mut().expect("sigmask cannot be NULL") };
|
||||
*sigmask = (*attr).sigmask;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setflags.html>
|
||||
///
|
||||
/// Panics if `attr` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setflags(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
flags: c_short,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
match Flags::from_bits(flags) {
|
||||
Some(v) => (*attr).flags = v.bits(),
|
||||
None => {
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getflags.html>
|
||||
///
|
||||
/// Panics if `attr` or `flags` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getflags(
|
||||
attr: *const posix_spawnattr_t,
|
||||
flags: *mut c_short,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let flags = unsafe { flags.as_mut().expect("flags cannot be NULL") };
|
||||
|
||||
*flags = (*attr).flags;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setpgroup.html>
|
||||
///
|
||||
/// Panics if `attr` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setpgroup(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
pgroup: pid_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_mut().expect("posix_spawnattr_t cannot be NULL") };
|
||||
(*attr).pgroup = pgroup;
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getpgroup.html>
|
||||
///
|
||||
/// Panics if `attr` or `pgroup` is `NULL`.
|
||||
///
|
||||
/// # Safety:
|
||||
/// `attr` must be initialised.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getpgroup(
|
||||
attr: *const posix_spawnattr_t,
|
||||
pgroup: *mut pid_t,
|
||||
) -> c_int {
|
||||
let attr = unsafe { attr.as_ref().expect("posix_spawnattr_t cannot be NULL") };
|
||||
let pgroup = unsafe { pgroup.as_mut().expect("pgroup cannot be NULL") };
|
||||
*pgroup = (*attr).pgroup;
|
||||
0
|
||||
}
|
||||
Reference in New Issue
Block a user