-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: os/v2: Stdin, Stdout and Stderr should be interfaces #13473
Comments
It's not unheard-of to legitimately close stdio streams ("I'm done with you"). Would it be worth making these io.ReadCloser and io.WriteCloser, respectively (if we had a convenient writer equivalent to io.NopCloser)? An aside: since stdio streams are just the first 3 file descriptors (and are technically files), there's nothing to prevent your process from receiving a seekable regular file as stdin, or a file opened in rw mode for stdout, etc. This is a fairly common occurrence in practice (redirecting input from a file), but it's rare for applications to notice or care that, e.g. stdin might be able to do more than read bytes. However, the functionality needed to handle these very rare cases could be regained with a call to os.NewFile, passing in 0, 1, or 2 as the fd. |
An example of what I mean by the aside:
If we compile this as stdin-stat, we can run:
(above results correspond to darwin 14.5.0) |
I think we can support interfaced Stdin, Stdout and Stderr in go1.x
and redirect panic to StdoutV2 and redirect fmt.Println to StderrV2,etc.. I am writing a ios app with PacketTunnelExtension with golang which can see NSLog, but can not see the stdout and stderr .I can only rediect stdout and stderr into a temp file ,and read the content with next startup.It will be good to have a callback to rediect the panic content into NSLog. |
The *Vn thing looks too ugly to me. |
I agree. We have never added version numbers to an API and in fact, there
is a discussion on golang-dev about an interface that looked like versioned
when it is actually not, and the end result is that the interface is
renamed so that it doesn't have trailing numbers in its name. (search for
Import2 and ImportFrom on golang-dev, or see https://golang.org/cl/18630)
|
This is a long-term issue that we are not actively working on. |
Can this be implemented as |
What is the current thinking on this? I currently have to set up an os.Pipe to be able to override Stdout (and StdErr) - our use case is that we need to insert a CR before each LF when the See https://github.com/jeelabs/folie/blob/master/console.go#L17-L19 |
As @rsc says, this is a long-term issue that we are not actively working on. |
It might be possible to do this almost cleanly without breaking anything. The variables
while
Because Then one could add functions to package For programs that only use The main difference between this and perfection is that one can't do
but must instead call a function. That might be a viable compromise. Another approach would be to provide But I might be missing something. Remember that this is for Go 2, so slavish compatibility might be set aside for the transition. |
Go for it please :) It will be ok, aim for perfection, the community owes you a second chance to achieve it. Can't be that hard to transpile Go1.x to Go2.x code anyway. |
Packages that attempt to change the behavior of If we want to make these outputs more configurable, we should add a proper API for configuring them rather than encouraging users to monkey-patch through global variables. |
How about redirect the output of |
I've been thinking about this some more. There may be a role for reassignable default inputs and outputs, but the If we instead mean “an arbitrary default If we mean “the destination of |
I have a counterproposal in the two comments starting at #14106 (comment) |
Would be helpful in testing programs which read/write to std*. Nice to capture panic generated output. |
@KevinBuchs You want to avoid globals for the system-under-test anyway. Once you extract that part of the program into a more testable |
Yes, agreed. But my tests can't handle panic(). I cannot overwrite os.Stderr just before I panic to direct the output to a io.Writer. |
@KevinBuchs, if you really intend to test the exact text of your program's panic messages, you can always run the program as a separate process and capture its That said, in my experience it is almost always a mistake to rely on the exact text of a program's panic messages: it is too sensitive to the implementation details of the runtime and compiler, the process's environment, and the general behavior of the program in case of erroneous inputs — if the behavior of the program is defined concretely enough to test, it should usually be defined as a programmer-controlled error message, not a panic. |
Yes, thanks for the suggestions. I was hoping to be able to capture and output some diagnostic information if there was a panic. I don't care about it for test pass/fail, but I care about it because I want to determine the issue so I can solve it. |
Here's another reason we should avoid making |
The three variables os.Stdin, os.Stdout, and os.Stderr are all *Files, for historical reasons (they predate the io.Writer interface definition).
They should be of type io.Reader and io.Writer, respectively. This would make it easier to do interesting things with special input or output processors. For instance, one could say
os.Stdout = bufio.NewWriter(os.Stdout)
os.Stderr = bufio.NewWriter(os.Stderr)
and all output, including from log.Printf and fmt.Printf, would be buffered. Much more imaginative things would also be possible.
Also, *File is the root of a large dependency tree that simple programs would be able to avoid.
Can't change it now, but we could in Go 2.
The text was updated successfully, but these errors were encountered: