From 50055e10f57de5e7881d427d1097e0277672a96f Mon Sep 17 00:00:00 2001 From: Daniel Schemmel Date: Mon, 26 Aug 2024 22:23:38 +0100 Subject: [PATCH] Add `rustix::process::exit` to terminate processes --- src/backend/libc/process/syscalls.rs | 11 +++++++ src/backend/linux_raw/arch/mod.rs | 2 +- src/backend/linux_raw/process/syscalls.rs | 11 +++++++ src/process/exit.rs | 35 +++++++++++++++++++---- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/backend/libc/process/syscalls.rs b/src/backend/libc/process/syscalls.rs index efb5a77f0..a69b29e9a 100644 --- a/src/backend/libc/process/syscalls.rs +++ b/src/backend/libc/process/syscalls.rs @@ -742,3 +742,14 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result { unsafe { ret_usize(c::getgroups(len, buf.as_mut_ptr().cast()) as isize) } } + +#[inline] +pub(crate) fn _exit(status: i32) -> ! { + unsafe { + libc::_exit(status); + } + #[allow(unreachable_code)] + { + unreachable!("_exit failed to exit the process") + } +} diff --git a/src/backend/linux_raw/arch/mod.rs b/src/backend/linux_raw/arch/mod.rs index ac9e25fa7..d1380991f 100644 --- a/src/backend/linux_raw/arch/mod.rs +++ b/src/backend/linux_raw/arch/mod.rs @@ -306,7 +306,7 @@ macro_rules! syscall_readonly { } /// Like `syscall`, but indicates that the syscall does not return. -#[cfg(feature = "runtime")] +#[cfg(any(feature = "runtime", feature = "process"))] macro_rules! syscall_noreturn { ($nr:ident, $a0:expr) => { $crate::backend::arch::choose::syscall1_noreturn( diff --git a/src/backend/linux_raw/process/syscalls.rs b/src/backend/linux_raw/process/syscalls.rs index d562aab33..64225db2e 100644 --- a/src/backend/linux_raw/process/syscalls.rs +++ b/src/backend/linux_raw/process/syscalls.rs @@ -620,3 +620,14 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result { )) } } + +#[inline] +pub(crate) fn _exit(status: i32) -> ! { + unsafe { + syscall_noreturn!(__NR_exit_group, c_int(status)); + }; + #[allow(unreachable_code)] + { + unreachable!("_exit failed to exit the process") + } +} diff --git a/src/process/exit.rs b/src/process/exit.rs index 95b78c4a1..4bccf9d25 100644 --- a/src/process/exit.rs +++ b/src/process/exit.rs @@ -1,8 +1,6 @@ use crate::backend; -/// `EXIT_SUCCESS` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit +/// `EXIT_SUCCESS` for use with [`exit`] or [`std::process::exit`]. /// /// # References /// - [POSIX] @@ -12,9 +10,7 @@ use crate::backend; /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html pub const EXIT_SUCCESS: i32 = backend::c::EXIT_SUCCESS; -/// `EXIT_FAILURE` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit +/// `EXIT_FAILURE` for use with [`exit`] or [`std::process::exit`]. /// /// # References /// - [POSIX] @@ -34,3 +30,30 @@ pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE; /// [`Signal::Abort`]: crate::process::Signal::Abort #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] pub const EXIT_SIGNALED_SIGABRT: i32 = backend::c::EXIT_SIGNALED_SIGABRT; + +/// Immediately exits the process. Exiting via this function does not unwind the +/// stack and does not call any further user code. This behavior is similar to +/// the POSIX/C `_Exit` and `_exit` functions. +/// +/// Notably, this function does: +/// - *Not* flush any buffers, such as Rust or C standard output or files. +/// - *Not* call any destructors, neither in the form of stack unwinding, nor +/// any global destructors. +/// - *Not* call functions registered with [`atexit`] or [`at_quick_exit`] +/// +/// In general, most code should call [`std::process::exit`] instead, if it is +/// available. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html +/// [Linux]: https://www.man7.org/linux/man-pages/man2/exit.2.html +/// [`atexit`]: https://www.man7.org/linux/man-pages/man3/atexit.3.html +/// [`at_quick_exit`]: https://en.cppreference.com/w/c/program/at_quick_exit +#[doc(alias = "_exit")] +#[inline] +pub fn immediate_exit(status: i32) -> ! { + backend::process::syscalls::_exit(status); +}