utwt_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;
6use zerocopy::{FromBytes, FromZeroes};
7
8pub mod x32;
9pub mod x64;
10
11/// Record does not contain valid info (formerly known as `UT_UNKNOWN` on Linux)
12pub const EMPTY: c_short = 0;
13/// Change in system run-level (see `init(8)`)
14pub const RUN_LVL: c_short = 1;
15/// Time of system boot (in `ut_tv`)
16pub const BOOT_TIME: c_short = 2;
17/// Time after system clock change (in `ut_tv`)
18pub const NEW_TIME: c_short = 3;
19/// Time before system clock change (in `ut_tv`)
20pub const OLD_TIME: c_short = 4;
21/// Process spawned by `init(8)`
22pub const INIT_PROCESS: c_short = 5;
23/// Session leader process for user login
24pub const LOGIN_PROCESS: c_short = 6;
25/// Normal process
26pub const USER_PROCESS: c_short = 7;
27/// Terminated process
28pub const DEAD_PROCESS: c_short = 8;
29/// Not implemented
30pub const ACCOUNTING: c_short = 9;
31
32pub const UT_LINESIZE: usize = 32;
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, FromZeroes, FromBytes)]
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    ))] {
60        pub use x32::*;
61    } else if #[cfg(any(
62        target_arch = "aarch64",
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}