Coverage Report

Created: 2024-05-20 06:38

/rust/registry/src/index.crates.io-6f17d22bba15001f/nix-0.26.2/src/features.rs
Line
Count
Source (jump to first uncovered line)
1
//! Feature tests for OS functionality
2
pub use self::os::*;
3
4
#[cfg(any(target_os = "linux", target_os = "android"))]
5
mod os {
6
    use crate::sys::utsname::uname;
7
    use crate::Result;
8
    use std::os::unix::ffi::OsStrExt;
9
10
    // Features:
11
    // * atomic cloexec on socket: 2.6.27
12
    // * pipe2: 2.6.27
13
    // * accept4: 2.6.28
14
15
    static VERS_UNKNOWN: usize = 1;
16
    static VERS_2_6_18: usize = 2;
17
    static VERS_2_6_27: usize = 3;
18
    static VERS_2_6_28: usize = 4;
19
    static VERS_3: usize = 5;
20
21
    #[inline]
22
0
    fn digit(dst: &mut usize, b: u8) {
23
0
        *dst *= 10;
24
0
        *dst += (b - b'0') as usize;
25
0
    }
26
27
0
    fn parse_kernel_version() -> Result<usize> {
28
0
        let u = uname()?;
29
30
0
        let mut curr: usize = 0;
31
0
        let mut major: usize = 0;
32
0
        let mut minor: usize = 0;
33
0
        let mut patch: usize = 0;
34
35
0
        for &b in u.release().as_bytes() {
36
0
            if curr >= 3 {
37
0
                break;
38
0
            }
39
0
40
0
            match b {
41
0
                b'.' | b'-' => {
42
0
                    curr += 1;
43
0
                }
44
0
                b'0'..=b'9' => match curr {
45
0
                    0 => digit(&mut major, b),
46
0
                    1 => digit(&mut minor, b),
47
0
                    _ => digit(&mut patch, b),
48
                },
49
0
                _ => break,
50
            }
51
        }
52
53
0
        Ok(if major >= 3 {
54
0
            VERS_3
55
0
        } else if major >= 2 {
56
0
            if minor >= 7 {
57
0
                VERS_UNKNOWN
58
0
            } else if minor >= 6 {
59
0
                if patch >= 28 {
60
0
                    VERS_2_6_28
61
0
                } else if patch >= 27 {
62
0
                    VERS_2_6_27
63
                } else {
64
0
                    VERS_2_6_18
65
                }
66
            } else {
67
0
                VERS_UNKNOWN
68
            }
69
        } else {
70
0
            VERS_UNKNOWN
71
        })
72
0
    }
73
74
0
    fn kernel_version() -> Result<usize> {
75
0
        static mut KERNEL_VERS: usize = 0;
76
0
77
0
        unsafe {
78
0
            if KERNEL_VERS == 0 {
79
0
                KERNEL_VERS = parse_kernel_version()?;
80
0
            }
81
82
0
            Ok(KERNEL_VERS)
83
        }
84
0
    }
85
86
    /// Check if the OS supports atomic close-on-exec for sockets
87
0
    pub fn socket_atomic_cloexec() -> bool {
88
0
        kernel_version()
89
0
            .map(|version| version >= VERS_2_6_27)
90
0
            .unwrap_or(false)
91
0
    }
92
93
    #[test]
94
    pub fn test_parsing_kernel_version() {
95
        assert!(kernel_version().unwrap() > 0);
96
    }
97
}
98
99
#[cfg(any(
100
        target_os = "dragonfly",    // Since ???
101
        target_os = "freebsd",      // Since 10.0
102
        target_os = "illumos",      // Since ???
103
        target_os = "netbsd",       // Since 6.0
104
        target_os = "openbsd",      // Since 5.7
105
        target_os = "redox",        // Since 1-july-2020
106
))]
107
mod os {
108
    /// Check if the OS supports atomic close-on-exec for sockets
109
    pub const fn socket_atomic_cloexec() -> bool {
110
        true
111
    }
112
}
113
114
#[cfg(any(
115
    target_os = "macos",
116
    target_os = "ios",
117
    target_os = "fuchsia",
118
    target_os = "haiku",
119
    target_os = "solaris"
120
))]
121
mod os {
122
    /// Check if the OS supports atomic close-on-exec for sockets
123
    pub const fn socket_atomic_cloexec() -> bool {
124
        false
125
    }
126
}