Skip to content

Commit 20b8064

Browse files
znullCopilot
andcommitted
Document WithStdin blocking-reader limitation
Explain the known deadlock risk for borrowed non-file stdin readers feeding a command that exits without draining stdin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3b5940a commit 20b8064

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

pipe/pipeline.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ func WithDir(dir string) Option {
9999
// WithStdin assigns stdin to the first command in the pipeline. The
100100
// caller retains ownership of stdin; the pipeline will not close it,
101101
// even if `Start()` returns an error.
102+
//
103+
// If the first stage is a `Command` and stdin is not an `*os.File`,
104+
// `exec.Cmd` has to copy stdin through an internal goroutine, and
105+
// `Cmd.Wait()` waits for that copy to finish. This is fine for bounded
106+
// readers such as `strings.Reader` and `bytes.Reader`, and for
107+
// `*os.File` values, which are passed to the command directly. But a
108+
// borrowed, non-file reader that can block forever can also block the
109+
// pipeline forever if the command exits without consuming all of its
110+
// stdin. See `TestPipelineIOPipeStdinThatIsNeverClosed` for the known
111+
// limitation.
102112
func WithStdin(stdin io.Reader) Option {
103113
return func(p *Pipeline) {
104114
p.stdin = Input(stdin)

0 commit comments

Comments
 (0)