From 4c5ee1dbd7373fab1f28540bbbd005d4c5898f47 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Wed, 16 Jun 2021 17:38:07 +0200 Subject: [PATCH] tty: correct exit code for write errrors --- src/uu/tty/src/tty.rs | 14 +++++++++++--- tests/by-util/test_tty.rs | 9 +++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index 331f5e254..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."; @@ -66,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 a59be61b4..6ba8cd029 100644 --- a/tests/by-util/test_tty.rs +++ b/tests/by-util/test_tty.rs @@ -63,3 +63,12 @@ fn test_close_stdin_silent_alias() { fn test_wrong_argument() { new_ucmd!().args(&["a"]).fails().code_is(2); } + +#[test] +#[cfg(not(windows))] +fn test_stdout_fail() { + let mut child = new_ucmd!().run_no_wait(); + drop(child.stdout.take()); + let status = child.wait().unwrap(); + assert_eq!(status.code(), Some(3)); +}