Skip to content

Commit 02115c9

Browse files
Merge pull request #3251 from openshift-cherrypick-robot/cherry-pick-3243-to-release-1.15
[release-1.15] exec: Close pipe fds to prevent hangs
2 parents 7648487 + 0dbcac6 commit 02115c9

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

oci/runtime_oci.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,27 +309,43 @@ func (r *runtimeOCI) ExecContainer(c *Container, cmd []string, stdin io.Reader,
309309
if tty {
310310
cmdErr = ttyCmd(execCmd, stdin, stdout, resize)
311311
} else {
312+
var r, w *os.File
312313
if stdin != nil {
313314
// Use an os.Pipe here as it returns true *os.File objects.
314315
// This way, if you run 'kubectl exec <pod> -i bash' (no tty) and type 'exit',
315316
// the call below to execCmd.Run() can unblock because its Stdin is the read half
316317
// of the pipe.
317-
r, w, err := os.Pipe()
318+
r, w, err = os.Pipe()
318319
if err != nil {
319320
return err
320321
}
321-
go func() { _, copyError = pools.Copy(w, stdin) }()
322-
323322
execCmd.Stdin = r
323+
go func() {
324+
_, copyError = pools.Copy(w, stdin)
325+
w.Close()
326+
}()
324327
}
328+
325329
if stdout != nil {
326330
execCmd.Stdout = stdout
327331
}
332+
328333
if stderr != nil {
329334
execCmd.Stderr = stderr
330335
}
331336

332-
cmdErr = execCmd.Run()
337+
if err := execCmd.Start(); err != nil {
338+
return err
339+
}
340+
341+
// The read side of the pipe should be closed after the container process has been started.
342+
if r != nil {
343+
if err := r.Close(); err != nil {
344+
return err
345+
}
346+
}
347+
348+
cmdErr = execCmd.Wait()
333349
}
334350

335351
if copyError != nil {

0 commit comments

Comments
 (0)