Skip to content

Commit 28e9665

Browse files
Add rustix::process::exit to terminate processes
1 parent c700ad7 commit 28e9665

File tree

4 files changed

+52
-7
lines changed

4 files changed

+52
-7
lines changed

Diff for: src/backend/libc/process/syscalls.rs

+11
Original file line numberDiff line numberDiff line change
@@ -742,3 +742,14 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> {
742742

743743
unsafe { ret_usize(c::getgroups(len, buf.as_mut_ptr().cast()) as isize) }
744744
}
745+
746+
#[inline]
747+
pub(crate) fn _exit(status: i32) -> ! {
748+
unsafe {
749+
libc::_exit(status);
750+
}
751+
#[allow(unreachable_code)]
752+
{
753+
unreachable!("_exit failed to exit the process")
754+
}
755+
}

Diff for: src/backend/linux_raw/arch/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ macro_rules! syscall_readonly {
306306
}
307307

308308
/// Like `syscall`, but indicates that the syscall does not return.
309-
#[cfg(feature = "runtime")]
309+
#[cfg(any(feature = "runtime", feature = "process"))]
310310
macro_rules! syscall_noreturn {
311311
($nr:ident, $a0:expr) => {
312312
$crate::backend::arch::choose::syscall1_noreturn(

Diff for: src/backend/linux_raw/process/syscalls.rs

+11
Original file line numberDiff line numberDiff line change
@@ -620,3 +620,14 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> {
620620
))
621621
}
622622
}
623+
624+
#[inline]
625+
pub(crate) fn _exit(status: i32) -> ! {
626+
unsafe {
627+
syscall_noreturn!(__NR_exit_group, c_int(status));
628+
};
629+
#[allow(unreachable_code)]
630+
{
631+
unreachable!("_exit failed to exit the process")
632+
}
633+
}

Diff for: src/process/exit.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::backend;
22

3-
/// `EXIT_SUCCESS` for use with [`exit`].
4-
///
5-
/// [`exit`]: std::process::exit
3+
/// `EXIT_SUCCESS` for use with [`exit`] or [`std::process::exit`].
64
///
75
/// # References
86
/// - [POSIX]
@@ -12,9 +10,7 @@ use crate::backend;
1210
/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html
1311
pub const EXIT_SUCCESS: i32 = backend::c::EXIT_SUCCESS;
1412

15-
/// `EXIT_FAILURE` for use with [`exit`].
16-
///
17-
/// [`exit`]: std::process::exit
13+
/// `EXIT_FAILURE` for use with [`exit`] or [`std::process::exit`].
1814
///
1915
/// # References
2016
/// - [POSIX]
@@ -34,3 +30,30 @@ pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE;
3430
/// [`Signal::Abort`]: crate::process::Signal::Abort
3531
#[cfg(not(any(target_os = "espidf", target_os = "wasi")))]
3632
pub const EXIT_SIGNALED_SIGABRT: i32 = backend::c::EXIT_SIGNALED_SIGABRT;
33+
34+
/// Immediately exits the process. Exiting via this function does not unwind the
35+
/// stack and does not call any further user code. This behavior is similar to
36+
/// the POSIX/C `_Exit` and `_exit` functions.
37+
///
38+
/// Notably, this function does:
39+
/// - *Not* flush any buffers, such as Rust or C standard output or files.
40+
/// - *Not* call any destructors, neither in the form of stack unwinding, nor
41+
/// any global destructors.
42+
/// - *Not* call functions registered with [`atexit`] or [`at_quick_exit`]
43+
///
44+
/// In general, most code should call [`std::process::exit`] instead, if it is
45+
/// available.
46+
///
47+
/// # References
48+
/// - [POSIX]
49+
/// - [Linux]
50+
///
51+
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html
52+
/// [Linux]: https://www.man7.org/linux/man-pages/man2/exit.2.html
53+
/// [`atexit`]: https://www.man7.org/linux/man-pages/man3/atexit.3.html
54+
/// [`at_quick_exit`]: https://en.cppreference.com/w/c/program/at_quick_exit
55+
#[doc(alias = "_exit")]
56+
#[inline]
57+
pub fn exit(status: i32) -> ! {
58+
backend::process::syscalls::_exit(status);
59+
}

0 commit comments

Comments
 (0)