Implement spawn.h + fix VaList API for Rust 1.98 + signal.h stdint.h
spawn.h: Implement posix_spawn/posix_spawnp with file actions and spawn attributes (flags, pgroup, sigmask, sigdefault). Uses fork+exec. signal/cbindgen.toml: Add stdint.h to sys_includes for signalfd_siginfo fixed-width integer types (uint32_t, int32_t, etc.). VaList API migration for Rust 1.98.0-dev toolchain: - VaListImpl merged into VaList (core::ffi::VaList) - .arg()/.arg::<T>() renamed to .next_arg()/.next_arg::<T>() - .as_va_list() removed (parameter is already VaList) - .with_copy() replaced with .clone() - printf.rs: Fix double-dereference cast for inline VaListInner redox-rt/signal.rs: Remove unnecessary unsafe around __cpuid (safe in new nightly).
This commit is contained in:
@@ -655,7 +655,7 @@ pub fn setup_sighandler(tcb: &RtTcb, first_thread: bool) {
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
let cpuid_eax1_ecx = unsafe { core::arch::x86_64::__cpuid(1) }.ecx;
|
||||
let cpuid_eax1_ecx = core::arch::x86_64::__cpuid(1).ecx;
|
||||
CPUID_EAX1_ECX.store(cpuid_eax1_ecx, core::sync::atomic::Ordering::Relaxed);
|
||||
SUPPORTS_AVX.store(u8::from(cpuid_eax1_ecx & 1 << 28 != 0), Ordering::Relaxed);
|
||||
}
|
||||
|
||||
+12
-12
@@ -65,9 +65,9 @@ pub unsafe extern "C" fn err_set_exit(ef: ExitCallback) {
|
||||
/// # Return
|
||||
/// Does not return. Exits with `eval` as an error code.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, va_list: ...) -> ! {
|
||||
let code = Some(ERRNO.get());
|
||||
err_exit(eval, code, fmt, va_list.as_va_list())
|
||||
err_exit(eval, code, fmt, va_list)
|
||||
}
|
||||
|
||||
/// Print a user message then an error message for `code` before exiting with `eval` as a return.
|
||||
@@ -77,8 +77,8 @@ pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, mut va_list: ...)
|
||||
/// # Return
|
||||
/// Exits with `eval` as an error code.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
err_exit(eval, Some(code), fmt, va_list.as_va_list())
|
||||
pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, va_list: ...) -> ! {
|
||||
err_exit(eval, Some(code), fmt, va_list)
|
||||
}
|
||||
|
||||
/// Print a user message then exits with `eval` as a return.
|
||||
@@ -88,33 +88,33 @@ pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, mut
|
||||
/// # Return
|
||||
/// Exits with `eval` as an error code.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
err_exit(eval, None, fmt, va_list.as_va_list())
|
||||
pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, va_list: ...) -> ! {
|
||||
err_exit(eval, None, fmt, va_list)
|
||||
}
|
||||
|
||||
/// Print a user message and then an error message for [`ERRNO`].
|
||||
///
|
||||
/// The message format is `progname: fmt: strerror(ERRNO)`
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warn(fmt: *const c_char, mut va_list: ...) {
|
||||
pub unsafe extern "C" fn warn(fmt: *const c_char, va_list: ...) {
|
||||
let code = Some(ERRNO.get());
|
||||
display_message(code, fmt, va_list.as_va_list());
|
||||
display_message(code, fmt, va_list);
|
||||
}
|
||||
|
||||
/// Print a user message then an error message for `code`.
|
||||
///
|
||||
/// The message format is `progname: fmt: strerror(code)`
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warnc(code: c_int, fmt: *const c_char, mut va_list: ...) {
|
||||
display_message(Some(code), fmt, va_list.as_va_list());
|
||||
pub unsafe extern "C" fn warnc(code: c_int, fmt: *const c_char, va_list: ...) {
|
||||
display_message(Some(code), fmt, va_list);
|
||||
}
|
||||
|
||||
/// Print a user message as a warning.
|
||||
///
|
||||
/// The message format is `progname: fmt`
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warnx(fmt: *const c_char, mut va_list: ...) {
|
||||
display_message(None, fmt, va_list.as_va_list());
|
||||
pub unsafe extern "C" fn warnx(fmt: *const c_char, va_list: ...) {
|
||||
display_message(None, fmt, va_list);
|
||||
}
|
||||
|
||||
/// See [`err`].
|
||||
|
||||
@@ -71,7 +71,7 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
||||
// c_ulonglong
|
||||
let arg = match cmd {
|
||||
F_DUPFD | F_SETFD | F_SETFL | F_GETLK | F_SETLK | F_SETLKW | F_OFD_GETLK | F_OFD_SETLK
|
||||
| F_OFD_SETLKW | F_DUPFD_CLOEXEC => unsafe { __valist.arg::<c_ulonglong>() },
|
||||
| F_OFD_SETLKW | F_DUPFD_CLOEXEC => unsafe { __valist.next_arg::<c_ulonglong>() },
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
@@ -112,7 +112,7 @@ pub unsafe extern "C" fn openat(
|
||||
let mode = if oflag & O_CREAT == O_CREAT
|
||||
/* || oflag & O_TMPFILE == O_TMPFILE */
|
||||
{
|
||||
unsafe { __valist.arg::<mode_t>() }
|
||||
unsafe { __valist.next_arg::<mode_t>() }
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
+1
-1
@@ -76,7 +76,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)
|
||||
// stdarg.h implemented in C
|
||||
// stdatomic.h implemented in C
|
||||
|
||||
@@ -122,7 +122,7 @@ pub unsafe extern "C" fn strfmon(
|
||||
Some('i') => {
|
||||
// International formatting
|
||||
flags.international = true;
|
||||
let value = unsafe { args.arg::<f64>() }; // Get the argument as f64
|
||||
let value = unsafe { args.next_arg::<f64>() }; // Get the argument as f64
|
||||
if let Some(written) =
|
||||
format_monetary(&mut buffer[pos..], value, &DEFAULT_MONETARY, &flags)
|
||||
{
|
||||
@@ -133,7 +133,7 @@ pub unsafe extern "C" fn strfmon(
|
||||
}
|
||||
Some('n') => {
|
||||
// Locale-specific formatting
|
||||
let value = unsafe { args.arg::<f64>() }; // Get the argument as f64
|
||||
let value = unsafe { args.next_arg::<f64>() }; // Get the argument as f64
|
||||
if let Some(written) =
|
||||
format_monetary(&mut buffer[pos..], value, &DEFAULT_MONETARY, &flags)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
sys_includes = ["sys/types.h", "signal.h", "sched.h"]
|
||||
include_guard = "_RELIBC_SPAWN_H"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
no_includes = true
|
||||
cpp_compat = true
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
|
||||
[export]
|
||||
include = [
|
||||
"posix_spawn_file_actions_t",
|
||||
"posix_spawnattr_t",
|
||||
"POSIX_SPAWN_RESETIDS",
|
||||
"POSIX_SPAWN_SETPGROUP",
|
||||
"POSIX_SPAWN_SETSIGDEF",
|
||||
"POSIX_SPAWN_SETSIGMASK",
|
||||
"POSIX_SPAWN_SETSCHEDULER",
|
||||
"POSIX_SPAWN_SETSCHEDPARAM",
|
||||
]
|
||||
@@ -0,0 +1,625 @@
|
||||
// POSIX spawn.h implementation
|
||||
// Spec: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/spawn.h.html
|
||||
//
|
||||
// posix_spawn / posix_spawnp are implemented as fork + file actions + exec.
|
||||
// File actions and spawn attributes are stored in opaque buffers embedded
|
||||
// directly in the public types (no heap indirection for the struct itself;
|
||||
// action entries use a linked list allocated on the heap).
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::ffi::CString;
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
header::{
|
||||
errno::EINVAL,
|
||||
signal,
|
||||
unistd,
|
||||
},
|
||||
platform::{self, Pal, Sys, types::*},
|
||||
};
|
||||
|
||||
// ─── Flags ───────────────────────────────────────────────────────────────────
|
||||
|
||||
pub const POSIX_SPAWN_RESETIDS: c_short = 0x01;
|
||||
pub const POSIX_SPAWN_SETPGROUP: c_short = 0x02;
|
||||
pub const POSIX_SPAWN_SETSIGDEF: c_short = 0x04;
|
||||
pub const POSIX_SPAWN_SETSIGMASK: c_short = 0x08;
|
||||
pub const POSIX_SPAWN_SETSCHEDULER: c_short = 0x10;
|
||||
pub const POSIX_SPAWN_SETSCHEDPARAM: c_short = 0x20;
|
||||
|
||||
// ─── Internal types ──────────────────────────────────────────────────────────
|
||||
|
||||
const ACTION_KIND_OPEN: c_int = 1;
|
||||
const ACTION_KIND_CLOSE: c_int = 2;
|
||||
const ACTION_KIND_DUP2: c_int = 3;
|
||||
|
||||
#[repr(C)]
|
||||
struct ActionNode {
|
||||
kind: c_int,
|
||||
fd: c_int,
|
||||
newfd: c_int,
|
||||
oflag: c_int,
|
||||
mode: c_int,
|
||||
path_ptr: *mut c_char,
|
||||
next: *mut ActionNode,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct ActionsInner {
|
||||
magic: u32,
|
||||
head: *mut ActionNode,
|
||||
tail: *mut ActionNode,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct AttrsInner {
|
||||
magic: u32,
|
||||
flags: c_short,
|
||||
pgroup: pid_t,
|
||||
sigdefault: c_ulonglong,
|
||||
sigmask: c_ulonglong,
|
||||
}
|
||||
|
||||
const ACTIONS_MAGIC: u32 = 0x53504641; // "SPFA"
|
||||
const ATTRS_MAGIC: u32 = 0x53504154; // "SPAT"
|
||||
|
||||
// ─── Public opaque types ─────────────────────────────────────────────────────
|
||||
// Sized to hold their respective Inner types with room to spare.
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/spawn.h.html>.
|
||||
#[repr(C)]
|
||||
pub struct posix_spawn_file_actions_t {
|
||||
__data: [u64; 8],
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/spawn.h.html>.
|
||||
#[repr(C)]
|
||||
pub struct posix_spawnattr_t {
|
||||
__data: [u64; 16],
|
||||
}
|
||||
|
||||
const _: () = assert!(mem::size_of::<ActionsInner>() <= mem::size_of::<posix_spawn_file_actions_t>());
|
||||
const _: () = assert!(mem::size_of::<AttrsInner>() <= mem::size_of::<posix_spawnattr_t>());
|
||||
|
||||
fn actions_as_inner(a: *mut posix_spawn_file_actions_t) -> *mut ActionsInner {
|
||||
a.cast()
|
||||
}
|
||||
|
||||
fn attrs_as_inner(a: *mut posix_spawnattr_t) -> *mut AttrsInner {
|
||||
a.cast()
|
||||
}
|
||||
|
||||
unsafe fn free_action_list(head: *mut ActionNode) {
|
||||
let mut cur = head;
|
||||
while !cur.is_null() {
|
||||
let node = unsafe { Box::from_raw(cur) };
|
||||
if !node.path_ptr.is_null() {
|
||||
drop(unsafe { CString::from_raw(node.path_ptr) });
|
||||
}
|
||||
cur = node.next;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── File actions API ────────────────────────────────────────────────────────
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addclose.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_init(
|
||||
actions: *mut posix_spawn_file_actions_t,
|
||||
) -> c_int {
|
||||
if actions.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = actions_as_inner(actions);
|
||||
unsafe {
|
||||
(*inner).magic = ACTIONS_MAGIC;
|
||||
(*inner).head = ptr::null_mut();
|
||||
(*inner).tail = ptr::null_mut();
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_destroy.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_destroy(
|
||||
actions: *mut posix_spawn_file_actions_t,
|
||||
) -> c_int {
|
||||
if actions.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = actions_as_inner(actions);
|
||||
unsafe {
|
||||
if (*inner).magic != ACTIONS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
free_action_list((*inner).head);
|
||||
(*inner).magic = 0;
|
||||
(*inner).head = ptr::null_mut();
|
||||
(*inner).tail = ptr::null_mut();
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addclose.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addclose(
|
||||
actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
) -> c_int {
|
||||
if actions.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = actions_as_inner(actions);
|
||||
unsafe {
|
||||
if (*inner).magic != ACTIONS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
let node = Box::into_raw(Box::new(ActionNode {
|
||||
kind: ACTION_KIND_CLOSE,
|
||||
fd,
|
||||
newfd: -1,
|
||||
oflag: 0,
|
||||
mode: 0,
|
||||
path_ptr: ptr::null_mut(),
|
||||
next: ptr::null_mut(),
|
||||
}));
|
||||
|
||||
unsafe { append_action(inner, node) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_adddup2.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_adddup2(
|
||||
actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
newfd: c_int,
|
||||
) -> c_int {
|
||||
if actions.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = actions_as_inner(actions);
|
||||
unsafe {
|
||||
if (*inner).magic != ACTIONS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
let node = Box::into_raw(Box::new(ActionNode {
|
||||
kind: ACTION_KIND_DUP2,
|
||||
fd,
|
||||
newfd,
|
||||
oflag: 0,
|
||||
mode: 0,
|
||||
path_ptr: ptr::null_mut(),
|
||||
next: ptr::null_mut(),
|
||||
}));
|
||||
|
||||
unsafe { append_action(inner, node) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addopen.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn_file_actions_addopen(
|
||||
actions: *mut posix_spawn_file_actions_t,
|
||||
fd: c_int,
|
||||
path: *const c_char,
|
||||
oflag: c_int,
|
||||
mode: mode_t,
|
||||
) -> c_int {
|
||||
if actions.is_null() || path.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = actions_as_inner(actions);
|
||||
unsafe {
|
||||
if (*inner).magic != ACTIONS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
let path_owned = CString::new(unsafe { CStr::from_ptr(path) }.to_bytes()).unwrap();
|
||||
let path_dup = CString::into_raw(path_owned);
|
||||
|
||||
let node = Box::into_raw(Box::new(ActionNode {
|
||||
kind: ACTION_KIND_OPEN,
|
||||
fd,
|
||||
newfd: -1,
|
||||
oflag,
|
||||
mode: mode as c_int,
|
||||
path_ptr: path_dup,
|
||||
next: ptr::null_mut(),
|
||||
}));
|
||||
|
||||
unsafe { append_action(inner, node) }
|
||||
}
|
||||
|
||||
unsafe fn append_action(inner: *mut ActionsInner, node: *mut ActionNode) -> c_int {
|
||||
unsafe {
|
||||
if (*inner).tail.is_null() {
|
||||
(*inner).head = node;
|
||||
} else {
|
||||
(*(*inner).tail).next = node;
|
||||
}
|
||||
(*inner).tail = node;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
// ─── Spawn attributes API ────────────────────────────────────────────────────
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_destroy.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> c_int {
|
||||
if attr.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
ptr::write_bytes(inner as *mut u8, 0, mem::size_of::<AttrsInner>());
|
||||
(*inner).magic = ATTRS_MAGIC;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_destroy.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> c_int {
|
||||
if attr.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
(*inner).magic = 0;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getflags.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getflags(
|
||||
attr: *const posix_spawnattr_t,
|
||||
flags: *mut c_short,
|
||||
) -> c_int {
|
||||
if attr.is_null() || flags.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr as *mut posix_spawnattr_t);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*flags = (*inner).flags;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setflags.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setflags(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
flags: c_short,
|
||||
) -> c_int {
|
||||
if attr.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let valid = POSIX_SPAWN_RESETIDS
|
||||
| POSIX_SPAWN_SETPGROUP
|
||||
| POSIX_SPAWN_SETSIGDEF
|
||||
| POSIX_SPAWN_SETSIGMASK
|
||||
| POSIX_SPAWN_SETSCHEDULER
|
||||
| POSIX_SPAWN_SETSCHEDPARAM;
|
||||
if (flags & !valid) != 0 {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
(*inner).flags = flags;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getpgroup.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getpgroup(
|
||||
attr: *const posix_spawnattr_t,
|
||||
pgroup: *mut pid_t,
|
||||
) -> c_int {
|
||||
if attr.is_null() || pgroup.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr as *mut posix_spawnattr_t);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*pgroup = (*inner).pgroup;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setpgroup.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setpgroup(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
pgroup: pid_t,
|
||||
) -> c_int {
|
||||
if attr.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
(*inner).pgroup = pgroup;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigmask.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getsigmask(
|
||||
attr: *const posix_spawnattr_t,
|
||||
sigmask: *mut c_ulonglong,
|
||||
) -> c_int {
|
||||
if attr.is_null() || sigmask.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr as *mut posix_spawnattr_t);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*sigmask = (*inner).sigmask;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigmask.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setsigmask(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
sigmask: *const c_ulonglong,
|
||||
) -> c_int {
|
||||
if attr.is_null() || sigmask.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
(*inner).sigmask = *sigmask;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_getsigdefault.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_getsigdefault(
|
||||
attr: *const posix_spawnattr_t,
|
||||
sigdefault: *mut c_ulonglong,
|
||||
) -> c_int {
|
||||
if attr.is_null() || sigdefault.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr as *mut posix_spawnattr_t);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*sigdefault = (*inner).sigdefault;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnattr_setsigdefault.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnattr_setsigdefault(
|
||||
attr: *mut posix_spawnattr_t,
|
||||
sigdefault: *const c_ulonglong,
|
||||
) -> c_int {
|
||||
if attr.is_null() || sigdefault.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let inner = attrs_as_inner(attr);
|
||||
unsafe {
|
||||
if (*inner).magic != ATTRS_MAGIC {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
(*inner).sigdefault = *sigdefault;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
// ─── Core spawn implementation ───────────────────────────────────────────────
|
||||
|
||||
unsafe fn do_spawn(
|
||||
path: *const c_char,
|
||||
search_path: bool,
|
||||
actions: *const posix_spawn_file_actions_t,
|
||||
attr: *const posix_spawnattr_t,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
if path.is_null() || argv.is_null() || envp.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate optional actions / attrs
|
||||
let actions_valid = actions.is_null()
|
||||
|| unsafe { (*actions_as_inner(actions as *mut _)).magic == ACTIONS_MAGIC };
|
||||
let attrs_valid = attr.is_null()
|
||||
|| unsafe { (*attrs_as_inner(attr as *mut _)).magic == ATTRS_MAGIC };
|
||||
|
||||
if !actions_valid || !attrs_valid {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read spawnattr flags
|
||||
let flags: c_short = if attr.is_null() {
|
||||
0
|
||||
} else {
|
||||
unsafe { (*attrs_as_inner(attr as *mut _)).flags }
|
||||
};
|
||||
|
||||
// Fork
|
||||
let pid = unsafe { unistd::fork() };
|
||||
if pid == -1 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if pid == 0 {
|
||||
// Child process: apply attributes and file actions, then exec
|
||||
|
||||
if flags & POSIX_SPAWN_RESETIDS != 0 {
|
||||
unistd::seteuid(unistd::getuid());
|
||||
unistd::setegid(unistd::getgid());
|
||||
}
|
||||
|
||||
if flags & POSIX_SPAWN_SETPGROUP != 0 {
|
||||
let pgrp = if attr.is_null() {
|
||||
0
|
||||
} else {
|
||||
unsafe { (*attrs_as_inner(attr as *mut _)).pgroup }
|
||||
};
|
||||
unistd::setpgid(0, pgrp);
|
||||
}
|
||||
|
||||
if flags & POSIX_SPAWN_SETSIGMASK != 0 && !attr.is_null() {
|
||||
let mask = unsafe { (*attrs_as_inner(attr as *mut _)).sigmask };
|
||||
unsafe {
|
||||
signal::sigprocmask(signal::SIG_SETMASK, &mask, ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
if flags & POSIX_SPAWN_SETSIGDEF != 0 && !attr.is_null() {
|
||||
let default_set = unsafe { (*attrs_as_inner(attr as *mut _)).sigdefault };
|
||||
let mut i = 1;
|
||||
while i < 32 {
|
||||
if (default_set & (1u64 << i)) != 0 {
|
||||
signal::signal(i, None);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if !actions.is_null() {
|
||||
let inner = actions_as_inner(actions as *mut _);
|
||||
let mut node = unsafe { (*inner).head };
|
||||
while !node.is_null() {
|
||||
let n = unsafe { &*node };
|
||||
match n.kind {
|
||||
ACTION_KIND_CLOSE => {
|
||||
unistd::close(n.fd);
|
||||
}
|
||||
ACTION_KIND_DUP2 => {
|
||||
unistd::dup2(n.fd, n.newfd);
|
||||
if n.fd != n.newfd {
|
||||
unistd::close(n.fd);
|
||||
}
|
||||
}
|
||||
ACTION_KIND_OPEN => unsafe {
|
||||
let path_cstr = CStr::from_ptr(n.path_ptr);
|
||||
if let Ok(new_fd) = Sys::open(path_cstr, n.oflag, n.mode) {
|
||||
if new_fd != n.fd {
|
||||
unistd::dup2(new_fd, n.fd);
|
||||
unistd::close(new_fd);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
node = n.next;
|
||||
}
|
||||
}
|
||||
|
||||
if search_path {
|
||||
unsafe { unistd::execvp(path, argv) };
|
||||
} else {
|
||||
unsafe { unistd::execve(path, argv, envp) };
|
||||
}
|
||||
|
||||
unistd::_exit(127);
|
||||
}
|
||||
|
||||
// ── Parent process ────────────────────────────────────────────────────────
|
||||
pid
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawn(
|
||||
pid: *mut pid_t,
|
||||
path: *const c_char,
|
||||
actions: *const posix_spawn_file_actions_t,
|
||||
attr: *const posix_spawnattr_t,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
let child = unsafe { do_spawn(path, false, actions, attr, argv, envp) };
|
||||
if child == -1 {
|
||||
return platform::ERRNO.get();
|
||||
}
|
||||
if !pid.is_null() {
|
||||
unsafe { *pid = child };
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawnp.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn posix_spawnp(
|
||||
pid: *mut pid_t,
|
||||
file: *const c_char,
|
||||
actions: *const posix_spawn_file_actions_t,
|
||||
attr: *const posix_spawnattr_t,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
let child = unsafe { do_spawn(file, true, actions, attr, argv, envp) };
|
||||
if child == -1 {
|
||||
return platform::ERRNO.get();
|
||||
}
|
||||
if !pid.is_null() {
|
||||
unsafe { *pid = child };
|
||||
}
|
||||
0
|
||||
}
|
||||
@@ -1415,7 +1415,7 @@ pub unsafe extern "C" fn fprintf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfprintf(file, format, __valist.as_va_list()) }
|
||||
unsafe { vfprintf(file, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vdprintf.html>.
|
||||
@@ -1433,7 +1433,7 @@ pub unsafe extern "C" fn vdprintf(fd: c_int, format: *const c_char, ap: va_list)
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/dprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn dprintf(fd: c_int, format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vdprintf(fd, format, __valist.as_va_list()) }
|
||||
unsafe { vdprintf(fd, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1445,7 +1445,7 @@ pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn printf(format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vfprintf(&raw mut *stdout, format, __valist.as_va_list()) }
|
||||
unsafe { vfprintf(&raw mut *stdout, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1470,7 +1470,7 @@ pub unsafe extern "C" fn asprintf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vasprintf(strp, format, __valist.as_va_list()) }
|
||||
unsafe { vasprintf(strp, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1502,7 +1502,7 @@ pub unsafe extern "C" fn snprintf(
|
||||
printf::printf(
|
||||
&mut platform::StringWriter(s.cast::<u8>(), n),
|
||||
CStr::from_ptr(format),
|
||||
__valist.as_va_list(),
|
||||
__valist,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1530,7 +1530,7 @@ pub unsafe extern "C" fn sprintf(
|
||||
printf::printf(
|
||||
&mut platform::UnsafeStringWriter(s.cast::<u8>()),
|
||||
CStr::from_ptr(format),
|
||||
__valist.as_va_list(),
|
||||
__valist,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1558,7 +1558,7 @@ pub unsafe extern "C" fn fscanf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfscanf(file, format, __valist.as_va_list()) }
|
||||
unsafe { vfscanf(file, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
|
||||
@@ -1570,7 +1570,7 @@ pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fscanf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn scanf(format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vfscanf(&raw mut *stdin, format, __valist.as_va_list()) }
|
||||
unsafe { vfscanf(&raw mut *stdin, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
|
||||
@@ -1593,7 +1593,7 @@ pub unsafe extern "C" fn sscanf(
|
||||
unsafe {
|
||||
let format = CStr::from_ptr(format);
|
||||
let s = CStr::from_ptr(s);
|
||||
scanf::scanf(s.into(), format.into(), __valist.as_va_list())
|
||||
scanf::scanf(s.into(), format.into(), __valist)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-16
@@ -127,36 +127,36 @@ impl VaArg {
|
||||
(FmtKind::Percent, _) => panic!("Can't call arg_from on %"),
|
||||
|
||||
(FmtKind::Char, IntKind::Long) | (FmtKind::Char, IntKind::LongLong) => {
|
||||
VaArg::wint_t(unsafe { ap.arg::<wint_t>() })
|
||||
VaArg::wint_t(unsafe { ap.next_arg::<wint_t>() })
|
||||
}
|
||||
|
||||
(FmtKind::Char, _)
|
||||
| (FmtKind::Unsigned, IntKind::Byte)
|
||||
| (FmtKind::Signed, IntKind::Byte) => {
|
||||
// c_int is passed but truncated to c_char
|
||||
VaArg::c_char(unsafe { ap.arg::<c_int>() } as c_char)
|
||||
VaArg::c_char(unsafe { ap.next_arg::<c_int>() } as c_char)
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Short) | (FmtKind::Signed, IntKind::Short) => {
|
||||
// c_int is passed but truncated to c_short
|
||||
VaArg::c_short(unsafe { ap.arg::<c_int>() } as c_short)
|
||||
VaArg::c_short(unsafe { ap.next_arg::<c_int>() } as c_short)
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Int) | (FmtKind::Signed, IntKind::Int) => {
|
||||
VaArg::c_int(unsafe { ap.arg::<c_int>() })
|
||||
VaArg::c_int(unsafe { ap.next_arg::<c_int>() })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Long) | (FmtKind::Signed, IntKind::Long) => {
|
||||
VaArg::c_long(unsafe { ap.arg::<c_long>() })
|
||||
VaArg::c_long(unsafe { ap.next_arg::<c_long>() })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::LongLong) | (FmtKind::Signed, IntKind::LongLong) => {
|
||||
VaArg::c_longlong(unsafe { ap.arg::<c_longlong>() })
|
||||
VaArg::c_longlong(unsafe { ap.next_arg::<c_longlong>() })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::IntMax) | (FmtKind::Signed, IntKind::IntMax) => {
|
||||
VaArg::intmax_t(unsafe { ap.arg::<intmax_t>() })
|
||||
VaArg::intmax_t(unsafe { ap.next_arg::<intmax_t>() })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::PtrDiff) | (FmtKind::Signed, IntKind::PtrDiff) => {
|
||||
VaArg::ptrdiff_t(unsafe { ap.arg::<ptrdiff_t>() })
|
||||
VaArg::ptrdiff_t(unsafe { ap.next_arg::<ptrdiff_t>() })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Size) | (FmtKind::Signed, IntKind::Size) => {
|
||||
VaArg::ssize_t(unsafe { ap.arg::<ssize_t>() })
|
||||
VaArg::ssize_t(unsafe { ap.next_arg::<ssize_t>() })
|
||||
}
|
||||
|
||||
(FmtKind::AnyNotation, IntKind::LongLong)
|
||||
@@ -165,11 +165,11 @@ impl VaArg {
|
||||
VaArg::c_longdouble(unsafe { VaArg::extract_longdouble(ap) })
|
||||
}
|
||||
(FmtKind::AnyNotation, _) | (FmtKind::Decimal, _) | (FmtKind::Scientific, _) => {
|
||||
VaArg::c_double(unsafe { ap.arg::<c_double>() })
|
||||
VaArg::c_double(unsafe { ap.next_arg::<c_double>() })
|
||||
}
|
||||
|
||||
(FmtKind::GetWritten, _) | (FmtKind::Pointer, _) | (FmtKind::String, _) => {
|
||||
VaArg::pointer(unsafe { ap.arg::<*const c_void>() })
|
||||
VaArg::pointer(unsafe { ap.next_arg::<*const c_void>() })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,7 +193,7 @@ impl VaArg {
|
||||
|
||||
let ap_impl = unsafe {
|
||||
// The double deconstruct is intended
|
||||
let ptr_to_struct = *(ap as *mut core::ffi::VaList as *mut *mut VaListImpl);
|
||||
let ptr_to_struct = (ap as *mut core::ffi::VaList as *mut VaListImpl);
|
||||
&mut *ptr_to_struct
|
||||
};
|
||||
|
||||
@@ -220,7 +220,7 @@ impl VaArg {
|
||||
|
||||
let ap_impl: &mut VaListImpl = unsafe {
|
||||
// The double deconstruct is intended
|
||||
let ptr_to_struct = *(ap as *mut core::ffi::VaList as *mut *mut VaListImpl);
|
||||
let ptr_to_struct = (ap as *mut core::ffi::VaList as *mut VaListImpl);
|
||||
&mut *ptr_to_struct
|
||||
};
|
||||
|
||||
@@ -348,13 +348,13 @@ impl VaListCache {
|
||||
// point. Reaching here means there are unused gaps in the
|
||||
// arguments. Ultimately we'll have to settle down with
|
||||
// defaulting to c_int.
|
||||
self.args.push(VaArg::c_int(unsafe { ap.arg::<c_int>() }))
|
||||
self.args.push(VaArg::c_int(unsafe { ap.next_arg::<c_int>() }))
|
||||
}
|
||||
|
||||
// Add the value to the cache
|
||||
self.args.push(match default {
|
||||
Some((fmtkind, intkind)) => unsafe { VaArg::arg_from(fmtkind, intkind, ap) },
|
||||
None => VaArg::c_int(unsafe { ap.arg::<c_int>() }),
|
||||
None => VaArg::c_int(unsafe { ap.next_arg::<c_int>() }),
|
||||
});
|
||||
|
||||
// Return the value
|
||||
@@ -774,7 +774,7 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
match num {
|
||||
Number::Next => varargs
|
||||
.args
|
||||
.push(VaArg::c_int(unsafe { ap.arg::<c_int>() })),
|
||||
.push(VaArg::c_int(unsafe { ap.next_arg::<c_int>() })),
|
||||
Number::Index(i) => {
|
||||
positional.insert(i - 1, (FmtKind::Signed, IntKind::Int));
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
n.parse::<$type>().map_err(|_| 0)?
|
||||
};
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut $type>() = n };
|
||||
unsafe { *ap.next_arg::<*mut $type>() = n };
|
||||
matched += 1;
|
||||
}
|
||||
}};
|
||||
@@ -264,7 +264,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
$type::from_str_radix(&n, radix).map_err(|_| 0)?
|
||||
};
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut $final>() = n as $final };
|
||||
unsafe { *ap.next_arg::<*mut $final>() = n as $final };
|
||||
matched += 1;
|
||||
}
|
||||
}};
|
||||
@@ -346,7 +346,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
}
|
||||
|
||||
let mut ptr: Option<*mut $type> =
|
||||
if ignore { None } else { Some(ap.arg()) };
|
||||
if ignore { None } else { Some(ap.next_arg()) };
|
||||
|
||||
while width.map(|w| w > 0).unwrap_or(true) && !character.is_whitespace()
|
||||
{
|
||||
@@ -391,7 +391,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
let ptr: Option<*mut $type> = if ignore {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { ap.arg() })
|
||||
Some(unsafe { ap.next_arg() })
|
||||
};
|
||||
|
||||
for i in 0..width.unwrap_or(1) {
|
||||
@@ -456,7 +456,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
let mut ptr: Option<*mut c_char> = if ignore {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { ap.arg() })
|
||||
Some(unsafe { ap.next_arg() })
|
||||
};
|
||||
|
||||
// While we haven't used up all the width, and it matches
|
||||
@@ -486,7 +486,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
}
|
||||
'n' => {
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut c_int>() = count as c_int };
|
||||
unsafe { *ap.next_arg::<*mut c_int>() = count as c_int };
|
||||
}
|
||||
}
|
||||
_ => return Err(-1),
|
||||
|
||||
@@ -112,7 +112,7 @@ pub unsafe extern "C" fn mremap(
|
||||
flags: c_int,
|
||||
mut __valist: ...
|
||||
) -> *mut c_void {
|
||||
let new_address = unsafe { __valist.arg::<*mut c_void>() };
|
||||
let new_address = unsafe { __valist.next_arg::<*mut c_void>() };
|
||||
match unsafe { Sys::mremap(old_address, old_size, new_size, flags, new_address) } {
|
||||
Ok(ptr) => ptr,
|
||||
Err(Errno(errno)) => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use crate::{
|
||||
error::ResultExt,
|
||||
platform::{PalPtrace, Sys, types::c_int},
|
||||
platform::{PalPtrace, Sys, types::{c_int, c_void, pid_t}},
|
||||
};
|
||||
|
||||
pub const PTRACE_TRACEME: c_int = 0;
|
||||
@@ -29,7 +29,8 @@ pub const PTRACE_SYSEMU_SINGLESTEP: c_int = 32;
|
||||
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/ptrace.2.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ptrace(request: c_int, mut __valist: ...) -> c_int {
|
||||
// Musl also just grabs the arguments from the varargs...
|
||||
unsafe { Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()) }
|
||||
.or_minus_one_errno()
|
||||
let pid = unsafe { __valist.next_arg::<pid_t>() };
|
||||
let addr = unsafe { __valist.next_arg::<*mut c_void>() };
|
||||
let data = unsafe { __valist.next_arg::<*mut c_void>() };
|
||||
unsafe { Sys::ptrace(request, pid, addr, data) }.or_minus_one_errno()
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ pub unsafe extern "C" fn vsyslog(priority: c_int, message: *const c_char, ap: Va
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn syslog(priority: c_int, message: *const c_char, mut __valist: ...) {
|
||||
unsafe { vsyslog(priority, message, __valist.as_va_list()) };
|
||||
unsafe { vsyslog(priority, message, __valist) };
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
|
||||
|
||||
+11
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
use core::{
|
||||
convert::TryFrom,
|
||||
ffi::VaListImpl,
|
||||
ffi::VaList,
|
||||
mem::{self, MaybeUninit},
|
||||
ptr, slice,
|
||||
};
|
||||
@@ -322,7 +322,7 @@ pub unsafe extern "C" fn execle(
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
with_argv(__valist, arg0, |args, mut remaining_va| {
|
||||
let envp = remaining_va.arg::<*const *mut c_char>();
|
||||
let envp = remaining_va.next_arg::<*const *mut c_char>();
|
||||
execve(path, args.as_ptr().cast(), envp)
|
||||
})
|
||||
}
|
||||
@@ -1267,16 +1267,15 @@ pub extern "C" fn vfork() -> pid_t {
|
||||
}
|
||||
|
||||
unsafe fn with_argv(
|
||||
mut va: VaListImpl,
|
||||
mut va: VaList<'_>,
|
||||
arg0: *const c_char,
|
||||
f: impl FnOnce(&[*const c_char], VaListImpl) -> c_int,
|
||||
f: impl FnOnce(&[*const c_char], VaList<'_>) -> c_int,
|
||||
) -> c_int {
|
||||
let argc = 1 + unsafe {
|
||||
va.with_copy(|mut copy| {
|
||||
core::iter::from_fn(|| Some(copy.arg::<*const c_char>()))
|
||||
.position(|p| p.is_null())
|
||||
.unwrap()
|
||||
})
|
||||
let argc = 1 + {
|
||||
let mut copy = va.clone();
|
||||
core::iter::from_fn(|| Some(unsafe { copy.next_arg::<*const c_char>() }))
|
||||
.position(|p| p.is_null())
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let mut stack: [MaybeUninit<*const c_char>; 32] = [MaybeUninit::uninit(); 32];
|
||||
@@ -1299,11 +1298,11 @@ unsafe fn with_argv(
|
||||
out[0].write(arg0);
|
||||
|
||||
for inner in out.iter_mut().take(argc).skip(1) {
|
||||
(*inner).write(unsafe { va.arg::<*const c_char>() });
|
||||
(*inner).write(unsafe { va.next_arg::<*const c_char>() });
|
||||
}
|
||||
out[argc].write(core::ptr::null());
|
||||
// NULL
|
||||
unsafe { va.arg::<*const c_char>() };
|
||||
unsafe { va.next_arg::<*const c_char>() };
|
||||
|
||||
f(unsafe { (&*out).assume_init_ref() }, va);
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ use crate::platform::types::c_long;
|
||||
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/getopt.3.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn syscall(sysno: c_long, mut args: ...) -> c_long {
|
||||
let a1 = unsafe { args.arg::<usize>() };
|
||||
let a2 = unsafe { args.arg::<usize>() };
|
||||
let a3 = unsafe { args.arg::<usize>() };
|
||||
let a4 = unsafe { args.arg::<usize>() };
|
||||
let a5 = unsafe { args.arg::<usize>() };
|
||||
let a6 = unsafe { args.arg::<usize>() };
|
||||
let a1 = unsafe { args.next_arg::<usize>() };
|
||||
let a2 = unsafe { args.next_arg::<usize>() };
|
||||
let a3 = unsafe { args.next_arg::<usize>() };
|
||||
let a4 = unsafe { args.next_arg::<usize>() };
|
||||
let a5 = unsafe { args.next_arg::<usize>() };
|
||||
let a6 = unsafe { args.next_arg::<usize>() };
|
||||
|
||||
(unsafe { sc::syscall6(sysno as usize, a1, a2, a3, a4, a5, a6) }) as c_long
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ pub unsafe extern "C" fn fwscanf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfwscanf(stream, format, __valist.as_va_list()) }
|
||||
unsafe { vfwscanf(stream, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getwc.html>.
|
||||
@@ -342,7 +342,7 @@ pub unsafe extern "C" fn swscanf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vswscanf(s, format, __valist.as_va_list()) }
|
||||
unsafe { vswscanf(s, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ungetwc.html>.
|
||||
@@ -396,7 +396,7 @@ pub unsafe extern "C" fn fwprintf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfwprintf(stream, format, __valist.as_va_list()) }
|
||||
unsafe { vfwprintf(stream, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
|
||||
@@ -408,7 +408,7 @@ pub unsafe extern "C" fn vwprintf(format: *const wchar_t, arg: va_list) -> c_int
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wprintf(format: *const wchar_t, mut __valist: ...) -> c_int {
|
||||
unsafe { vfwprintf(&raw mut *stdout, format, __valist.as_va_list()) }
|
||||
unsafe { vfwprintf(&raw mut *stdout, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
|
||||
@@ -433,7 +433,7 @@ pub unsafe extern "C" fn swprintf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vswprintf(s, n, format, __valist.as_va_list()) }
|
||||
unsafe { vswprintf(s, n, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcpcpy.html>.
|
||||
@@ -1053,7 +1053,7 @@ pub unsafe extern "C" fn vwscanf(format: *const wchar_t, __valist: va_list) -> c
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wscanf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wscanf(format: *const wchar_t, mut __valist: ...) -> c_int {
|
||||
unsafe { vfwscanf(stdin, format, __valist.as_va_list()) }
|
||||
unsafe { vfwscanf(stdin, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscasecmp.html>.
|
||||
|
||||
Reference in New Issue
Block a user