utmp_classic_raw/
lib.rs

1#![allow(non_camel_case_types)]
2
3use cfg_if::cfg_if;
4use std::ffi::CStr;
5use std::os::raw::c_short;
6
7pub mod x32;
8pub mod x64;
9
10/// Record does not contain valid info (formerly known as `UT_UNKNOWN` on Linux)
11pub const EMPTY: c_short = 0;
12/// Change in system run-level (see `init(8)`)
13pub const RUN_LVL: c_short = 1;
14/// Time of system boot (in `ut_tv`)
15pub const BOOT_TIME: c_short = 2;
16/// Time after system clock change (in `ut_tv`)
17pub const NEW_TIME: c_short = 3;
18/// Time before system clock change (in `ut_tv`)
19pub const OLD_TIME: c_short = 4;
20/// Process spawned by `init(8)`
21pub const INIT_PROCESS: c_short = 5;
22/// Session leader process for user login
23pub const LOGIN_PROCESS: c_short = 6;
24/// Normal process
25pub const USER_PROCESS: c_short = 7;
26/// Terminated process
27pub const DEAD_PROCESS: c_short = 8;
28/// Not implemented
29pub const ACCOUNTING: c_short = 9;
30pub const UTMP: c_short = 10;
31
32pub const UT_LINESIZE: usize = 8;
33pub const UT_NAMESIZE: usize = 32;
34pub const UT_HOSTSIZE: usize = 256;
35
36/// Type for `ut_exit`, below
37#[repr(C)]
38#[derive(Clone, Copy, Debug)]
39pub struct exit_status {
40    /// Process termination status
41    pub e_termination: c_short,
42    /// Process exit status
43    pub e_exit: c_short,
44}
45
46cfg_if! {
47    if #[cfg(any(
48        target_arch = "x86",
49        target_arch = "x86_64",
50        target_arch = "arm",
51        target_arch = "mips",
52        target_arch = "mips64",
53        target_arch = "powerpc",
54        target_arch = "powerpc64",
55        target_arch = "riscv32",
56        target_arch = "riscv64",
57        target_arch = "sparc",
58        target_arch = "sparc64",
59        target_arch = "aarch64",
60    ))] {
61        pub use x32::*;
62    } else if #[cfg(any(
63        target_arch = "s390x",
64    ))] {
65        pub use x64::*;
66    } else {
67        compile_error!("The target platform is not supported, please help us add it.");
68    }
69}
70
71fn cstr_from_bytes(bytes: &[u8]) -> &CStr {
72    match bytes.iter().position(|b| *b == 0) {
73        // This is safe because we manually located the first zero byte above.
74        Some(pos) => unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[..=pos]) },
75        // This is safe because we manually generated this string.
76        None => unsafe { CStr::from_bytes_with_nul_unchecked("???\0".as_bytes()) },
77    }
78}
79
80