1pub use self::os::*;
3
4#[cfg(any(target_os = "linux", target_os = "android"))]
5mod os {
6 use crate::sys::utsname::uname;
7
8 static VERS_UNKNOWN: usize = 1;
14 static VERS_2_6_18: usize = 2;
15 static VERS_2_6_27: usize = 3;
16 static VERS_2_6_28: usize = 4;
17 static VERS_3: usize = 5;
18
19 #[inline]
20 fn digit(dst: &mut usize, b: u8) {
21 *dst *= 10;
22 *dst += (b - b'0') as usize;
23 }
24
25 fn parse_kernel_version() -> usize {
26 let u = uname();
27
28 let mut curr: usize = 0;
29 let mut major: usize = 0;
30 let mut minor: usize = 0;
31 let mut patch: usize = 0;
32
33 for b in u.release().bytes() {
34 if curr >= 3 {
35 break;
36 }
37
38 match b {
39 b'.' | b'-' => {
40 curr += 1;
41 }
42 b'0'..=b'9' => {
43 match curr {
44 0 => digit(&mut major, b),
45 1 => digit(&mut minor, b),
46 _ => digit(&mut patch, b),
47 }
48 }
49 _ => break,
50 }
51 }
52
53 if major >= 3 {
54 VERS_3
55 } else if major >= 2 {
56 if minor >= 7 {
57 VERS_UNKNOWN
58 } else if minor >= 6 {
59 if patch >= 28 {
60 VERS_2_6_28
61 } else if patch >= 27 {
62 VERS_2_6_27
63 } else {
64 VERS_2_6_18
65 }
66 } else {
67 VERS_UNKNOWN
68 }
69 } else {
70 VERS_UNKNOWN
71 }
72 }
73
74 fn kernel_version() -> usize {
75 static mut KERNEL_VERS: usize = 0;
76
77 unsafe {
78 if KERNEL_VERS == 0 {
79 KERNEL_VERS = parse_kernel_version();
80 }
81
82 KERNEL_VERS
83 }
84 }
85
86 pub fn socket_atomic_cloexec() -> bool {
88 kernel_version() >= VERS_2_6_27
89 }
90
91 #[test]
92 pub fn test_parsing_kernel_version() {
93 assert!(kernel_version() > 0);
94 }
95}
96
97#[cfg(any(
98 target_os = "dragonfly", target_os = "freebsd", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", ))]
105mod os {
106 pub const fn socket_atomic_cloexec() -> bool {
108 true
109 }
110}
111
112#[cfg(any(target_os = "macos",
113 target_os = "ios",
114 target_os = "fuchsia",
115 target_os = "solaris"))]
116mod os {
117 pub const fn socket_atomic_cloexec() -> bool {
119 false
120 }
121}