mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Don't read from stdout in hijack unless attached. Fixes #1503
This commit is contained in:
parent
4caa604793
commit
c7cda86e84
2 changed files with 19 additions and 13 deletions
12
commands.go
12
commands.go
|
@ -1460,15 +1460,18 @@ func (cli *DockerCli) CmdRun(args ...string) error {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
v.Set("logs", "1")
|
v.Set("logs", "1")
|
||||||
v.Set("stream", "1")
|
v.Set("stream", "1")
|
||||||
|
var out io.Writer
|
||||||
|
|
||||||
if config.AttachStdin {
|
if config.AttachStdin {
|
||||||
v.Set("stdin", "1")
|
v.Set("stdin", "1")
|
||||||
}
|
}
|
||||||
if config.AttachStdout {
|
if config.AttachStdout {
|
||||||
v.Set("stdout", "1")
|
v.Set("stdout", "1")
|
||||||
|
out = cli.out
|
||||||
}
|
}
|
||||||
if config.AttachStderr {
|
if config.AttachStderr {
|
||||||
v.Set("stderr", "1")
|
v.Set("stderr", "1")
|
||||||
|
out = cli.out
|
||||||
}
|
}
|
||||||
|
|
||||||
signals := make(chan os.Signal, 1)
|
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)
|
utils.Debugf("Error hijack: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1645,11 +1648,14 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
|
||||||
rwc, br := clientconn.Hijack()
|
rwc, br := clientconn.Hijack()
|
||||||
defer rwc.Close()
|
defer rwc.Close()
|
||||||
|
|
||||||
receiveStdout := utils.Go(func() error {
|
var receiveStdout (chan error)
|
||||||
|
if out != nil {
|
||||||
|
receiveStdout = utils.Go(func() error {
|
||||||
_, err := io.Copy(out, br)
|
_, err := io.Copy(out, br)
|
||||||
utils.Debugf("[hijack] End of stdout")
|
utils.Debugf("[hijack] End of stdout")
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if in != nil && setRawTerminal && cli.isTerminal && os.Getenv("NORAW") == "" {
|
if in != nil && setRawTerminal && cli.isTerminal && os.Getenv("NORAW") == "" {
|
||||||
oldState, err := term.SetRawTerminal(cli.terminalFd)
|
oldState, err := term.SetRawTerminal(cli.terminalFd)
|
||||||
|
@ -1677,10 +1683,12 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if out != nil {
|
||||||
if err := <-receiveStdout; err != nil {
|
if err := <-receiveStdout; err != nil {
|
||||||
utils.Debugf("Error receiveStdout: %s", err)
|
utils.Debugf("Error receiveStdout: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !cli.isTerminal {
|
if !cli.isTerminal {
|
||||||
if err := <-sendStdin; err != nil {
|
if err := <-sendStdin; err != nil {
|
||||||
|
|
|
@ -255,7 +255,7 @@ func TestRunAttachStdin(t *testing.T) {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
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
|
// Send input to the command, close stdin
|
||||||
|
@ -283,12 +283,10 @@ func TestRunAttachStdin(t *testing.T) {
|
||||||
|
|
||||||
// wait for CmdRun to return
|
// wait for CmdRun to return
|
||||||
setTimeout(t, "Waiting for CmdRun timed out", 5*time.Second, func() {
|
setTimeout(t, "Waiting for CmdRun timed out", 5*time.Second, func() {
|
||||||
// Unblock hijack end
|
|
||||||
stdout.Read([]byte{})
|
|
||||||
<-ch
|
<-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()
|
container.Wait()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue