1#[cfg(target_family = "windows")]
16static mut WINAPI_STDERR_HANDLE: windows_sys::Win32::Foundation::HANDLE =
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: windows_sys::Win32::Foundation::HANDLE =
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 windows_sys::Win32::Foundation::{
42 HANDLE_FLAG_INHERIT, SetHandleInformation,
43 };
44 use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, SetStdHandle};
45
46 unsafe {
47 let handle =
49 dev_null.as_raw_handle() as windows_sys::Win32::Foundation::HANDLE;
50 SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
51
52 if (WINAPI_STDERR_HANDLE != handle) {
53 WINAPI_STDERR_HANDLE = std::io::stdout().as_raw_handle()
54 as windows_sys::Win32::Foundation::HANDLE;
55 }
56
57 if SetStdHandle(STD_ERROR_HANDLE, handle) == 0 {
59 return Err(io::Error::last_os_error());
60 }
61 }
62 }
63
64 #[cfg(not(target_os = "windows"))]
65 {
66 use libc;
67 use std::os::unix::io::AsRawFd;
68
69 let dev_null_fd = dev_null.as_raw_fd();
70
71 unsafe {
72 if UNIX_STDERR_HANDLE != -1 {
76 libc::close(UNIX_STDERR_HANDLE);
77 }
78 UNIX_STDERR_HANDLE = libc::dup(libc::STDERR_FILENO);
79 if UNIX_STDERR_HANDLE == -1 {
80 return Err(io::Error::last_os_error());
81 }
82
83 if libc::dup2(dev_null_fd, libc::STDERR_FILENO) == -1 {
84 return Err(io::Error::last_os_error());
85 }
86 }
87 }
88
89 Ok(())
90}
91
92pub fn restore_stderr() -> std::io::Result<()> {
93 use std::io::{self};
94
95 #[cfg(target_os = "windows")]
96 {
97 use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, SetStdHandle};
98
99 unsafe {
100 if SetStdHandle(STD_ERROR_HANDLE, WINAPI_STDERR_HANDLE) == 0 {
101 return Err(io::Error::last_os_error());
102 }
103 }
104 }
105
106 #[cfg(not(target_os = "windows"))]
107 {
108 use libc;
109
110 unsafe {
111 if UNIX_STDERR_HANDLE == -1 {
112 return Ok(());
113 }
114 if libc::dup2(UNIX_STDERR_HANDLE, libc::STDERR_FILENO) == -1 {
115 return Err(io::Error::last_os_error());
116 }
117 libc::close(UNIX_STDERR_HANDLE);
118 UNIX_STDERR_HANDLE = -1;
119 }
120 }
121
122 Ok(())
123}
124
125pub fn redirect_stdout() -> std::io::Result<()> {
126 use std::fs::File;
127 use std::io::{self};
128
129 #[allow(unused_variables)]
130 let dev_null = if cfg!(target_os = "windows") {
131 File::create("NUL")?
132 } else {
133 File::create("/dev/null")?
134 };
135
136 #[cfg(target_os = "windows")]
137 {
138 use std::os::windows::io::AsRawHandle;
139 use windows_sys::Win32::Foundation::{
140 HANDLE_FLAG_INHERIT, SetHandleInformation,
141 };
142 use windows_sys::Win32::System::Console::{
143 STD_OUTPUT_HANDLE, SetStdHandle,
144 };
145
146 unsafe {
147 let handle =
149 dev_null.as_raw_handle() as windows_sys::Win32::Foundation::HANDLE;
150 SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
151
152 if (WINAPI_STDOUT_HANDLE != handle) {
153 WINAPI_STDOUT_HANDLE = std::io::stdout().as_raw_handle()
154 as windows_sys::Win32::Foundation::HANDLE;
155 }
156
157 if SetStdHandle(STD_OUTPUT_HANDLE, handle) == 0 {
159 return Err(io::Error::last_os_error());
160 }
161 }
162 }
163
164 #[cfg(not(target_os = "windows"))]
165 {
166 use libc;
167 use std::os::unix::io::AsRawFd;
168
169 let original_fd = io::stdout().as_raw_fd();
175 let dev_null_fd = dev_null.as_raw_fd();
176
177 unsafe {
178 if UNIX_STDOUT_HANDLE != -1 {
182 libc::close(UNIX_STDOUT_HANDLE);
183 }
184 UNIX_STDOUT_HANDLE = libc::dup(original_fd);
185 if UNIX_STDOUT_HANDLE == -1 {
186 return Err(io::Error::last_os_error());
187 }
188
189 if libc::dup2(dev_null_fd, original_fd) == -1 {
190 return Err(io::Error::last_os_error());
191 }
192 }
193 }
194
195 Ok(())
196}
197
198pub fn restore_stdout() -> std::io::Result<()> {
199 use std::io::{self};
200
201 #[cfg(target_os = "windows")]
202 {
203 use windows_sys::Win32::System::Console::{
204 STD_OUTPUT_HANDLE, SetStdHandle,
205 };
206
207 unsafe {
208 if SetStdHandle(STD_OUTPUT_HANDLE, WINAPI_STDOUT_HANDLE) == 0 {
209 return Err(io::Error::last_os_error());
210 }
211 }
212 }
213
214 #[cfg(not(target_os = "windows"))]
215 {
216 use libc;
217 use std::os::unix::io::AsRawFd;
218
219 let original_fd = io::stdout().as_raw_fd();
220
221 unsafe {
222 if UNIX_STDOUT_HANDLE == -1 {
223 return Ok(());
225 }
226 if libc::dup2(UNIX_STDOUT_HANDLE, original_fd) == -1 {
227 return Err(io::Error::last_os_error());
228 }
229 libc::close(UNIX_STDOUT_HANDLE);
233 UNIX_STDOUT_HANDLE = -1;
234 }
235 }
236
237 Ok(())
238}