Need a way to close standard output
It is sometimes appropriate for a program to close its standard output stream long before it's done running. For instance, I have a C program that sets up some system-wide state, waits for its parent to be done using that setup, and then tears it down again. (It's a separate program from the parent because it has to be setuid.) It notifies the parent that it's done setting up by closing its stdout, which is expected to be a pipe.
You can do this in Rust, but only by going behind the stdlib's back and calling libc::close(1). I would like there to be an official way to do this, without going behind the stdlib's back. A concrete proposal: Stdout (and Stderr) add a close method. These flush buffered output, close the underlying OS-level file descriptor, and then immediately reopen it on /dev/null, taking care to ensure that the well-known fd number is retained. It remains OK to use io::stdout() after calling close on it.
(Reopening the OS-level file descriptor on /dev/null is to accommodate third-party libraries that may assume it is always safe to write to file descriptors 1 and/or 2, and/or that the open() primitive will never return descriptors numbered 0, 1, or 2.)
(Windows doesn't exactly have "file descriptors" but it does have the concept of "standard handles" and there is a 1:1 mapping from the Unixy terms I used above to Windows equivalents.)
(For consistency, the internal method for "replacing Stdout and Stderr with an arbitrary instance of Write" (mentioned in #40007) should also perform this close operation.)
For Windows it’s Nul Device Driver and SetStdHandle AFAICT.
Simonas Kazlauskas at 2017-02-22 21:15:55
Seems reasonable to me. I would be interested in seeing an implementation of this in a PR.
David Tolnay at 2017-11-16 20:11:39
https://github.com/rust-lang/rust/pull/75295 looks related... @tmiasko do you think your PR can be a first step towards solving this issue?
Ralf Jung at 2020-09-25 06:29:47
This seems related to #59567 (closed, "Add close method to File"), too.
Ian Jackson at 2021-11-24 23:09:05
(Windows doesn't exactly have "file descriptors" but it does have the concept of "standard handles" and there is a 1:1 mapping from the Unixy terms I used above to Windows equivalents.)
This isn't quite true. Windows doesn't use magic handle values. Instead it uses
GetStdHandleto get the relevant handle. These can be changed at any time usingSetStdHandle. So closing the handle would be a two step process: firstly replace the handle with, say, 0; then close the handle.However, that second step is made much more risky because Rust allows getting the handle value from stdio. So if that handle is subsequently closed, it's a kind of "use after free" situation for anything that grabbed the handle value beforehand. The handle value could be reused for something completely different.
Chris Denton at 2021-11-25 08:40:39