Repository navigation
Introduce a wrapper on std::io::Stdin that checks for closed STDIN before reading
#15835
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
base: main
Are you sure you want to change the base?
Changes from all commits
6a76613
c31f5b8
9782396
6997ad6
7a8cf86
63ba0b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -191,6 +191,7 @@ unportable | |
| unsync | ||
| unwritable | ||
| urand | ||
| ustdin | ||
| utimensat | ||
| whitespace | ||
| wordlist | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -154,7 +154,14 @@ default = ["signals"] | |||||
| backup-control = [] | ||||||
| colors = [] | ||||||
| diagnostics = ["dep:ariadne"] | ||||||
| checksum = ["base64-simd", "quoting-style", "rustix/fs", "sum"] | ||||||
| checksum = [ | ||||||
| "base64-simd", | ||||||
| "quoting-style", | ||||||
| "rustix/fs", | ||||||
| "signals", | ||||||
| "stdio", | ||||||
| "sum", | ||||||
| ] | ||||||
| encoding = ["data-encoding", "data-encoding-macro", "z85", "base64-simd"] | ||||||
| entries = ["libc", "rustix/fs", "rustix/process"] | ||||||
| extendedbigdecimal = ["bigdecimal", "num-traits"] | ||||||
|
|
@@ -203,6 +210,7 @@ safe-traversal = ["libc", "nix/fs", "nix/dir", "nix/user", "rustix/fs"] | |||||
| selinux = ["dep:selinux", "libc"] | ||||||
| smack = ["xattr"] | ||||||
| signals = ["nix/fs", "nix/signal", "nix/poll"] | ||||||
| stdio = [] | ||||||
|
Collaborator
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.
Suggested change
we should enable the
Collaborator
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. Not sure about that. I made the |
||||||
| sum = [ | ||||||
| "digest", | ||||||
| "hex", | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| use std::io; | ||
|
|
||
| #[cfg(all(feature = "signals", unix, not(target_os = "fuchsia")))] | ||
| use crate::{signals, translate}; | ||
|
RenjiSann marked this conversation as resolved.
RenjiSann marked this conversation as resolved.
|
||
|
|
||
| #[cfg_attr( | ||
| not(all(feature = "signals", unix, not(target_os = "fuchsia"))), | ||
| expect(clippy::unnecessary_wraps) | ||
| )] | ||
| fn err_if_stdin_closed() -> io::Result<()> { | ||
| #[cfg(all(feature = "signals", unix, not(target_os = "fuchsia")))] | ||
| if signals::stdin_was_closed() { | ||
| return Err(io::Error::other(translate!("error-bad-file-descriptor"))); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| /// Wrapper around [`std::io::Stdin`] that checks if stdin was closed | ||
| /// before trying to read. | ||
| pub struct UStdin { | ||
| inner: io::Stdin, | ||
| } | ||
|
|
||
| impl UStdin { | ||
| pub fn lock(&self) -> UStdinLock<'static> { | ||
| UStdinLock { | ||
| inner: self.inner.lock(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl io::Read for UStdin { | ||
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read(buf) | ||
| } | ||
|
|
||
| fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read_to_end(buf) | ||
| } | ||
|
|
||
| fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { | ||
|
RenjiSann marked this conversation as resolved.
|
||
| err_if_stdin_closed()?; | ||
| self.inner.read_to_string(buf) | ||
| } | ||
|
|
||
| fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read_exact(buf) | ||
| } | ||
| } | ||
|
|
||
| pub struct UStdinLock<'a> { | ||
| inner: io::StdinLock<'a>, | ||
| } | ||
|
|
||
| impl io::Read for UStdinLock<'_> { | ||
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read(buf) | ||
| } | ||
|
|
||
| fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read_to_end(buf) | ||
| } | ||
|
|
||
| fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read_to_string(buf) | ||
| } | ||
|
|
||
| fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.read_exact(buf) | ||
| } | ||
| } | ||
|
|
||
| impl io::BufRead for UStdinLock<'_> { | ||
| fn fill_buf(&mut self) -> io::Result<&[u8]> { | ||
| err_if_stdin_closed()?; | ||
| self.inner.fill_buf() | ||
| } | ||
|
|
||
| fn consume(&mut self, amount: usize) { | ||
| self.inner.consume(amount); | ||
| } | ||
| } | ||
|
|
||
| pub fn ustdin() -> UStdin { | ||
|
Collaborator
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'd probably just name this
Collaborator
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. why not follow the naming of other wrappers of uucore (like
Collaborator
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’m not particularly fond of the naming of those types either, but they’re very common return types, so disambiguation may be necessary. That doesn’t apply in this case, though.
Collaborator
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 name |
||
| UStdin { inner: io::stdin() } | ||
| } | ||
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.
Going forward, it would be better to keep unrelated style changes in a separate commit.