diff --git a/Cargo.lock b/Cargo.lock index baefe36259..4d8fa157b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,7 +786,6 @@ name = "deno" version = "1.36.3" dependencies = [ "async-trait", - "atty", "base32", "base64 0.13.1", "bincode", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index b3a6939acd..91ccebf714 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -62,7 +62,6 @@ eszip = "=0.50.0" napi_sym.workspace = true async-trait.workspace = true -atty.workspace = true base32 = "=0.4.0" base64.workspace = true bincode = "=1.3.3" diff --git a/cli/cache/cache_db.rs b/cli/cache/cache_db.rs index 9b591f58a5..b6b4d074e8 100644 --- a/cli/cache/cache_db.rs +++ b/cli/cache/cache_db.rs @@ -9,6 +9,7 @@ use deno_runtime::deno_webstorage::rusqlite::Connection; use deno_runtime::deno_webstorage::rusqlite::OptionalExtension; use deno_runtime::deno_webstorage::rusqlite::Params; use once_cell::sync::OnceCell; +use std::io::IsTerminal; use std::path::PathBuf; use std::sync::Arc; @@ -261,7 +262,7 @@ impl CacheDB { }; // Failed, try deleting it - let is_tty = atty::is(atty::Stream::Stderr); + let is_tty = std::io::stderr().is_terminal(); log::log!( if is_tty { log::Level::Warn } else { log::Level::Trace }, "Could not initialize cache database '{}', deleting and retrying... ({err:?})", diff --git a/cli/tools/upgrade.rs b/cli/tools/upgrade.rs index bef4538b3f..c0fbb73ce2 100644 --- a/cli/tools/upgrade.rs +++ b/cli/tools/upgrade.rs @@ -23,6 +23,7 @@ use once_cell::sync::Lazy; use std::borrow::Cow; use std::env; use std::fs; +use std::io::IsTerminal; use std::ops::Sub; use std::path::Path; use std::path::PathBuf; @@ -210,7 +211,7 @@ pub fn check_for_upgrades( // Print a message if an update is available if let Some(upgrade_version) = update_checker.should_prompt() { - if log::log_enabled!(log::Level::Info) && atty::is(atty::Stream::Stderr) { + if log::log_enabled!(log::Level::Info) && std::io::stderr().is_terminal() { if version::is_canary() { eprint!( "{} ", diff --git a/cli/util/draw_thread.rs b/cli/util/draw_thread.rs index 832c7f74bc..352ead3b0b 100644 --- a/cli/util/draw_thread.rs +++ b/cli/util/draw_thread.rs @@ -5,6 +5,7 @@ use deno_core::parking_lot::Mutex; use deno_core::unsync::spawn_blocking; use deno_runtime::ops::tty::ConsoleSize; use once_cell::sync::Lazy; +use std::io::IsTerminal; use std::sync::Arc; use std::time::Duration; @@ -70,7 +71,7 @@ static INTERNAL_STATE: Lazy>> = Lazy::new(|| { }); static IS_TTY_WITH_CONSOLE_SIZE: Lazy = Lazy::new(|| { - atty::is(atty::Stream::Stderr) + std::io::stderr().is_terminal() && console_size() .map(|s| s.cols > 0 && s.rows > 0) .unwrap_or(false) diff --git a/cli/util/file_watcher.rs b/cli/util/file_watcher.rs index ddeedb7415..c0eda2d863 100644 --- a/cli/util/file_watcher.rs +++ b/cli/util/file_watcher.rs @@ -16,6 +16,7 @@ use notify::RecommendedWatcher; use notify::RecursiveMode; use notify::Watcher; use std::collections::HashSet; +use std::io::IsTerminal; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; @@ -98,7 +99,7 @@ pub struct PrintConfig { fn create_print_after_restart_fn(clear_screen: bool) -> impl Fn() { move || { - if clear_screen && atty::is(atty::Stream::Stderr) { + if clear_screen && std::io::stderr().is_terminal() { eprint!("{CLEAR_SCREEN}"); } info!( diff --git a/runtime/colors.rs b/runtime/colors.rs index a9ad12e8c0..fe5a3dcbea 100644 --- a/runtime/colors.rs +++ b/runtime/colors.rs @@ -1,8 +1,8 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use atty; use once_cell::sync::Lazy; use std::fmt; +use std::io::IsTerminal; use std::io::Write; use termcolor::Ansi; use termcolor::Color::Ansi256; @@ -25,7 +25,7 @@ use termcolor::ColorChoice; static NO_COLOR: Lazy = Lazy::new(|| std::env::var_os("NO_COLOR").is_some()); -static IS_TTY: Lazy = Lazy::new(|| atty::is(atty::Stream::Stdout)); +static IS_TTY: Lazy = Lazy::new(|| std::io::stdout().is_terminal()); pub fn is_tty() -> bool { *IS_TTY diff --git a/runtime/js/40_tty.js b/runtime/js/40_tty.js index 859f492757..7476daad31 100644 --- a/runtime/js/40_tty.js +++ b/runtime/js/40_tty.js @@ -4,7 +4,6 @@ const ops = core.ops; const primordials = globalThis.__bootstrap.primordials; const { Uint32Array, - Uint8Array, } = primordials; const size = new Uint32Array(2); @@ -14,10 +13,8 @@ function consoleSize() { return { columns: size[0], rows: size[1] }; } -const isattyBuffer = new Uint8Array(1); function isatty(rid) { - ops.op_isatty(rid, isattyBuffer); - return !!isattyBuffer[0]; + return ops.op_isatty(rid); } export { consoleSize, isatty }; diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index b24c9d8935..1d4c123a22 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -1,10 +1,13 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use std::io::Error; +use std::io::IsTerminal; use deno_core::error::AnyError; use deno_core::op; +use deno_core::op2; use deno_core::OpState; +use deno_core::ResourceHandle; #[cfg(unix)] use deno_core::ResourceId; @@ -162,32 +165,27 @@ fn op_stdin_set_raw( } } -#[op(fast)] -fn op_isatty( - state: &mut OpState, - rid: u32, - out: &mut [u8], -) -> Result<(), AnyError> { - let raw_fd = state.resource_table.get_fd(rid)?; - #[cfg(windows)] - { - use winapi::shared::minwindef::FALSE; - use winapi::um::consoleapi; - - let handle = raw_fd; - let mut test_mode: DWORD = 0; - // If I cannot get mode out of console, it is not a console. - out[0] = - // SAFETY: Windows API - unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE } - as u8; - } - #[cfg(unix)] - { - // SAFETY: Posix API - out[0] = unsafe { libc::isatty(raw_fd as libc::c_int) == 1 } as u8; - } - Ok(()) +#[op2(fast)] +fn op_isatty(state: &mut OpState, rid: u32) -> Result { + let handle = state.resource_table.get_handle(rid)?; + // TODO(mmastrac): this can migrate to the deno_core implementation when it lands + Ok(match handle { + ResourceHandle::Fd(fd) if handle.is_valid() => { + #[cfg(windows)] + { + // SAFETY: The resource remains open for the for the duration of borrow_raw + unsafe { + std::os::windows::io::BorrowedHandle::borrow_raw(fd).is_terminal() + } + } + #[cfg(unix)] + { + // SAFETY: The resource remains open for the for the duration of borrow_raw + unsafe { std::os::fd::BorrowedFd::borrow_raw(fd).is_terminal() } + } + } + _ => false, + }) } #[op(fast)] diff --git a/runtime/permissions/prompter.rs b/runtime/permissions/prompter.rs index 93a7c96869..78761aa32d 100644 --- a/runtime/permissions/prompter.rs +++ b/runtime/permissions/prompter.rs @@ -6,6 +6,7 @@ use deno_core::parking_lot::Mutex; use once_cell::sync::Lazy; use std::fmt::Write; use std::io::BufRead; +use std::io::IsTerminal; use std::io::StderrLock; use std::io::StdinLock; use std::io::Write as IoWrite; @@ -84,7 +85,7 @@ impl PermissionPrompter for TtyPrompter { api_name: Option<&str>, is_unary: bool, ) -> PromptResponse { - if !atty::is(atty::Stream::Stdin) || !atty::is(atty::Stream::Stderr) { + if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() { return PromptResponse::Deny; };