github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/api/client/hijack.go (about)

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