diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index edcdf091e..cc5052dea 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -14,6 +14,7 @@ extern crate uucore; use clap::{crate_version, App, Arg}; use std::ffi::CStr; +use std::io::Write; use uucore::InvalidEncodingHandling; static ABOUT: &str = "Print the file name of the terminal connected to standard input."; @@ -44,7 +45,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .help("print nothing, only return an exit status") .required(false), ) - .get_matches_from(args); + .get_matches_from_safe(args); + + let matches = match matches { + Ok(m) => m, + Err(e) => { + eprint!("{}", e); + return 2; + } + }; let silent = matches.is_present(options::SILENT); @@ -58,11 +67,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } }; + let mut stdout = std::io::stdout(); + if !silent { - if !tty.chars().all(|c| c.is_whitespace()) { - println!("{}", tty); + let write_result = if !tty.chars().all(|c| c.is_whitespace()) { + writeln!(stdout, "{}", tty) } else { - println!("not a tty"); + writeln!(stdout, "not a tty") + }; + if write_result.is_err() || stdout.flush().is_err() { + // Don't return to prevent a panic later when another flush is attempted + // because the `uucore_procs::main` macro inserts a flush after execution for every utility. + std::process::exit(3); } } diff --git a/tests/by-util/test_tty.rs b/tests/by-util/test_tty.rs index 6bca54e03..6ba8cd029 100644 --- a/tests/by-util/test_tty.rs +++ b/tests/by-util/test_tty.rs @@ -1,11 +1,14 @@ +use std::fs::File; + use crate::common::util::*; #[test] #[cfg(not(windows))] fn test_dev_null() { new_ucmd!() - .pipe_in("