#[cfg(target_family = "windows")]
static mut WINAPI_STDERR_HANDLE: windows_sys::Win32::Foundation::HANDLE =
std::ptr::null_mut();
#[cfg(not(target_os = "windows"))]
static mut UNIX_STDERR_HANDLE: i32 = -1;
#[cfg(target_family = "windows")]
static mut WINAPI_STDOUT_HANDLE: windows_sys::Win32::Foundation::HANDLE =
std::ptr::null_mut();
#[cfg(not(target_os = "windows"))]
static mut UNIX_STDOUT_HANDLE: i32 = -1;
pub fn redirect_stderr() -> std::io::Result<()> {
use std::fs::File;
use std::io::{self};
#[allow(unused_variables)]
let dev_null = if cfg!(target_os = "windows") {
File::create("NUL")?
} else {
File::create("/dev/null")?
};
#[cfg(target_os = "windows")]
{
use std::os::windows::io::AsRawHandle;
use windows_sys::Win32::Foundation::{
HANDLE_FLAG_INHERIT, SetHandleInformation,
};
use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, SetStdHandle};
unsafe {
let handle =
dev_null.as_raw_handle() as windows_sys::Win32::Foundation::HANDLE;
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
if (WINAPI_STDERR_HANDLE != handle) {
WINAPI_STDERR_HANDLE = std::io::stdout().as_raw_handle()
as windows_sys::Win32::Foundation::HANDLE;
}
if SetStdHandle(STD_ERROR_HANDLE, handle) == 0 {
return Err(io::Error::last_os_error());
}
}
}
#[cfg(not(target_os = "windows"))]
{
use libc;
use std::os::unix::io::AsRawFd;
let dev_null_fd = dev_null.as_raw_fd();
unsafe {
if UNIX_STDERR_HANDLE != -1 {
libc::close(UNIX_STDERR_HANDLE);
}
UNIX_STDERR_HANDLE = libc::dup(libc::STDERR_FILENO);
if UNIX_STDERR_HANDLE == -1 {
return Err(io::Error::last_os_error());
}
if libc::dup2(dev_null_fd, libc::STDERR_FILENO) == -1 {
return Err(io::Error::last_os_error());
}
}
}
Ok(())
}
pub fn restore_stderr() -> std::io::Result<()> {
use std::io::{self};
#[cfg(target_os = "windows")]
{
use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, SetStdHandle};
unsafe {
if SetStdHandle(STD_ERROR_HANDLE, WINAPI_STDERR_HANDLE) == 0 {
return Err(io::Error::last_os_error());
}
}
}
#[cfg(not(target_os = "windows"))]
{
use libc;
unsafe {
if UNIX_STDERR_HANDLE == -1 {
return Ok(());
}
if libc::dup2(UNIX_STDERR_HANDLE, libc::STDERR_FILENO) == -1 {
return Err(io::Error::last_os_error());
}
libc::close(UNIX_STDERR_HANDLE);
UNIX_STDERR_HANDLE = -1;
}
}
Ok(())
}
pub fn redirect_stdout() -> std::io::Result<()> {
use std::fs::File;
use std::io::{self};
#[allow(unused_variables)]
let dev_null = if cfg!(target_os = "windows") {
File::create("NUL")?
} else {
File::create("/dev/null")?
};
#[cfg(target_os = "windows")]
{
use std::os::windows::io::AsRawHandle;
use windows_sys::Win32::Foundation::{
HANDLE_FLAG_INHERIT, SetHandleInformation,
};
use windows_sys::Win32::System::Console::{
STD_OUTPUT_HANDLE, SetStdHandle,
};
unsafe {
let handle =
dev_null.as_raw_handle() as windows_sys::Win32::Foundation::HANDLE;
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
if (WINAPI_STDOUT_HANDLE != handle) {
WINAPI_STDOUT_HANDLE = std::io::stdout().as_raw_handle()
as windows_sys::Win32::Foundation::HANDLE;
}
if SetStdHandle(STD_OUTPUT_HANDLE, handle) == 0 {
return Err(io::Error::last_os_error());
}
}
}
#[cfg(not(target_os = "windows"))]
{
use libc;
use std::os::unix::io::AsRawFd;
let original_fd = io::stdout().as_raw_fd();
let dev_null_fd = dev_null.as_raw_fd();
unsafe {
if UNIX_STDOUT_HANDLE != -1 {
libc::close(UNIX_STDOUT_HANDLE);
}
UNIX_STDOUT_HANDLE = libc::dup(original_fd);
if UNIX_STDOUT_HANDLE == -1 {
return Err(io::Error::last_os_error());
}
if libc::dup2(dev_null_fd, original_fd) == -1 {
return Err(io::Error::last_os_error());
}
}
}
Ok(())
}
pub fn restore_stdout() -> std::io::Result<()> {
use std::io::{self};
#[cfg(target_os = "windows")]
{
use windows_sys::Win32::System::Console::{
STD_OUTPUT_HANDLE, SetStdHandle,
};
unsafe {
if SetStdHandle(STD_OUTPUT_HANDLE, WINAPI_STDOUT_HANDLE) == 0 {
return Err(io::Error::last_os_error());
}
}
}
#[cfg(not(target_os = "windows"))]
{
use libc;
use std::os::unix::io::AsRawFd;
let original_fd = io::stdout().as_raw_fd();
unsafe {
if UNIX_STDOUT_HANDLE == -1 {
return Ok(());
}
if libc::dup2(UNIX_STDOUT_HANDLE, original_fd) == -1 {
return Err(io::Error::last_os_error());
}
libc::close(UNIX_STDOUT_HANDLE);
UNIX_STDOUT_HANDLE = -1;
}
}
Ok(())
}