1#[cfg(target_family = "windows")]
16static mut WINAPI_STDERR_HANDLE: *mut winapi::ctypes::c_void =
17 std::ptr::null_mut();
18#[cfg(not(target_os = "windows"))]
19static mut UNIX_STDERR_HANDLE: i32 = -1;
20
21#[cfg(target_family = "windows")]
22static mut WINAPI_STDOUT_HANDLE: *mut winapi::ctypes::c_void =
23 std::ptr::null_mut();
24#[cfg(not(target_os = "windows"))]
25static mut UNIX_STDOUT_HANDLE: i32 = -1;
26
27pub fn redirect_stderr() -> std::io::Result<()> {
28 use std::fs::File;
29 use std::io::{self};
30
31 #[allow(unused_variables)]
32 let dev_null = if cfg!(target_os = "windows") {
33 File::create("NUL")?
34 } else {
35 File::create("/dev/null")?
36 };
37
38 #[cfg(target_os = "windows")]
39 {
40 use std::os::windows::io::AsRawHandle;
41 use winapi::um::handleapi::SetHandleInformation;
42 use winapi::um::processenv::SetStdHandle;
43 use winapi::um::winbase::{HANDLE_FLAG_INHERIT, STD_ERROR_HANDLE};
44
45 unsafe {
46 let handle = dev_null.as_raw_handle() as *mut winapi::ctypes::c_void;
48 SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
49
50 if (WINAPI_STDERR_HANDLE != handle) {
51 WINAPI_STDERR_HANDLE =
52 std::io::stdout().as_raw_handle() as *mut winapi::ctypes::c_void;
53 }
54
55 if SetStdHandle(STD_ERROR_HANDLE, handle) == 0 {
57 return Err(io::Error::last_os_error());
58 }
59 }
60 }
61
62 #[cfg(not(target_os = "windows"))]
63 {
64 use libc;
65 use std::os::unix::io::AsRawFd;
66
67 unsafe {
68 let raw_fd = dev_null.as_raw_fd();
69
70 if (UNIX_STDERR_HANDLE != raw_fd) {
71 UNIX_STDERR_HANDLE = std::io::stdout().as_raw_fd();
72 }
73
74 if libc::dup2(raw_fd, libc::STDERR_FILENO) == -1 {
75 return Err(io::Error::last_os_error());
76 }
77 }
78 }
79
80 Ok(())
81}
82
83pub fn restore_stderr() -> std::io::Result<()> {
84 use std::fs::File;
85 use std::io::{self};
86
87 #[cfg(target_os = "windows")]
88 {
89 use std::os::windows::io::AsRawHandle;
90 use winapi::um::handleapi::SetHandleInformation;
91 use winapi::um::processenv::SetStdHandle;
92 use winapi::um::winbase::{HANDLE_FLAG_INHERIT, STD_ERROR_HANDLE};
93
94 unsafe {
95 if SetStdHandle(STD_ERROR_HANDLE, WINAPI_STDERR_HANDLE) == 0 {
96 return Err(io::Error::last_os_error());
97 }
98 }
99 }
100
101 #[cfg(not(target_os = "windows"))]
102 {
103 use libc;
104 use std::os::unix::io::AsRawFd;
105
106 unsafe {
107 if libc::dup2(UNIX_STDERR_HANDLE, libc::STDERR_FILENO) == -1 {
108 return Err(io::Error::last_os_error());
109 }
110 }
111 }
112
113 Ok(())
114}
115
116pub fn redirect_stdout() -> std::io::Result<()> {
117 use std::fs::File;
118 use std::io::{self};
119
120 #[allow(unused_variables)]
121 let dev_null = if cfg!(target_os = "windows") {
122 File::create("NUL")?
123 } else {
124 File::create("/dev/null")?
125 };
126
127 #[cfg(target_os = "windows")]
128 {
129 use std::os::windows::io::AsRawHandle;
130 use winapi::um::handleapi::SetHandleInformation;
131 use winapi::um::processenv::SetStdHandle;
132 use winapi::um::winbase::{HANDLE_FLAG_INHERIT, STD_OUTPUT_HANDLE};
133
134 unsafe {
135 let handle = dev_null.as_raw_handle() as *mut winapi::ctypes::c_void;
137 SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
138
139 if (WINAPI_STDOUT_HANDLE != handle) {
140 WINAPI_STDOUT_HANDLE =
141 std::io::stdout().as_raw_handle() as *mut winapi::ctypes::c_void;
142 }
143
144 if SetStdHandle(STD_OUTPUT_HANDLE, handle) == 0 {
146 return Err(io::Error::last_os_error());
147 }
148 }
149 }
150
151 #[cfg(not(target_os = "windows"))]
152 {
153 use libc;
154 use std::os::unix::io::AsRawFd;
155
156 let stdout = io::stdout();
158 let original_fd = stdout.as_raw_fd();
159
160 let dev_null_fd = File::open("/dev/null").unwrap().as_raw_fd();
162
163 unsafe {
164 if (UNIX_STDOUT_HANDLE != dev_null_fd) {
165 UNIX_STDOUT_HANDLE = libc::dup(original_fd);
166 }
167
168 libc::dup2(dev_null_fd, original_fd);
169 }
170
171 }
183
184 Ok(())
185}
186
187pub fn restore_stdout() -> std::io::Result<()> {
188 use std::fs::File;
189 use std::io::{self};
190
191 #[cfg(target_os = "windows")]
192 {
193 use std::os::windows::io::AsRawHandle;
194 use winapi::um::handleapi::SetHandleInformation;
195 use winapi::um::processenv::SetStdHandle;
196 use winapi::um::winbase::{HANDLE_FLAG_INHERIT, STD_OUTPUT_HANDLE};
197
198 unsafe {
199 if SetStdHandle(STD_OUTPUT_HANDLE, WINAPI_STDOUT_HANDLE) == 0 {
200 return Err(io::Error::last_os_error());
201 }
202 }
203 }
204
205 #[cfg(not(target_os = "windows"))]
206 {
207 use libc;
208 use std::os::unix::io::AsRawFd;
209
210 let stdout = io::stdout();
212 let original_fd = stdout.as_raw_fd();
213
214 unsafe {
215 libc::dup2(UNIX_STDOUT_HANDLE, original_fd);
216 }
217 }
218
219 Ok(())
220}