-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Fix isatty in WASI.
#3696
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
Fix isatty in WASI.
#3696
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,7 +35,11 @@ impl WasiFile for Stdin { | |
| Ok(()) | ||
| } | ||
| async fn get_filetype(&self) -> Result<FileType, Error> { | ||
| Ok(FileType::Unknown) | ||
| if self.isatty() { | ||
| Ok(FileType::CharacterDevice) | ||
| } else { | ||
| Ok(FileType::Unknown) | ||
| } | ||
| } | ||
| async fn get_fdflags(&self) -> Result<FdFlags, Error> { | ||
| Ok(FdFlags::empty()) | ||
|
|
@@ -104,6 +108,16 @@ impl WasiFile for Stdin { | |
| async fn num_ready_bytes(&self) -> Result<u64, Error> { | ||
| Ok(self.0.num_ready_bytes()?) | ||
| } | ||
| fn isatty(&self) -> bool { | ||
| #[cfg(unix)] | ||
| { | ||
| rustix::io::isatty(&self.0) | ||
| } | ||
| #[cfg(not(unix))] | ||
| { | ||
| atty::is(atty::Stream::Stdin) | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Linux rustix can use inline asm, while atty always uses libc.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My reason for using rustix here was that cap-std-sync already depends on rustix for other things, so this avoids adding a new dependency on Rustix's isatty uses the same ioctl as musl, which is a different ioctl from what glibc uses, but the difference shouldn't matter in practice.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm ok, personally I'm not a fan of having a lot of "if linux else everyone else this" because it seems like it'll just cause tons of Linux-specific or not-Linux-specific issues. This is pretty minor though.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The actual change uses
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh sure but it's the same thing with Windows. Crates like But again this is personal preference and this is minor. I don't like to pervasively use platform-specific crates, instead using platform-specific crates in very specific situations and otherwise favoring platform-agnostic crates for heavy usage.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've now factored this to use a platform-agnostic crate, so that Wasmtime's own code avoids the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify I'm fine either way, mostly just stating my own personal preference. But also, this looks the same as before, so unsure if this is intended to stay as-is or whether a commit was forgotten? (this PR is fine to merge whenever imo, I don't feel any need to debate fine detatils like this)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one now has
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's consistent with And, I'm working on a change which will help; I plan to replace all these isatty implementations with a new is-terminal crate which supports windows, unix, and (to the extent possible) non-windows-non-unix with a single API. I'll do it in a separate PR because I need to make a few other changes to avoid cargo deny flagging it for duplicate dependency versions. |
||
| } | ||
| async fn readable(&self) -> Result<(), Error> { | ||
| Err(Error::badf()) | ||
| } | ||
|
|
@@ -125,7 +139,7 @@ impl AsFd for Stdin { | |
| } | ||
|
|
||
| macro_rules! wasi_file_write_impl { | ||
| ($ty:ty) => { | ||
| ($ty:ty, $ident:ident) => { | ||
| #[async_trait::async_trait] | ||
| impl WasiFile for $ty { | ||
| fn as_any(&self) -> &dyn Any { | ||
|
|
@@ -138,7 +152,11 @@ macro_rules! wasi_file_write_impl { | |
| Ok(()) | ||
| } | ||
| async fn get_filetype(&self) -> Result<FileType, Error> { | ||
| Ok(FileType::Unknown) | ||
| if self.isatty() { | ||
| Ok(FileType::CharacterDevice) | ||
| } else { | ||
| Ok(FileType::Unknown) | ||
| } | ||
| } | ||
| async fn get_fdflags(&self) -> Result<FdFlags, Error> { | ||
| Ok(FdFlags::APPEND) | ||
|
|
@@ -210,6 +228,16 @@ macro_rules! wasi_file_write_impl { | |
| async fn num_ready_bytes(&self) -> Result<u64, Error> { | ||
| Ok(0) | ||
| } | ||
| fn isatty(&self) -> bool { | ||
| #[cfg(unix)] | ||
| { | ||
| rustix::io::isatty(&self.0) | ||
| } | ||
| #[cfg(not(unix))] | ||
| { | ||
| atty::is(atty::Stream::$ident) | ||
| } | ||
| } | ||
| async fn readable(&self) -> Result<(), Error> { | ||
| Err(Error::badf()) | ||
| } | ||
|
|
@@ -237,11 +265,11 @@ pub struct Stdout(std::io::Stdout); | |
| pub fn stdout() -> Stdout { | ||
| Stdout(std::io::stdout()) | ||
| } | ||
| wasi_file_write_impl!(Stdout); | ||
| wasi_file_write_impl!(Stdout, Stdout); | ||
|
|
||
| pub struct Stderr(std::io::Stderr); | ||
|
|
||
| pub fn stderr() -> Stderr { | ||
| Stderr(std::io::stderr()) | ||
| } | ||
| wasi_file_write_impl!(Stderr); | ||
| wasi_file_write_impl!(Stderr, Stderr); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be cfg(unix) and cfg(not(unix)) instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the first to
cfg(unix), but I thinkcfg(windows)makes sense for the second. If we port to a non-Unix non-Windows platform in the future, we should figure out whatisattymeans for that platform.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The atty crate would figure that out, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in its current form, because the atty crate currently has no interface for passing in a handle. It just supports literal stdin, stdout, and stderr. Possibly that will change in the future, and then we could simplify code like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case yes, but in stdio.rs you are using atty on stdin only for windows. There the
#[cfg(windows)]can be turned into#[cfg(not(unix))]without issues.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. I've now made this change.