Skip to content
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

Need a way to close standard output #40032

Open
zackw opened this issue Feb 22, 2017 · 5 comments
Open

Need a way to close standard output #40032

zackw opened this issue Feb 22, 2017 · 5 comments
Labels
C-feature-accepted Category: A feature request that has been accepted pending implementation. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@zackw
Copy link
Contributor

zackw commented Feb 22, 2017

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.)

@steveklabnik steveklabnik added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Feb 22, 2017
@nagisa
Copy link
Member

nagisa commented Feb 22, 2017

For Windows it’s Nul Device Driver and SetStdHandle AFAICT.

@steveklabnik steveklabnik added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed A-libs labels Mar 24, 2017
@Mark-Simulacrum Mark-Simulacrum added C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Sep 10, 2017
@dtolnay dtolnay added C-feature-accepted Category: A feature request that has been accepted pending implementation. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 16, 2017
@dtolnay
Copy link
Member

dtolnay commented Nov 16, 2017

Seems reasonable to me. I would be interested in seeing an implementation of this in a PR.

@RalfJung
Copy link
Member

#75295 looks related... @tmiasko do you think your PR can be a first step towards solving this issue?

@ijackson
Copy link
Contributor

ijackson commented Nov 24, 2021

This seems related to #59567 (closed, "Add close method to File"), too.

@ChrisDenton
Copy link
Contributor

(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 GetStdHandle to get the relevant handle. These can be changed at any time using SetStdHandle. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-accepted Category: A feature request that has been accepted pending implementation. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants