uu_tty/
tty.rs

1// This file is part of the uutils coreutils package.
2//
3// For the full copyright and license information, please view the LICENSE
4// file that was distributed with this source code.
5
6// spell-checker:ignore (ToDO) ttyname filedesc
7
8use clap::{Arg, ArgAction, Command};
9use std::io::{IsTerminal, Write};
10use uucore::error::{UResult, set_exit_code};
11use uucore::format_usage;
12
13use uucore::translate;
14
15mod options {
16    pub const SILENT: &str = "silent";
17}
18
19#[uucore::main]
20pub fn uumain(args: impl uucore::Args) -> UResult<()> {
21    let matches = uucore::clap_localization::handle_clap_result_with_exit_code(uu_app(), args, 2)?;
22
23    let silent = matches.get_flag(options::SILENT);
24
25    // If silent, we don't need the name, only whether or not stdin is a tty.
26    if silent {
27        return if std::io::stdin().is_terminal() {
28            Ok(())
29        } else {
30            Err(1.into())
31        };
32    }
33
34    let mut stdout = std::io::stdout();
35
36    let name = nix::unistd::ttyname(std::io::stdin());
37
38    let write_result = match name {
39        Ok(name) => writeln!(stdout, "{}", name.display()),
40        Err(_) => {
41            set_exit_code(1);
42            writeln!(stdout, "{}", translate!("tty-not-a-tty"))
43        }
44    };
45
46    if write_result.is_err() || stdout.flush().is_err() {
47        // Don't return to prevent a panic later when another flush is attempted
48        // because the `uucore_procs::main` macro inserts a flush after execution for every utility.
49        std::process::exit(3);
50    }
51
52    Ok(())
53}
54
55pub fn uu_app() -> Command {
56    let cmd = Command::new(uucore::util_name())
57        .version(uucore::crate_version!())
58        .about(translate!("tty-about"))
59        .override_usage(format_usage(&translate!("tty-usage")))
60        .infer_long_args(true);
61    uucore::clap_localization::configure_localized_command(cmd).arg(
62        Arg::new(options::SILENT)
63            .long(options::SILENT)
64            .visible_alias("quiet")
65            .short('s')
66            .help(translate!("tty-help-silent"))
67            .action(ArgAction::SetTrue),
68    )
69}