Search code examples
windowsrustsignalsmsys2sigpipe

Rust how to ignore print to stdout error?


How do I ignore pipe errors in Rust? In C, this comes for free:

user@localhost:~ $ cat main.c
#include <stdio.h>
int main(){printf("Hello World!\n");}
user@localhost:~ $ clang main.c -o main
user@localhost:~ $ ./main.exe | echo && echo $?

0
user@localhost:~ $

But with Rust, its default behavior is to panic on a bad pipe:

user@localhost:~ $ cat main.rs
fn main(){println!("Hello World!");}
user@localhost:~ $ rustc main.rs
user@localhost:~ $ ./main.exe | echo && echo $?

thread 'main' panicked at library\std\src\io\stdio.rs:1021:9:
failed printing to stdout: The pipe is being closed. (os error 232)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
0
user@localhost:~ $

This post suggests reseting the SIGPIPE handler, but that is not useful for me as I'm on Windows. I am running zsh in MSYS2 as my shell, but the underlying OS is still Windows, so the symbol libc::SIGPIPE still can't be resolved - plus I get the same error running the program from CMD or powershell, so I doubt its a shell problem.

Is there a way I can make my Rust program ignore SIGPIPE errors, as my C program does?


Solution

  • You can use the writeln! macro instead of println! and handle (or ignore) the errors yourself:

    use std::io::Write;
    
    fn main() {
        let mut stdout = std::io::stdout();
        // ignore errors (assign to _ to silence the warning)
        let _ = writeln!(stdout, "Hello World!");
    }
    

    println!(format_str) essentially resolves to something like

    writeln!(std::io::stdout(), format_str, ...).unwrap();