Skip to content

Commit e25414a

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 b01b6f2 commit e25414a

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

pipe/options.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ func WithDir(dir string) ConfigOption {
8585
// WithStdin assigns stdin for the runner. The caller retains
8686
// ownership of stdin; the runner will not close it, even if `Start()`
8787
// returns an error.
88+
//
89+
// If this stdin is connected to a `Command` stage and is not an
90+
// `*os.File`, `exec.Cmd` has to copy stdin through an internal
91+
// goroutine, and `Cmd.Wait()` waits for that copy to finish. This is
92+
// fine for bounded readers such as `strings.Reader` and
93+
// `bytes.Reader`, and for `*os.File` values, which are passed to the
94+
// command directly. But a borrowed, non-file reader that can block
95+
// forever can also block the runner forever if the command exits
96+
// without consuming all of its stdin. See
97+
// `TestPipelineIOPipeStdinThatIsNeverClosed` for the known limitation.
8898
func WithStdin(stdin io.Reader) Option {
8999
return newFuncOption(
90100
func(r *runner) {

0 commit comments

Comments
 (0)