hijack.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package client
  2. import (
  3. "io"
  4. "github.com/Sirupsen/logrus"
  5. "github.com/docker/docker/pkg/stdcopy"
  6. "github.com/docker/engine-api/types"
  7. )
  8. func (cli *DockerCli) holdHijackedConnection(tty bool, inputStream io.ReadCloser, outputStream, errorStream io.Writer, resp types.HijackedResponse) error {
  9. var err error
  10. receiveStdout := make(chan error, 1)
  11. if outputStream != nil || errorStream != nil {
  12. go func() {
  13. // When TTY is ON, use regular copy
  14. if tty && outputStream != nil {
  15. _, err = io.Copy(outputStream, resp.Reader)
  16. } else {
  17. _, err = stdcopy.StdCopy(outputStream, errorStream, resp.Reader)
  18. }
  19. logrus.Debugf("[hijack] End of stdout")
  20. receiveStdout <- err
  21. }()
  22. }
  23. stdinDone := make(chan struct{})
  24. go func() {
  25. if inputStream != nil {
  26. io.Copy(resp.Conn, inputStream)
  27. logrus.Debugf("[hijack] End of stdin")
  28. }
  29. if err := resp.CloseWrite(); err != nil {
  30. logrus.Debugf("Couldn't send EOF: %s", err)
  31. }
  32. close(stdinDone)
  33. }()
  34. select {
  35. case err := <-receiveStdout:
  36. if err != nil {
  37. logrus.Debugf("Error receiveStdout: %s", err)
  38. return err
  39. }
  40. case <-stdinDone:
  41. if outputStream != nil || errorStream != nil {
  42. if err := <-receiveStdout; err != nil {
  43. logrus.Debugf("Error receiveStdout: %s", err)
  44. return err
  45. }
  46. }
  47. }
  48. return nil
  49. }