From dd72eca93c2a336ad188e3bee234579c51f78c15 Mon Sep 17 00:00:00 2001 From: oech3 <79379754+oech3@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:31:45 +0900 Subject: [PATCH] tty: Build for Windows --- .github/workflows/make.yml | 2 +- .github/workflows/wasi.yml | 2 +- Cargo.toml | 3 +-- src/uu/tty/src/tty.rs | 14 +++++++++++--- tests/by-util/test_tty.rs | 9 +++++++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 4cfc8233e..e654b5510 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -322,7 +322,7 @@ jobs: set -x # Check that we exclude unix programs to avoid build failure make PREFIX=/tmp/usr MULTICALL=y COMPLETIONS=n MANPAGES=n LOCALES=n \ - SKIP_UTILS="arch b2sum base32 base64 basename basenc cat cksum comm cp csplit cut date dd df dir dircolors dirname du echo env expand expr factor false fmt fold head hostname join link ln ls md5sum mkdir mktemp more mv nl nproc numfmt od paste pr printenv printf ptx pwd readlink realpath rm rmdir seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort split sum sync tac tail tee test touch tr truncate tsort uname unexpand uniq unlink vdir wc whoami yes" + SKIP_UTILS="arch b2sum base32 base64 basename basenc cat cksum comm cp csplit cut date dd df dir dircolors dirname du echo env expand expr factor false fmt fold head hostname join link ln ls md5sum mkdir mktemp more mv nl nproc numfmt od paste pathchk pr printenv printf ptx pwd readlink realpath rm rmdir seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf sleep sort split sum sync tac tail tee test touch tr truncate tsort tty uname unexpand uniq unlink vdir wc whoami yes" target/debug/coreutils.exe true test_busybox: diff --git a/.github/workflows/wasi.yml b/.github/workflows/wasi.yml index 8c3721d6a..549e85dd0 100644 --- a/.github/workflows/wasi.yml +++ b/.github/workflows/wasi.yml @@ -37,7 +37,7 @@ jobs: CARGO_TARGET_WASM32_WASIP1_RUNNER: wasmtime run: | # Get all utilities and exclude ones that don't compile for wasm32-wasip1 - EXCLUDE="dd|df|du|env|expr|mktemp|more|tac|test" + EXCLUDE="dd|df|du|env|expr|mktemp|more|tac|test|tty" UTILS=$(./util/show-utils.sh | tr ' ' '\n' | grep -vE "^($EXCLUDE)$" | sed 's/^/-p uu_/' | tr '\n' ' ') cargo test --target wasm32-wasip1 --no-default-features $UTILS - name: Run integration tests via wasmtime diff --git a/Cargo.toml b/Cargo.toml index 145cd2b72..6a3307648 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -156,6 +156,7 @@ feat_common_core = [ "true", "truncate", "tsort", + "tty", "unexpand", "uniq", "unlink", @@ -312,7 +313,6 @@ feat_require_unix_core = [ "stat", "stty", "timeout", - "tty", ] # "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support # * ref: @@ -337,7 +337,6 @@ feat_os_unix_fuchsia = [ "mkfifo", "mknod", "nice", - "tty", "uname", "unlink", ] diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index edab189fd..33c84804c 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -7,7 +7,6 @@ use clap::{Arg, ArgAction, Command}; use std::io::{IsTerminal, Write}; -use uucore::display::OsWrite; use uucore::error::{UResult, set_exit_code}; use uucore::format_usage; @@ -38,11 +37,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } let mut stdout = std::io::stdout(); - + #[cfg(unix)] let name = rustix::termios::ttyname(std::io::stdin(), Vec::with_capacity(8)); - + #[cfg(unix)] let write_result = if let Ok(name) = name { use std::os::unix::ffi::OsStrExt; + use uucore::display::OsWrite; let os_name = std::ffi::OsStr::from_bytes(name.as_bytes()); stdout.write_all_os(os_name) } else { @@ -50,6 +50,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { writeln!(stdout, "{}", translate!("tty-not-a-tty")) }; + #[cfg(target_os = "windows")] + let write_result = if std::io::stdin().is_terminal() { + writeln!(stdout, r"\\.\CON") + } else { + set_exit_code(1); + writeln!(stdout, "{}", translate!("tty-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. diff --git a/tests/by-util/test_tty.rs b/tests/by-util/test_tty.rs index b5aa23aa7..be0ea00af 100644 --- a/tests/by-util/test_tty.rs +++ b/tests/by-util/test_tty.rs @@ -2,12 +2,13 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +#[cfg(unix)] use std::fs::File; use uutests::new_ucmd; #[test] -#[cfg(not(windows))] +#[cfg(unix)] fn test_dev_null() { new_ucmd!() .set_stdin(File::open("/dev/null").unwrap()) @@ -16,7 +17,7 @@ fn test_dev_null() { } #[test] -#[cfg(not(windows))] +#[cfg(unix)] fn test_dev_null_silent() { new_ucmd!() .args(&["-s"]) @@ -26,6 +27,7 @@ fn test_dev_null_silent() { } #[test] +#[cfg(unix)] fn test_close_stdin() { let mut child = new_ucmd!().run_no_wait(); child.close_stdin(); @@ -33,6 +35,7 @@ fn test_close_stdin() { } #[test] +#[cfg(unix)] fn test_close_stdin_silent() { let mut child = new_ucmd!().arg("-s").run_no_wait(); child.close_stdin(); @@ -40,6 +43,7 @@ fn test_close_stdin_silent() { } #[test] +#[cfg(unix)] fn test_close_stdin_silent_long() { let mut child = new_ucmd!().arg("--silent").run_no_wait(); child.close_stdin(); @@ -47,6 +51,7 @@ fn test_close_stdin_silent_long() { } #[test] +#[cfg(unix)] fn test_close_stdin_silent_alias() { let mut child = new_ucmd!().arg("--quiet").run_no_wait(); child.close_stdin();