Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tty: Deno.setRaw(rid, mode) to turn on/off raw mode #3958

Merged
merged 22 commits into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,6 @@ nix = "0.14.1"

[dev-dependencies]
os_pipe = "0.9.1"

[target.'cfg(unix)'.dev-dependencies]
pty = "0.2"
2 changes: 1 addition & 1 deletion cli/js/deno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export {
dir,
env,
exit,
isTTY,
execPath,
hostname,
loadavg,
Expand Down Expand Up @@ -124,6 +123,7 @@ export { statSync, lstatSync, stat, lstat } from "./stat.ts";
export { symlinkSync, symlink } from "./symlink.ts";
export { connectTLS, listenTLS } from "./tls.ts";
export { truncateSync, truncate } from "./truncate.ts";
export { isatty, setRaw } from "./tty.ts";
export { utimeSync, utime } from "./utime.ts";
export { version } from "./version.ts";
export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts";
Expand Down
25 changes: 15 additions & 10 deletions cli/js/lib.deno.ns.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ declare namespace Deno {

export function runTests(opts?: RunTestsOptions): Promise<void>;

/** Check if running in terminal.
*
* console.log(Deno.isTTY().stdout);
*/
export function isTTY(): {
stdin: boolean;
stdout: boolean;
stderr: boolean;
};

/** Get the loadavg. Requires the `--allow-env` flag.
*
* console.log(Deno.loadavg());
Expand Down Expand Up @@ -492,6 +482,7 @@ declare namespace Deno {
seekSync(offset: number, whence: SeekMode): void;
close(): void;
}

/** An instance of `File` for stdin. */
export const stdin: File;
/** An instance of `File` for stdout. */
Expand Down Expand Up @@ -555,6 +546,20 @@ declare namespace Deno {
/** Read-write. Behaves like `x` and allows to read from file. */
| "x+";

// @url js/tty.d.ts

/** UNSTABLE: newly added API
*
* Check if a given resource is TTY
*/
export function isatty(rid: number): boolean;

/** UNSTABLE: newly added API
*
* Set TTY to be under raw mode or not.
*/
export function setRaw(rid: number, mode: boolean): void;

// @url js/buffer.d.ts

/** A Buffer is a variable-sized buffer of bytes with read() and write()
Expand Down
7 changes: 0 additions & 7 deletions cli/js/os.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ import { sendSync } from "./dispatch_json.ts";
import { errors } from "./errors.ts";
import * as util from "./util.ts";

/** Check if running in terminal.
*
* console.log(Deno.isTTY().stdout);
*/
export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } {
return sendSync("op_is_tty");
}
/** Get the loadavg.
* Requires the `--allow-env` flag.
*
Expand Down
4 changes: 0 additions & 4 deletions cli/js/os_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ test(function osPid(): void {
assert(Deno.pid > 0);
});

test(function osIsTTYSmoke(): void {
console.log(Deno.isTTY());
});

testPerm({ env: true }, function getDir(): void {
type supportOS = "mac" | "win" | "linux";

Expand Down
14 changes: 14 additions & 0 deletions cli/js/tty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { sendSync } from "./dispatch_json.ts";

/** Check if a given resource is TTY. */
export function isatty(rid: number): boolean {
return sendSync("op_isatty", { rid });
}

/** Set TTY to be under raw mode or not. */
export function setRaw(rid: number, mode: boolean): void {
sendSync("op_set_raw", {
rid,
mode
});
}
22 changes: 22 additions & 0 deletions cli/js/tty_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { test, testPerm, assert } from "./test_util.ts";

// Note tests for Deno.setRaw is in integration tests.

testPerm({ read: true }, function isatty(): void {
// CI not under TTY, so cannot test stdin/stdout/stderr.
const f = Deno.openSync("cli/tests/hello.txt");
assert(!Deno.isatty(f.rid));
});

test(function isattyError(): void {
let caught = false;
try {
// Absurdly large rid.
Deno.isatty(0x7fffffff);
} catch (e) {
caught = true;
assert(e instanceof Deno.errors.BadResource);
}
assert(caught);
});
1 change: 1 addition & 0 deletions cli/js/unit_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import "./text_encoding_test.ts";
import "./timers_test.ts";
import "./tls_test.ts";
import "./truncate_test.ts";
import "./tty_test.ts";
import "./url_test.ts";
import "./url_search_params_test.ts";
import "./utime_test.ts";
Expand Down
11 changes: 6 additions & 5 deletions cli/ops/files.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use super::io::{FileMetadata, StreamResource};
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::state::State;
Expand Down Expand Up @@ -125,9 +125,10 @@ fn op_open(
let fut = async move {
let fs_file = open_options.open(filename).await?;
let mut state = state_.borrow_mut();
let rid = state
.resource_table
.add("fsFile", Box::new(StreamResource::FsFile(fs_file)));
let rid = state.resource_table.add(
"fsFile",
Box::new(StreamResource::FsFile(fs_file, FileMetadata::default())),
);
Ok(json!(rid))
};

Expand Down Expand Up @@ -197,7 +198,7 @@ fn op_seek(
.ok_or_else(OpError::bad_resource)?;

let tokio_file = match resource {
StreamResource::FsFile(ref file) => file,
StreamResource::FsFile(ref file, _) => file,
_ => return Err(OpError::bad_resource()),
};
let mut file = futures::executor::block_on(tokio_file.try_clone())?;
Expand Down
28 changes: 21 additions & 7 deletions cli/ops/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn init(i: &mut Isolate, s: &State) {
}

pub fn get_stdio() -> (StreamResource, StreamResource, StreamResource) {
let stdin = StreamResource::Stdin(tokio::io::stdin());
let stdin = StreamResource::Stdin(tokio::io::stdin(), TTYMetadata::default());
let stdout = StreamResource::Stdout({
let stdout = STDOUT_HANDLE
.try_clone()
Expand All @@ -69,11 +69,25 @@ pub fn get_stdio() -> (StreamResource, StreamResource, StreamResource) {
(stdin, stdout, stderr)
}

#[cfg(unix)]
use nix::sys::termios;

#[derive(Default)]
pub struct TTYMetadata {
#[cfg(unix)]
pub mode: Option<termios::Termios>,
}

#[derive(Default)]
pub struct FileMetadata {
pub tty: TTYMetadata,
}

pub enum StreamResource {
Stdin(tokio::io::Stdin),
Stdin(tokio::io::Stdin, TTYMetadata),
Stdout(tokio::fs::File),
Stderr(tokio::io::Stderr),
FsFile(tokio::fs::File),
FsFile(tokio::fs::File, FileMetadata),
TcpStream(tokio::net::TcpStream),
ServerTlsStream(Box<ServerTlsStream<TcpStream>>),
ClientTlsStream(Box<ClientTlsStream<TcpStream>>),
Expand Down Expand Up @@ -101,8 +115,8 @@ impl DenoAsyncRead for StreamResource {
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncRead>> = match self {
FsFile(f) => Box::pin(f),
Stdin(f) => Box::pin(f),
FsFile(f, _) => Box::pin(f),
Stdin(f, _) => Box::pin(f),
TcpStream(f) => Box::pin(f),
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
Expand Down Expand Up @@ -203,7 +217,7 @@ impl DenoAsyncWrite for StreamResource {
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f) => Box::pin(f),
FsFile(f, _) => Box::pin(f),
Stdout(f) => Box::pin(f),
Stderr(f) => Box::pin(f),
TcpStream(f) => Box::pin(f),
Expand All @@ -220,7 +234,7 @@ impl DenoAsyncWrite for StreamResource {
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f) => Box::pin(f),
FsFile(f, _) => Box::pin(f),
Stdout(f) => Box::pin(f),
Stderr(f) => Box::pin(f),
TcpStream(f) => Box::pin(f),
Expand Down
1 change: 1 addition & 0 deletions cli/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ pub mod runtime_compiler;
pub mod signal;
pub mod timers;
pub mod tls;
pub mod tty;
pub mod web_worker;
pub mod worker_host;
14 changes: 0 additions & 14 deletions cli/ops/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::op_error::OpError;
use crate::state::State;
use atty;
use deno_core::*;
use std::collections::HashMap;
use std::env;
Expand All @@ -12,7 +11,6 @@ use url::Url;

pub fn init(i: &mut Isolate, s: &State) {
i.register_op("op_exit", s.stateful_json_op(op_exit));
i.register_op("op_is_tty", s.stateful_json_op(op_is_tty));
i.register_op("op_env", s.stateful_json_op(op_env));
i.register_op("op_exec_path", s.stateful_json_op(op_exec_path));
i.register_op("op_set_env", s.stateful_json_op(op_set_env));
Expand Down Expand Up @@ -151,18 +149,6 @@ fn op_exit(
std::process::exit(args.code)
}

fn op_is_tty(
_s: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, OpError> {
Ok(JsonOp::Sync(json!({
"stdin": atty::is(atty::Stream::Stdin),
"stdout": atty::is(atty::Stream::Stdout),
"stderr": atty::is(atty::Stream::Stderr),
})))
}
ry marked this conversation as resolved.
Show resolved Hide resolved

fn op_loadavg(
state: &State,
_args: Value,
Expand Down
2 changes: 1 addition & 1 deletion cli/ops/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn clone_file(rid: u32, state: &State) -> Result<std::fs::File, OpError> {
.get_mut::<StreamResource>(rid)
.ok_or_else(OpError::bad_resource)?;
let file = match repr {
StreamResource::FsFile(ref mut file) => file,
StreamResource::FsFile(ref mut file, _) => file,
_ => return Err(OpError::bad_resource()),
};
let tokio_file = futures::executor::block_on(file.try_clone())?;
Expand Down
Loading