open_coroutine_hooks/unix/
mod.rs1macro_rules! init_hook {
3 ( $symbol:literal ) => {
4 once_cell::sync::Lazy::new(|| unsafe {
5 let syscall = $symbol;
6 let symbol = std::ffi::CString::new(String::from(syscall))
7 .unwrap_or_else(|_| panic!("can not transfer \"{syscall}\" to CString"));
8 let ptr = libc::dlsym(libc::RTLD_NEXT, symbol.as_ptr());
9 assert!(!ptr.is_null(), "system call \"{syscall}\" not found !");
10 std::mem::transmute(ptr)
11 })
12 };
13}
14
15pub mod common;
16
17pub mod sleep;
18
19pub mod socket;
20
21pub mod read;
22
23pub mod write;
24
25#[cfg(any(
26 target_os = "linux",
27 target_os = "l4re",
28 target_os = "android",
29 target_os = "emscripten"
30))]
31mod linux_like;
32
33extern "C" {
34 #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
35 #[cfg_attr(
36 any(
37 target_os = "linux",
38 target_os = "emscripten",
39 target_os = "fuchsia",
40 target_os = "l4re"
41 ),
42 link_name = "__errno_location"
43 )]
44 #[cfg_attr(
45 any(
46 target_os = "netbsd",
47 target_os = "openbsd",
48 target_os = "android",
49 target_os = "redox",
50 target_env = "newlib"
51 ),
52 link_name = "__errno"
53 )]
54 #[cfg_attr(
55 any(target_os = "solaris", target_os = "illumos"),
56 link_name = "___errno"
57 )]
58 #[cfg_attr(
59 any(
60 target_os = "macos",
61 target_os = "ios",
62 target_os = "freebsd",
63 target_os = "watchos"
64 ),
65 link_name = "__error"
66 )]
67 #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
68 fn errno_location() -> *mut libc::c_int;
69}
70
71pub extern "C" fn reset_errno() {
72 set_errno(0);
73}
74
75pub extern "C" fn set_errno(errno: libc::c_int) {
76 unsafe { errno_location().write(errno) }
77}
78
79extern "C" fn set_non_blocking(socket: libc::c_int) {
80 assert!(
81 set_non_blocking_flag(socket, true),
82 "set_non_blocking failed !"
83 );
84}
85
86extern "C" fn set_blocking(socket: libc::c_int) {
87 assert!(
88 set_non_blocking_flag(socket, false),
89 "set_blocking failed !"
90 );
91}
92
93extern "C" fn set_non_blocking_flag(socket: libc::c_int, on: bool) -> bool {
94 let flags = unsafe { libc::fcntl(socket, libc::F_GETFL) };
95 if flags < 0 {
96 return false;
97 }
98 unsafe {
99 libc::fcntl(
100 socket,
101 libc::F_SETFL,
102 if on {
103 flags | libc::O_NONBLOCK
104 } else {
105 flags & !libc::O_NONBLOCK
106 },
107 ) == 0
108 }
109}
110
111#[must_use]
112pub extern "C" fn is_blocking(socket: libc::c_int) -> bool {
113 !is_non_blocking(socket)
114}
115
116#[must_use]
117pub extern "C" fn is_non_blocking(socket: libc::c_int) -> bool {
118 let flags = unsafe { libc::fcntl(socket, libc::F_GETFL) };
119 if flags < 0 {
120 return false;
121 }
122 (flags & libc::O_NONBLOCK) != 0
123}