-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Expose raw Stdout/err/in #58326
Comments
This is similar to #23818, where having more control over the buffering/flushing behavior of stdio/stdin would be helpfull. |
So I've been thinking about the same thing while working on #58454. I do wonder how useful it they would be though.
I don't think
pub struct Stdout {
// FIXME: this should be LineWriter or BufWriter depending on the state of
// stdout (tty or not). Note that if this is not line buffered it
// should also flush-on-panic or some form of flush-on-abort.
inner: Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>,
} Working on this would change flushing behavior for piped buffered stdout, but is not at all relevant for
Another point, the Windows stdio implementation turns out to be quite tricky because it converts from UTF-8 to UTF-16 when writing to the console, but accepts arbitrary bytes when writing to a pipe. Ideally Finally the non-raw types have a Some advantages the
A single synchronized |
Oh, I wasn't aware that
A slight advantage is that you can more easily check if any of them are not present, since the raw functions return
I agree a |
Sorry, just made a PR to that makes them no longer return a I am still trying to make up my mind whether writing up a pre-RFC or PR to expose the
I am preparing a PR that switches the buffering mode between |
One big question is should we have |
I would like to be able to set the capacity of the inner |
After further investigation it looks like writing directly to the underlying |
This led to an otherwise-unnecessary use of This is an unfortunate data loss bug that is entirely non-obvious in the library and not blocked by the type system. |
In my application I need to forward I/O from a serial port to stdio, and the serial port is an interactive console where the remote device echoes the characters back if they should be printed on the terminal, and controls various other aspects of the terminal. (Come to think of it, It doesn't have to be a serial port, another similar example with this behavior is an SSH client) Line-buffered stdin simply does not work for this case; action needs to be taken for every input byte, not for every line. |
Having line-buffered stdout is also an unnecessary performance overhead when outputting binary data. First the code scans for newlines to only partially write the bytes to stdout and copy the remaining bytes into a buffer, only for me to flush the remaining bytes out. One syscall too many for every write that I do and unnecessary buffer copying. |
Created a proposal for this: rust-lang/libs-team#148 |
If anyone else came across this issue while looking for a workaround, this is what I'm using right now. use std::{fs::File, io};
#[cfg(unix)]
pub fn stdout_raw() -> File {
use std::os::fd::{AsRawFd, FromRawFd};
let stdout = io::stdout();
let raw_fd = stdout.as_raw_fd(); // or just use `1`
unsafe { File::from_raw_fd(raw_fd) }
}
#[cfg(windows)]
pub fn stdout_raw() -> File {
use std::os::windows::io::{AsRawHandle, FromRawHandle};
let stdout = io::stdout();
let raw_handle = stdout.as_raw_handle();
unsafe { File::from_raw_handle(raw_handle) }
}
#[cfg(test)]
mod test {
use super::*;
use std::io::{self, Write};
#[test]
fn rawwwwww() -> io::Result<()> {
let mut stdout = stdout_raw();
stdout.write_all(b"This stdout... is RAWWWWWW!!!")?;
Ok(())
}
} |
In Filespooler, for Unix, I am using:
FWIW |
AFAICT, both of these will close the actual stdin/stdout FD once the returned file gets dropped. This is probably not intended. Additionally, the solution posted by @jgoerzen looks like it's trying to lock stdin, but the lock is immediately dropped after the function is returned. |
Definitely wouldn't recommend using my snippet for any serious/larger code, it's just suggested as a quick and dirty workaround for trivial but IO intensive scenario. In my case I was solving an algorithm problem when I encountered this. |
Currently there is not easy/obvious way to get an unbuffered Stdout/err/in. The types do exist in stdio, however they are not public for reasons not noted.
For example these types would be useful for CLI applications that write a lot of data at once without it getting unnecessarily flushed.
One can use platform specific extensions such as
from_raw_fd
on unix, andfrom _raw_handle
on windows as a workaround.The text was updated successfully, but these errors were encountered: