-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
std::io::stdin() is causing significant trouble, losing data to its buffer #14434
Comments
With a little further thought, However, I do still defend the notion of passing By "argument to |
it looks like there's already a Would a solution here be that |
|
I'd rather see |
To begin with, we could rename it to Even if we change the standard streams to be arguments to main, chances are people who feel like using them deep within some code without having them passed down all the way from main will just go "gee, rust is making this too complicated" and call the libc stdio functions (and that will conflict with whatever we do, unless we go the C++ route of building our standard streams on top of stdio). |
cc me |
It seems like |
So it seems like there are two options: We can use thread-local |
io::stdin returns a new `BufferedReader` each time it's called, which results in some very confusing behavior with disappearing output. It now returns a `StdinReader`, which wraps a global singleton `Arc<Mutex<BufferedReader<StdReader>>`. `Reader` is implemented directly on `StdinReader`. However, `Buffer` is not, as the `fill_buf` method is fundamentaly un-thread safe. A `lock` method is defined on `StdinReader` which returns a smart pointer wrapping the underlying `BufferedReader` while guaranteeing mutual exclusion. Code that treats the return value of io::stdin as implementing `Buffer` will break. Add a call to `lock`: ```rust io::stdin().lines() // => io::stdin().lock().lines() ``` Closes rust-lang#14434 [breaking-change]
Buffered reading from stdin now needs to lock stdin. This is to solve [Rust issue #14434](rust-lang/rust#14434) which was a race condition on buffered reads from stdin. This change is to conform to the new API.
Buffered reading from stdin now needs to lock stdin. This is to solve rust-lang/rust#14434 which was a race condition on buffered reads from stdin. This change is to conform to the new API.
Buffered reading from stdin now needs to lock stdin. This is to solve rust-lang/rust#14434 which was a race condition on buffered reads from stdin. This change is to conform to the new API submitted as part of rust-lang/rust#19416.
Buffered reading from stdin now needs to lock stdin. This is to solve rust-lang/rust#14434 which was a race condition on buffered reads from stdin. This change is to conform to the new API submitted in rust-lang/rust@e7c1f57 as part of rust-lang/rust#19416.
fix: Use struct_tail_without_normalization in Expectation::rvalue_hint
Currently (for three months, since #12422),
stdin()
returns a buffered reader.This is causing lots of trouble with people that write
The first read will typically consume all the data from stdin, and so
b
ends upNone
, the rest of the firststdin()
call having mysteriously vanished.Documentation that you should only call
stdin()
once is not sufficient. It needs to be either a compile error in some way (once fn stdin()
!?) or callingstdin()
multiple times must be safe. (Causing task failure, “you’ve already called stdin()!”, would probably not be considered acceptable.)One suggestion is to switch it to using task-local storage. This is imperfect (reading stdin from multiple tasks is broken), but generally acceptable.
Having stdin/stdout/stderr as true globals in some way is another possibility.
Yet another suggestion, aired by @o11c, is passing stdin, stdout and stderr as arguments to
main
. (There are certainly significant difficulties with that scheme.)This needs to be fixed urgently. It appears to be tripping up a significant number of people and is very much non-obvious.
The text was updated successfully, but these errors were encountered: