summaryrefslogtreecommitdiffstats
path: root/third_party/rust/whatsys/src/apple.rs
blob: 000fbe36cbfb0bfa2b508fa18ee404c3661e39d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* Based on code from sysinfo: https://crates.io/crates/sysinfo
 * Original licenses: MIT
 * Original author: Guillaume Gomez
 * License file: https://github.com/GuillaumeGomez/sysinfo/blob/master/LICENSE
 */

use libc::c_int;

fn get_system_info(value: c_int) -> Option<String> {
    let mut mib: [c_int; 2] = [libc::CTL_KERN, value];
    let mut size = 0;

    // Call first to get size
    unsafe {
        libc::sysctl(
            mib.as_mut_ptr(),
            2,
            std::ptr::null_mut(),
            &mut size,
            std::ptr::null_mut(),
            0,
        )
    };

    // exit early if we did not update the size
    if size == 0 {
        return None;
    }

    // set the buffer to the correct size
    let mut buf = vec![0_u8; size as usize];

    if unsafe {
        libc::sysctl(
            mib.as_mut_ptr(),
            2,
            buf.as_mut_ptr() as _,
            &mut size,
            std::ptr::null_mut(),
            0,
        )
    } == -1
    {
        // If command fails return default
        None
    } else {
        if let Some(pos) = buf.iter().position(|x| *x == 0) {
            // Shrink buffer to terminate the null bytes
            buf.resize(pos, 0);
        }

        String::from_utf8(buf).ok()
    }
}

/// Get the version of the currently running kernel.
///
/// Returns `None` if an error occured.
pub fn kernel_version() -> Option<String> {
    get_system_info(libc::KERN_OSRELEASE)
}