x86_64_linux_nolibc/
process.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! A module for working with processes.
4
5use crate::eprintln;
6
7use core::arch::asm;
8use core::fmt;
9
10/// Termination
11pub trait Termination {
12    /// Is called to get the representation of the value as status code.
13    /// This status code is returned to the operating system.
14    fn report(self) -> ExitCode;
15}
16
17impl Termination for () {
18    #[inline]
19    fn report(self) -> ExitCode {
20        ExitCode::SUCCESS.report()
21    }
22}
23
24impl Termination for ExitCode {
25    #[inline]
26    fn report(self) -> ExitCode {
27        self
28    }
29}
30
31impl<E: fmt::Debug> Termination for Result<(), E> {
32    fn report(self) -> ExitCode {
33        match self {
34            Ok(()) => ().report(),
35            Err(err) => {
36                eprintln!("Error: {:?}", err);
37                ExitCode::FAILURE.report()
38            }
39        }
40    }
41}
42
43/// The ExitCode
44pub struct ExitCode(i32);
45
46impl ExitCode {
47    pub const SUCCESS: ExitCode = ExitCode(0);
48    pub const FAILURE: ExitCode = ExitCode(-1);
49}
50
51impl ExitCode {
52    #[inline]
53    pub fn to_i32(self) -> i32 {
54        self.0
55    }
56}
57
58impl From<u8> for ExitCode {
59    /// Construct an exit code from an arbitrary u8 value.
60    fn from(code: u8) -> Self {
61        ExitCode(code as _)
62    }
63}
64
65#[inline]
66pub fn exit(status: i32) -> ! {
67    #[allow(non_upper_case_globals)]
68    const SYS_exit: isize = 60;
69
70    unsafe {
71        asm!(
72            "syscall",
73            in("rax") SYS_exit,
74            in("rdi") status,
75            options(noreturn),
76        )
77    }
78}