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 }