github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/daemon/execdriver/windows/namedpipes.go (about)

     1  // +build windows
     2  
     3  package windows
     4  
     5  import (
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  	"github.com/docker/docker/daemon/execdriver"
    11  )
    12  
    13  // General comment. Handling I/O for a container is very different to Linux.
    14  // We use a named pipe to HCS to copy I/O both in and out of the container,
    15  // very similar to how docker daemon communicates with a CLI.
    16  
    17  // startStdinCopy asynchronously copies an io.Reader to the container's
    18  // process's stdin pipe and closes the pipe when there is no more data to copy.
    19  func startStdinCopy(dst io.WriteCloser, src io.Reader) {
    20  
    21  	// Anything that comes from the client stdin should be copied
    22  	// across to the stdin named pipe of the container.
    23  	go func() {
    24  		defer dst.Close()
    25  		bytes, err := io.Copy(dst, src)
    26  		log := fmt.Sprintf("Copied %d bytes from stdin.", bytes)
    27  		if err != nil {
    28  			log = log + " err=" + err.Error()
    29  		}
    30  		logrus.Debugf(log)
    31  	}()
    32  }
    33  
    34  // startStdouterrCopy asynchronously copies data from the container's process's
    35  // stdout or stderr pipe to an io.Writer and closes the pipe when there is no
    36  // more data to copy.
    37  func startStdouterrCopy(dst io.Writer, src io.ReadCloser, name string) {
    38  	// Anything that comes from the container named pipe stdout/err should be copied
    39  	// across to the stdout/err of the client
    40  	go func() {
    41  		defer src.Close()
    42  		bytes, err := io.Copy(dst, src)
    43  		log := fmt.Sprintf("Copied %d bytes from %s.", bytes, name)
    44  		if err != nil {
    45  			log = log + " err=" + err.Error()
    46  		}
    47  		logrus.Debugf(log)
    48  	}()
    49  }
    50  
    51  // setupPipes starts the asynchronous copying of data to and from the named
    52  // pipes used byt he HCS for the std handles.
    53  func setupPipes(stdin io.WriteCloser, stdout, stderr io.ReadCloser, pipes *execdriver.Pipes) {
    54  	if stdin != nil {
    55  		startStdinCopy(stdin, pipes.Stdin)
    56  	}
    57  	if stdout != nil {
    58  		startStdouterrCopy(pipes.Stdout, stdout, "stdout")
    59  	}
    60  	if stderr != nil {
    61  		startStdouterrCopy(pipes.Stderr, stderr, "stderr")
    62  	}
    63  }