diff --git a/cli/bench/tty.js b/cli/bench/tty.js index f86bcfd826..c01af255f8 100644 --- a/cli/bench/tty.js +++ b/cli/bench/tty.js @@ -17,5 +17,5 @@ function bench(fun) { } bench(() => { - Deno.consoleSize(0); + Deno.consoleSize(); }); diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs index 0fa35839ee..7c27b62e5f 100644 --- a/cli/diagnostics.rs +++ b/cli/diagnostics.rs @@ -35,7 +35,6 @@ const UNSTABLE_DENO_PROPS: &[&str] = &[ "addSignalListener", "bench", "connect", - "consoleSize", "createHttpClient", "kill", "listen", diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index 0ac06dc625..eea3c79477 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -1901,6 +1901,19 @@ declare namespace Deno { */ export const File: typeof FsFile; + /** Gets the size of the console as columns/rows. + * + * ```ts + * const { columns, rows } = Deno.consoleSize(); + * ``` + * + * @category I/O + */ + export function consoleSize(): { + columns: number; + rows: number; + }; + /** @category I/O */ export interface SetRawOptions { /** diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index c687848cae..4161765648 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -226,23 +226,6 @@ declare namespace Deno { */ export function umask(mask?: number): number; - /** **UNSTABLE**: New API, yet to be vetted. - * - * Gets the size of the console as columns/rows. - * - * ```ts - * const { columns, rows } = Deno.consoleSize(Deno.stdout.rid); - * ``` - * - * @category I/O - */ - export function consoleSize( - rid: number, - ): { - columns: number; - rows: number; - }; - /** **UNSTABLE**: New API, yet to be vetted. * * Returns the release version of the Operating System. diff --git a/cli/tests/unit/tty_test.ts b/cli/tests/unit/tty_test.ts index 8787db3e17..88b25d758c 100644 --- a/cli/tests/unit/tty_test.ts +++ b/cli/tests/unit/tty_test.ts @@ -1,21 +1,15 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -import { assert, assertThrows } from "./test_util.ts"; +import { assert } from "./test_util.ts"; // Note tests for Deno.stdin.setRaw is in integration tests. -Deno.test({ permissions: { read: true } }, function consoleSizeFile() { - const file = Deno.openSync("cli/tests/testdata/assets/hello.txt"); - assertThrows(() => { - Deno.consoleSize(file.rid); - }, Error); - file.close(); -}); - -Deno.test(function consoleSizeError() { - assertThrows(() => { - // Absurdly large rid. - Deno.consoleSize(0x7fffffff); - }, Deno.errors.BadResource); +Deno.test(function consoleSize() { + if (!Deno.isatty(Deno.stdout.rid)) { + return; + } + const result = Deno.consoleSize(); + assert(typeof result.columns !== "undefined"); + assert(typeof result.rows !== "undefined"); }); Deno.test({ permissions: { read: true } }, function isatty() { diff --git a/runtime/js/40_tty.js b/runtime/js/40_tty.js index be5154fa26..8ce3e83efd 100644 --- a/runtime/js/40_tty.js +++ b/runtime/js/40_tty.js @@ -10,8 +10,8 @@ const ops = core.ops; const size = new Uint32Array(2); - function consoleSize(rid) { - ops.op_console_size(rid, size); + function consoleSize() { + ops.op_console_size(size); return { columns: size[0], rows: size[1] }; } diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index 3bfd26da76..00d343f747 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -120,10 +120,10 @@ refTimer: __bootstrap.timers.refTimer, unrefTimer: __bootstrap.timers.unrefTimer, hostname: __bootstrap.os.hostname, + consoleSize: __bootstrap.tty.consoleSize, }; __bootstrap.denoNsUnstable = { - consoleSize: __bootstrap.tty.consoleSize, DiagnosticCategory: __bootstrap.diagnostics.DiagnosticCategory, osRelease: __bootstrap.os.osRelease, systemMemoryInfo: __bootstrap.os.systemMemoryInfo, diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index f8dae1d265..6382f967fc 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -192,48 +192,66 @@ fn op_isatty( #[op(fast)] fn op_console_size( state: &mut OpState, - rid: u32, result: &mut [u32], ) -> Result<(), AnyError> { - super::check_unstable(state, "Deno.consoleSize"); - StdFileResource::with_file(state, rid, move |std_file| { - #[cfg(windows)] - { - use std::os::windows::io::AsRawHandle; - let handle = std_file.as_raw_handle(); + fn check_console_size( + state: &mut OpState, + result: &mut [u32], + rid: u32, + ) -> Result<(), AnyError> { + StdFileResource::with_file(state, rid, move |std_file| { + #[cfg(windows)] + { + use std::os::windows::io::AsRawHandle; + let handle = std_file.as_raw_handle(); - // SAFETY: winapi calls - unsafe { - let mut bufinfo: winapi::um::wincon::CONSOLE_SCREEN_BUFFER_INFO = - std::mem::zeroed(); + // SAFETY: winapi calls + unsafe { + let mut bufinfo: winapi::um::wincon::CONSOLE_SCREEN_BUFFER_INFO = + std::mem::zeroed(); - if winapi::um::wincon::GetConsoleScreenBufferInfo(handle, &mut bufinfo) - == 0 - { - return Err(Error::last_os_error().into()); + if winapi::um::wincon::GetConsoleScreenBufferInfo( + handle, + &mut bufinfo, + ) == 0 + { + return Err(Error::last_os_error().into()); + } + result[0] = bufinfo.dwSize.X as u32; + result[1] = bufinfo.dwSize.Y as u32; + Ok(()) } - result[0] = bufinfo.dwSize.X as u32; - result[1] = bufinfo.dwSize.Y as u32; - Ok(()) } - } - #[cfg(unix)] - { - use std::os::unix::io::AsRawFd; + #[cfg(unix)] + { + use std::os::unix::io::AsRawFd; - let fd = std_file.as_raw_fd(); - // TODO(bartlomieju): - #[allow(clippy::undocumented_unsafe_blocks)] - unsafe { - let mut size: libc::winsize = std::mem::zeroed(); - if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 { - return Err(Error::last_os_error().into()); + let fd = std_file.as_raw_fd(); + // TODO(bartlomieju): + #[allow(clippy::undocumented_unsafe_blocks)] + unsafe { + let mut size: libc::winsize = std::mem::zeroed(); + if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 { + return Err(Error::last_os_error().into()); + } + result[0] = size.ws_col as u32; + result[1] = size.ws_row as u32; + Ok(()) } - result[0] = size.ws_col as u32; - result[1] = size.ws_row as u32; - Ok(()) } + }) + } + + let mut last_result = Ok(()); + // Since stdio might be piped we try to get the size of the console for all + // of them and return the first one that succeeds. + for rid in [0, 1, 2] { + last_result = check_console_size(state, result, rid); + if last_result.is_ok() { + return last_result; } - }) + } + + last_result } diff --git a/test_util/std b/test_util/std index 0ce558fec1..f2c97ea9c3 160000 --- a/test_util/std +++ b/test_util/std @@ -1 +1 @@ -Subproject commit 0ce558fec1a1beeda3ed7710c6507b9e991829c9 +Subproject commit f2c97ea9c382fb3e225929c7650934417e2fc8c9