1pub use self::os::*;
3
4#[cfg(linux_android)]
5mod os {
6 use crate::sys::utsname::uname;
7 use crate::Result;
8 use std::os::unix::ffi::OsStrExt;
9 use std::sync::atomic::{AtomicUsize, Ordering};
10
11 static VERS_UNKNOWN: usize = 1;
17 static VERS_2_6_18: usize = 2;
18 static VERS_2_6_27: usize = 3;
19 static VERS_2_6_28: usize = 4;
20 static VERS_3: usize = 5;
21
22 #[inline]
23 fn digit(dst: &mut usize, b: u8) {
24 *dst *= 10;
25 *dst += (b - b'0') as usize;
26 }
27
28 fn parse_kernel_version() -> Result<usize> {
29 let u = uname()?;
30
31 let mut curr: usize = 0;
32 let mut major: usize = 0;
33 let mut minor: usize = 0;
34 let mut patch: usize = 0;
35
36 for &b in u.release().as_bytes() {
37 if curr >= 3 {
38 break;
39 }
40
41 match b {
42 b'.' | b'-' => {
43 curr += 1;
44 }
45 b'0'..=b'9' => match curr {
46 0 => digit(&mut major, b),
47 1 => digit(&mut minor, b),
48 _ => digit(&mut patch, b),
49 },
50 _ => break,
51 }
52 }
53
54 Ok(if major >= 3 {
55 VERS_3
56 } else if major >= 2 {
57 if minor >= 7 {
58 VERS_UNKNOWN
59 } else if minor >= 6 {
60 if patch >= 28 {
61 VERS_2_6_28
62 } else if patch >= 27 {
63 VERS_2_6_27
64 } else {
65 VERS_2_6_18
66 }
67 } else {
68 VERS_UNKNOWN
69 }
70 } else {
71 VERS_UNKNOWN
72 })
73 }
74
75 fn kernel_version() -> Result<usize> {
76 static KERNEL_VERS: AtomicUsize = AtomicUsize::new(0);
77 let mut kernel_vers = KERNEL_VERS.load(Ordering::Relaxed);
78
79 if kernel_vers == 0 {
80 kernel_vers = parse_kernel_version()?;
81 KERNEL_VERS.store(kernel_vers, Ordering::Relaxed);
82 }
83
84 Ok(kernel_vers)
85 }
86
87 pub fn socket_atomic_cloexec() -> bool {
89 kernel_version()
90 .map(|version| version >= VERS_2_6_27)
91 .unwrap_or(false)
92 }
93
94 #[test]
95 pub fn test_parsing_kernel_version() {
96 assert!(kernel_version().unwrap() > 0);
97 }
98}
99
100#[cfg(any(
101 freebsdlike, netbsdlike, target_os = "hurd", target_os = "illumos", target_os = "redox", ))]
107mod os {
108 pub const fn socket_atomic_cloexec() -> bool {
110 true
111 }
112}
113
114#[cfg(any(
115 target_os = "aix",
116 apple_targets,
117 target_os = "fuchsia",
118 target_os = "haiku",
119 target_os = "solaris"
120))]
121mod os {
122 pub const fn socket_atomic_cloexec() -> bool {
124 false
125 }
126}