summaryrefslogtreecommitdiff
path: root/cli/ops/tty.rs
diff options
context:
space:
mode:
authorSebastien Filion <sebastienfilion@mac.com>2020-07-10 10:07:12 -0400
committerGitHub <noreply@github.com>2020-07-10 10:07:12 -0400
commit1bcc35b84a78fb052b8092b7ed57c2ce763f5d4b (patch)
tree913a4533901ba35bf47012009c0fa4c88b8ebe60 /cli/ops/tty.rs
parentdc6b3ef714c743358703512cd766aed4abc8bd3b (diff)
feat(unstable): add Deno.consoleSize (#6520)
Diffstat (limited to 'cli/ops/tty.rs')
-rw-r--r--cli/ops/tty.rs80
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)))
+}