diff options
Diffstat (limited to 'cli/ops/tty.rs')
-rw-r--r-- | cli/ops/tty.rs | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/cli/ops/tty.rs b/cli/ops/tty.rs index bf94ec17f..d86100232 100644 --- a/cli/ops/tty.rs +++ b/cli/ops/tty.rs @@ -8,7 +8,7 @@ use deno_core::CoreIsolateState; use deno_core::ZeroCopyBuf; #[cfg(unix)] use nix::sys::termios; -use serde_derive::Deserialize; +use serde_derive::{Deserialize, Serialize}; use serde_json::Value; #[cfg(windows)] @@ -38,6 +38,7 @@ fn get_windows_handle( pub fn init(i: &mut CoreIsolate, s: &State) { i.register_op("op_set_raw", s.stateful_json_op2(op_set_raw)); i.register_op("op_isatty", s.stateful_json_op2(op_isatty)); + i.register_op("op_console_size", s.stateful_json_op2(op_console_size)); } #[derive(Deserialize)] @@ -250,3 +251,80 @@ pub fn op_isatty( })?; Ok(JsonOp::Sync(json!(isatty))) } + +#[derive(Deserialize)] +struct ConsoleSizeArgs { + rid: u32, +} + +#[derive(Serialize)] +struct ConsoleSize { + columns: u32, + rows: u32, +} + +pub fn op_console_size( + isolate_state: &mut CoreIsolateState, + state: &State, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result<JsonOp, OpError> { + state.check_unstable("Deno.consoleSize"); + let args: ConsoleSizeArgs = serde_json::from_value(args)?; + let rid = args.rid; + + let mut resource_table = isolate_state.resource_table.borrow_mut(); + let size = + std_file_resource(&mut resource_table, rid as u32, move |r| match r { + Ok(std_file) => { + #[cfg(windows)] + { + use std::os::windows::io::AsRawHandle; + let handle = std_file.as_raw_handle(); + + unsafe { + let mut bufinfo: winapi::um::wincon::CONSOLE_SCREEN_BUFFER_INFO = + std::mem::zeroed(); + + if winapi::um::wincon::GetConsoleScreenBufferInfo( + handle, + &mut bufinfo, + ) == 0 + { + // TODO (caspervonb) use GetLastError + return Err(OpError::other( + winapi::um::errhandlingapi::GetLastError().to_string(), + )); + } + + Ok(ConsoleSize { + columns: bufinfo.dwSize.X as u32, + rows: bufinfo.dwSize.Y as u32, + }) + } + } + + #[cfg(unix)] + { + use std::os::unix::io::AsRawFd; + + let fd = std_file.as_raw_fd(); + unsafe { + let mut size: libc::winsize = std::mem::zeroed(); + if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 { + return Err(OpError::from(std::io::Error::last_os_error())); + } + + // TODO (caspervonb) return a tuple instead + Ok(ConsoleSize { + columns: size.ws_col as u32, + rows: size.ws_row as u32, + }) + } + } + } + Err(_) => Err(OpError::bad_resource_id()), + })?; + + Ok(JsonOp::Sync(json!(size))) +} |