]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: document blocking Stdin/Stdout/Stderr
authorIan Lance Taylor <iant@golang.org>
Tue, 27 Jan 2026 04:03:30 +0000 (20:03 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 27 Jan 2026 20:28:35 +0000 (12:28 -0800)
WaitDelay only handles writes to Stdin and reads from Stdout/Stderr.
If Stdin is set to a blocking Reader, or Stdout/Stderr are set to
a blocking Writer, Wait can hang indefinitely. I don't see any way to
fix this with the current API, as there is no general way that the
os/exec package can interrupt the blocking Read or Write.

This CL documents the limitation and points people toward the
workaround of using StdinPipe/StdoutPipe/StderrPipe and arranging
for their own way to interrupt the blocking Read or Write.

Fixes #77227

Change-Id: I3150ae7af89dccf8d859b41eb43eaf0bbbb55fee
Reviewed-on: https://go-review.googlesource.com/c/go/+/739422
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
src/os/exec/exec.go

index aa7a6be7f07c1c578952cfe0be3cc8aae2dace42..e5bf97a1880c4656ed836b3e1bb4effd8eba7514 100644 (file)
@@ -203,6 +203,11 @@ type Cmd struct {
        // stops copying, either because it has reached the end of Stdin
        // (EOF or a read error), or because writing to the pipe returned an error,
        // or because a nonzero WaitDelay was set and expired.
+       //
+       // Regardless of WaitDelay, Wait can block until a Read from
+       // Stdin completes. If you need to use a blocking io.Reader,
+       // use the StdinPipe method to get a pipe, copy from the Reader
+       // to the pipe, and arrange to close the Reader after Wait returns.
        Stdin io.Reader
 
        // Stdout and Stderr specify the process's standard output and error.
@@ -219,6 +224,12 @@ type Cmd struct {
        // goroutine reaches EOF or encounters an error or a nonzero WaitDelay
        // expires.
        //
+       // Regardless of WaitDelay, Wait can block until a Write to
+       // Stdout or Stderr completes. If you need to use a blocking io.Writer,
+       // use the StdoutPipe or StderrPipe method to get a pipe,
+       // copy from the pipe to the Writer, and arrange to close the
+       // Writer after Wait returns.
+       //
        // If Stdout and Stderr are the same writer, and have a type that can
        // be compared with ==, at most one goroutine at a time will call Write.
        Stdout io.Writer