summaryrefslogtreecommitdiff
path: root/cli/ops/tty.rs
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2020-04-15 20:43:19 -0400
committerGitHub <noreply@github.com>2020-04-15 20:43:19 -0400
commitfab0204cbf20cc1be7874266325bf258fe0ecaca (patch)
treec67b3febde254ea36122966aadf13dfb62b67a0e /cli/ops/tty.rs
parent7cfd094359f7f94573b084328ad1a956dd70005d (diff)
Make writeSync, readSync, seekSync, openSync, isatty proper synchronous syscalls (#4762)
Diffstat (limited to 'cli/ops/tty.rs')
-rw-r--r--cli/ops/tty.rs89
1 files changed, 40 insertions, 49 deletions
diff --git a/cli/ops/tty.rs b/cli/ops/tty.rs
index ebe6c39e3..461c1ca30 100644
--- a/cli/ops/tty.rs
+++ b/cli/ops/tty.rs
@@ -1,4 +1,5 @@
use super::dispatch_json::JsonOp;
+use super::io::std_file_resource;
use super::io::{StreamResource, StreamResourceHolder};
use crate::op_error::OpError;
use crate::ops::json_op;
@@ -73,13 +74,16 @@ pub fn op_set_raw(
// For now, only stdin.
let handle = match &resource_holder.unwrap().resource {
StreamResource::Stdin(_, _) => std::io::stdin().as_raw_handle(),
- StreamResource::FsFile(f, _) => {
+ StreamResource::FsFile(None) => {
+ return Err(OpError::resource_unavailable())
+ }
+ StreamResource::FsFile(Some((f, _))) => {
let tokio_file = futures::executor::block_on(f.try_clone())?;
let std_file = futures::executor::block_on(tokio_file.into_std());
std_file.as_raw_handle()
}
_ => {
- return Err(OpError::other("Not supported".to_owned()));
+ return Err(OpError::bad_resource_id());
}
};
@@ -122,11 +126,14 @@ pub fn op_set_raw(
StreamResource::Stdin(_, ref mut metadata) => {
(std::io::stdin().as_raw_fd(), &mut metadata.mode)
}
- StreamResource::FsFile(f, ref mut metadata) => {
+ StreamResource::FsFile(Some((f, ref mut metadata))) => {
let tokio_file = futures::executor::block_on(f.try_clone())?;
let std_file = futures::executor::block_on(tokio_file.into_std());
(std_file.as_raw_fd(), &mut metadata.tty.mode)
}
+ StreamResource::FsFile(None) => {
+ return Err(OpError::resource_unavailable())
+ }
_ => {
return Err(OpError::other("Not supported".to_owned()));
}
@@ -165,13 +172,16 @@ pub fn op_set_raw(
StreamResource::Stdin(_, ref mut metadata) => {
(std::io::stdin().as_raw_fd(), &mut metadata.mode)
}
- StreamResource::FsFile(f, ref mut metadata) => {
+ StreamResource::FsFile(Some((f, ref mut metadata))) => {
let tokio_file = futures::executor::block_on(f.try_clone())?;
let std_file = futures::executor::block_on(tokio_file.into_std());
(std_file.as_raw_fd(), &mut metadata.tty.mode)
}
+ StreamResource::FsFile(None) => {
+ return Err(OpError::resource_unavailable());
+ }
_ => {
- return Err(OpError::other("Not supported".to_owned()));
+ return Err(OpError::bad_resource_id());
}
};
@@ -190,55 +200,36 @@ struct IsattyArgs {
}
pub fn op_isatty(
- state_: &State,
+ state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, OpError> {
let args: IsattyArgs = serde_json::from_value(args)?;
let rid = args.rid;
- let state = state_.borrow_mut();
- if !state.resource_table.has(rid) {
- return Err(OpError::bad_resource_id());
- }
-
- let resource_holder = state.resource_table.get::<StreamResourceHolder>(rid);
- if resource_holder.is_none() {
- return Ok(JsonOp::Sync(json!(false)));
- }
-
- match &resource_holder.unwrap().resource {
- StreamResource::Stdin(_, _) => {
- Ok(JsonOp::Sync(json!(atty::is(atty::Stream::Stdin))))
- }
- StreamResource::Stdout(_) => {
- Ok(JsonOp::Sync(json!(atty::is(atty::Stream::Stdout))))
- }
- StreamResource::Stderr(_) => {
- Ok(JsonOp::Sync(json!(atty::is(atty::Stream::Stderr))))
- }
- StreamResource::FsFile(f, _) => {
- let tokio_file = futures::executor::block_on(f.try_clone())?;
- let std_file = futures::executor::block_on(tokio_file.into_std());
- #[cfg(windows)]
- {
- use winapi::um::consoleapi;
-
- let handle = get_windows_handle(&std_file)?;
- let mut test_mode: DWORD = 0;
- // If I cannot get mode out of console, it is not a console.
- let result =
- unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != 0 };
- Ok(JsonOp::Sync(json!(result)))
+ let resource_table = &mut state.borrow_mut().resource_table;
+ let isatty: bool =
+ std_file_resource(resource_table, rid as u32, move |r| match r {
+ Ok(std_file) => {
+ #[cfg(windows)]
+ {
+ use winapi::um::consoleapi;
+
+ let handle = get_windows_handle(&std_file)?;
+ let mut test_mode: DWORD = 0;
+ // If I cannot get mode out of console, it is not a console.
+ Ok(unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != 0 })
+ }
+ #[cfg(unix)]
+ {
+ use std::os::unix::io::AsRawFd;
+ let raw_fd = std_file.as_raw_fd();
+ Ok(unsafe { libc::isatty(raw_fd as libc::c_int) == 1 })
+ }
}
- #[cfg(unix)]
- {
- use std::os::unix::io::AsRawFd;
- let raw_fd = std_file.as_raw_fd();
- let result = unsafe { libc::isatty(raw_fd as libc::c_int) == 1 };
- Ok(JsonOp::Sync(json!(result)))
- }
- }
- _ => Ok(JsonOp::Sync(json!(false))),
- }
+ Err(StreamResource::FsFile(_)) => unreachable!(),
+ Err(StreamResource::Stdin(_, _)) => Ok(atty::is(atty::Stream::Stdin)),
+ _ => Ok(false),
+ })?;
+ Ok(JsonOp::Sync(json!(isatty)))
}