-
Notifications
You must be signed in to change notification settings - Fork 18k
os/exec: stop stdin copying goroutine after process exits #7990
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
Labels
Milestone
Comments
The issue here is that when c.Stdin is set to an io.Reader that is not an os.File, a goroutine is created to copy data from the io.Reader to a freshly create os.Pipe. When the process exits, and we've waited for it, Cmd.Wait waits for that goroutine to complete. But there is really no reason to do that. The process is done; it's not going to read any more data. We shouldn't sit around waiting for the goroutine to copy data to a process that isn't going to read it. We should instead just tell the goroutine to shut down. Labels changed: added repo-main, release-go1.4. |
There is a problem with making that change: If we were to change tis, the following example would become a data race: http://play.golang.org/p/bODUysTV1l (the copying goroutine and main() would access mr concurrently). At the same time I find it weird that this example returns the broken pipe error from Run(). There are two weird things I see here: This is another difference in behaviour between *os.File and other io.Readers This makes it largely impossible to use Cmd.Stdin directly (ie. not by calling StdinPipe) if we don't want to treat an early exit from the child process as an error. |
I agree that it would be incorrect to permit Run to return while the copying goroutine is still running. I wasn't suggesting that. I'm sorry, I don't understand the comment about the broken pipe error. It's clearly possible to use Cmd.Stdin directly if you set it to a file or an os.Pipe. Perhaps it is difficult to use it for a general io.Reader, I'm not sure. |
> I'm sorry, I don't understand the comment about the broken pipe error. It's clearly possible to use Cmd.Stdin directly if you set it to a file or an os.Pipe. Perhaps it is difficult to use it for a general io.Reader, I'm not sure. The difficulty arises if you set it to another io.Reader and you don't expect the child process to read all its input. In that case, Run (or Wait) will return a broken pipe error if the child didn't read all its input (http://play.golang.org/p/bODUysTV1l demonstrates that). It's difficult to distinguish between that error and any other error (eg. the process having died due to a signal). It seems to me now that one should always use StdinPipe in those situations. If that's true, I will send a doc CL that makes it explicit after Go 1.3 is out. |
Owner changed to @bradfitz. Status changed to Accepted. |
CL https://golang.org/cl/156220043 mentions this issue. |
This issue was closed by revision 05c4b69. Status changed to Fixed. |
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jun 25, 2018
Fixes golang#7990. LGTM=iant, bradfitz R=bradfitz, iant, robryk CC=golang-codereviews https://golang.org/cl/156220043
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jun 26, 2018
Fixes golang#7990. LGTM=iant, bradfitz R=bradfitz, iant, robryk CC=golang-codereviews https://golang.org/cl/156220043
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jul 9, 2018
Fixes golang#7990. LGTM=iant, bradfitz R=bradfitz, iant, robryk CC=golang-codereviews https://golang.org/cl/156220043
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jul 30, 2018
Fixes golang#7990. LGTM=iant, bradfitz R=bradfitz, iant, robryk CC=golang-codereviews https://golang.org/cl/156220043
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by robryk:
The text was updated successfully, but these errors were encountered: