diff --git a/commands.go b/commands.go index 056bcbfb56..d0a1c6b1e8 100644 --- a/commands.go +++ b/commands.go @@ -1460,15 +1460,18 @@ func (cli *DockerCli) CmdRun(args ...string) error { v := url.Values{} v.Set("logs", "1") v.Set("stream", "1") + var out io.Writer if config.AttachStdin { v.Set("stdin", "1") } if config.AttachStdout { v.Set("stdout", "1") + out = cli.out } if config.AttachStderr { v.Set("stderr", "1") + out = cli.out } signals := make(chan os.Signal, 1) @@ -1482,7 +1485,7 @@ func (cli *DockerCli) CmdRun(args ...string) error { } }() - if err := cli.hijack("POST", "/containers/"+runResult.ID+"/attach?"+v.Encode(), config.Tty, cli.in, cli.out); err != nil { + if err := cli.hijack("POST", "/containers/"+runResult.ID+"/attach?"+v.Encode(), config.Tty, cli.in, out); err != nil { utils.Debugf("Error hijack: %s", err) return err } @@ -1645,11 +1648,14 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea rwc, br := clientconn.Hijack() defer rwc.Close() - receiveStdout := utils.Go(func() error { - _, err := io.Copy(out, br) - utils.Debugf("[hijack] End of stdout") - return err - }) + var receiveStdout (chan error) + if out != nil { + receiveStdout = utils.Go(func() error { + _, err := io.Copy(out, br) + utils.Debugf("[hijack] End of stdout") + return err + }) + } if in != nil && setRawTerminal && cli.isTerminal && os.Getenv("NORAW") == "" { oldState, err := term.SetRawTerminal(cli.terminalFd) @@ -1677,9 +1683,11 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea return nil }) - if err := <-receiveStdout; err != nil { - utils.Debugf("Error receiveStdout: %s", err) - return err + if out != nil { + if err := <-receiveStdout; err != nil { + utils.Debugf("Error receiveStdout: %s", err) + return err + } } if !cli.isTerminal { diff --git a/commands_test.go b/commands_test.go index ac30cc73f9..9686849aaa 100644 --- a/commands_test.go +++ b/commands_test.go @@ -255,7 +255,7 @@ func TestRunAttachStdin(t *testing.T) { ch := make(chan struct{}) go func() { defer close(ch) - cli.CmdRun("-i", "-a", "stdin", unitTestImageID, "sh", "-c", "echo hello && cat") + cli.CmdRun("-i", "-a", "stdin", unitTestImageID, "sh", "-c", "echo hello && cat && sleep 5") }() // Send input to the command, close stdin @@ -283,12 +283,10 @@ func TestRunAttachStdin(t *testing.T) { // wait for CmdRun to return setTimeout(t, "Waiting for CmdRun timed out", 5*time.Second, func() { - // Unblock hijack end - stdout.Read([]byte{}) <-ch }) - setTimeout(t, "Waiting for command to exit timed out", 5*time.Second, func() { + setTimeout(t, "Waiting for command to exit timed out", 10*time.Second, func() { container.Wait() })