moby--moby/daemon/execdriver/windows/namedpipes.go

64 lines
1.9 KiB
Go

// +build windows
package windows
import (
"fmt"
"io"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/execdriver"
)
// General comment. Handling I/O for a container is very different to Linux.
// We use a named pipe to HCS to copy I/O both in and out of the container,
// very similar to how docker daemon communicates with a CLI.
// startStdinCopy asynchronously copies an io.Reader to the container's
// process's stdin pipe and closes the pipe when there is no more data to copy.
func startStdinCopy(dst io.WriteCloser, src io.Reader) {
// Anything that comes from the client stdin should be copied
// across to the stdin named pipe of the container.
go func() {
defer dst.Close()
bytes, err := io.Copy(dst, src)
log := fmt.Sprintf("Copied %d bytes from stdin.", bytes)
if err != nil {
log = log + " err=" + err.Error()
}
logrus.Debugf(log)
}()
}
// startStdouterrCopy asynchronously copies data from the container's process's
// stdout or stderr pipe to an io.Writer and closes the pipe when there is no
// more data to copy.
func startStdouterrCopy(dst io.Writer, src io.ReadCloser, name string) {
// Anything that comes from the container named pipe stdout/err should be copied
// across to the stdout/err of the client
go func() {
defer src.Close()
bytes, err := io.Copy(dst, src)
log := fmt.Sprintf("Copied %d bytes from %s.", bytes, name)
if err != nil {
log = log + " err=" + err.Error()
}
logrus.Debugf(log)
}()
}
// setupPipes starts the asynchronous copying of data to and from the named
// pipes used byt he HCS for the std handles.
func setupPipes(stdin io.WriteCloser, stdout, stderr io.ReadCloser, pipes *execdriver.Pipes) {
if stdin != nil {
startStdinCopy(stdin, pipes.Stdin)
}
if stdout != nil {
startStdouterrCopy(pipes.Stdout, stdout, "stdout")
}
if stderr != nil {
startStdouterrCopy(pipes.Stderr, stderr, "stderr")
}
}