From c0affdfcf85c8ad7d8982b5b421b60f178d144cc Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Thu, 16 Jun 2016 17:34:00 -0700 Subject: [PATCH] Fixing bug in AttachStreams that would fail to close StdIn During a docker exec, if no TTY is specified, the code would still leave stdin open instead of closing it. This change adds handling for the execConfig TTY bool that mirrors what is already done for container config. (Updated this change to be Windows only.) Signed-off-by: Stefan J. Wernli Upstream-commit: 176345435b33ecbb725cac995083fab0462f60e3 Component: engine --- components/engine/daemon/monitor.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go index 30d36836f8..f517aa20e9 100644 --- a/components/engine/daemon/monitor.go +++ b/components/engine/daemon/monitor.go @@ -8,6 +8,7 @@ import ( "strconv" "github.com/Sirupsen/logrus" + "github.com/docker/docker/daemon/exec" "github.com/docker/docker/libcontainerd" "github.com/docker/docker/runconfig" ) @@ -103,10 +104,15 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error { // AttachStreams is called by libcontainerd to connect the stdio. func (daemon *Daemon) AttachStreams(id string, iop libcontainerd.IOPipe) error { - var s *runconfig.StreamConfig + var ( + s *runconfig.StreamConfig + ec *exec.Config + ) + c := daemon.containers.Get(id) if c == nil { - ec, err := daemon.getExecConfig(id) + var err error + ec, err = daemon.getExecConfig(id) if err != nil { return fmt.Errorf("no such exec/container: %s", id) } @@ -127,7 +133,10 @@ func (daemon *Daemon) AttachStreams(id string, iop libcontainerd.IOPipe) error { }() } } else { - if c != nil && !c.Config.Tty { + //TODO(swernli): On Windows, not closing stdin when no tty is requested by the exec Config + // results in a hang. We should re-evaluate generalizing this fix for all OSes if + // we can determine that is the right thing to do more generally. + if (c != nil && !c.Config.Tty) || (ec != nil && !ec.Tty && runtime.GOOS == "windows") { // tty is enabled, so dont close containerd's iopipe stdin. if iop.Stdin != nil { iop.Stdin.Close()