1pub use self::os::*;
3
4#[cfg(any(target_os = "linux", target_os = "android"))]
5mod os {
6 use std::os::unix::ffi::OsStrExt;
7 use crate::sys::utsname::uname;
8 use crate::Result;
9
10 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 fn digit(dst: &mut usize, b: u8) {
23 *dst *= 10;
24 *dst += (b - b'0') as usize;
25 }
26
27 fn parse_kernel_version() -> Result<usize> {
28 let u = uname()?;
29
30 let mut curr: usize = 0;
31 let mut major: usize = 0;
32 let mut minor: usize = 0;
33 let mut patch: usize = 0;
34
35 for &b in u.release().as_bytes() {
36 if curr >= 3 {
37 break;
38 }
39
40 match b {
41 b'.' | b'-' => {
42 curr += 1;
43 }
44 b'0'..=b'9' => {
45 match curr {
46 0 => digit(&mut major, b),
47 1 => digit(&mut minor, b),
48 _ => digit(&mut patch, b),
49 }
50 }
51 _ => break,
52 }
53 }
54
55 Ok(if major >= 3 {
56 VERS_3
57 } else if major >= 2 {
58 if minor >= 7 {
59 VERS_UNKNOWN
60 } else if minor >= 6 {
61 if patch >= 28 {
62 VERS_2_6_28
63 } else if patch >= 27 {
64 VERS_2_6_27
65 } else {
66 VERS_2_6_18
67 }
68 } else {
69 VERS_UNKNOWN
70 }
71 } else {
72 VERS_UNKNOWN
73 })
74 }
75
76 fn kernel_version() -> Result<usize> {
77 static mut KERNEL_VERS: usize = 0;
78
79 unsafe {
80 if KERNEL_VERS == 0 {
81 KERNEL_VERS = parse_kernel_version()?;
82 }
83
84 Ok(KERNEL_VERS)
85 }
86 }
87
88 pub fn socket_atomic_cloexec() -> bool {
90 kernel_version().map(|version| version >= VERS_2_6_27).unwrap_or(false)
91 }
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", target_os = "freebsd", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", ))]
107mod os {
108 pub const fn socket_atomic_cloexec() -> bool {
110 true
111 }
112}
113
114#[cfg(any(target_os = "macos",
115 target_os = "ios",
116 target_os = "fuchsia",
117 target_os = "solaris"))]
118mod os {
119 pub const fn socket_atomic_cloexec() -> bool {
121 false
122 }
123}