diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2020-04-15 20:43:19 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-15 20:43:19 -0400 |
commit | fab0204cbf20cc1be7874266325bf258fe0ecaca (patch) | |
tree | c67b3febde254ea36122966aadf13dfb62b67a0e /cli/ops/tty.rs | |
parent | 7cfd094359f7f94573b084328ad1a956dd70005d (diff) |
Make writeSync, readSync, seekSync, openSync, isatty proper synchronous syscalls (#4762)
Diffstat (limited to 'cli/ops/tty.rs')
-rw-r--r-- | cli/ops/tty.rs | 89 |
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))) } |