-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
stdio handles (stdin, stdout, stderr) should be Seek
at least on Unix
#72802
Comments
The stdin/stdout handles on Windows can also be file handles, in which case seeking can function correctly. So therefore this feature request applies equally well to Windows. That said, I question what sort of use case you have where you need to seek stdin/stdout. |
@retep998 in ACM with tough memory limits and a lot of reads you may want to read input several times instead of allocating tons of additional memory. |
I'm currently writing a tool that needs to be able to produce a very large output file, and write each block of that output file in a semi-random order. Its output file is specified by redirecting stdout. This particular tool could be changed to accept its output file as a command line argument, but if I were writing a tool that needed to avoid file creation race conditions (like the ones |
I use this hack where it is ok. It looses already buffered input and is platform specific, though: let lock = std::io::stdin().lock();
#[cfg(any(target_family="unix", target_family="wasi"))]
let mut seekable_stdin = unsafe {
use std::os::unix::io::{AsRawFd, FromRawFd};
std::fs::File::from_raw_fd(lock.as_raw_fd())
};
#[cfg(target_family="windows")]
let mut seekable_stdin = unsafe {
use std::os::windows::io::{AsRawHandle, FromRawHandle};
std::fs::File::from_raw_handle(lock.as_raw_handle())
}; The question is with non-lexical lifetimes how can I be sure the lock is held long enough? Can I be sure if I do an explicit |
What's the way forward here? I'm confused why this is classified as an "enhancement" isn't this arguably more of a "bug"/question of design? Btw, here's the current implementation for File in unix: rust/library/std/src/sys/unix/fs.rs Lines 1164 to 1174 in ac4379f
|
Currently,
std::io::Stdin
et al do not implementSeek
.It is true that a Unix program is not guaranteed that its stdin/stdout/stderr will be seekable. Often they won't be. But, they may be. If stdin is redirected from a file, for example,
lseek
(the system call) will work fine.The
Seek
trait does not promise thatseek
actually works.seek
returnsio::Result
(quite properly). Indeed astd::io::File
object can easily refer to a non-seekable object, depending what path was passed.Conversely, not implementing
Seek
makes it impossible to perform this operation in safe Rust. There are perhaps some workarounds like asking to open/dev/stdin
, but they are non-portable and often quite horrible. Usingunsafe { libc::lseek(...) }
is quite straightforward (apart, perhaps, from a question about whetherlseek64
should be used instead) but we shouldn't expect our users to do that when we could have provided a safe way.There are file data integrity and synchronisation issues with
Seek
. But these are not significantly worse for stdin/out/err than forstd::fs::File
. They are not a memory safety issue and we have already chosen to address this in the documentation rather than through the type system.I come from a Unix background. I don't know what the situation is on Windows. But, the fact that in Standard C, it is legal to call
fseek
onstdin
(for example) suggests that the correct answer for Rust is to permit the user to try to callseek
on all platforms.The text was updated successfully, but these errors were encountered: