2015-05-27 20:15:14 +00:00
|
|
|
// +build windows
|
|
|
|
|
|
|
|
package windows
|
|
|
|
|
|
|
|
import (
|
2015-10-13 22:03:20 +00:00
|
|
|
"fmt"
|
2015-05-27 20:15:14 +00:00
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
2015-07-19 00:15:02 +00:00
|
|
|
"github.com/docker/docker/daemon/execdriver"
|
2015-05-27 20:15:14 +00:00
|
|
|
)
|
|
|
|
|
2015-07-19 00:15:02 +00:00
|
|
|
// 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.
|
2015-05-27 20:15:14 +00:00
|
|
|
|
2015-07-19 00:15:02 +00:00
|
|
|
// 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) {
|
2015-05-27 20:15:14 +00:00
|
|
|
|
|
|
|
// Anything that comes from the client stdin should be copied
|
|
|
|
// across to the stdin named pipe of the container.
|
2015-07-19 00:15:02 +00:00
|
|
|
go func() {
|
|
|
|
defer dst.Close()
|
|
|
|
bytes, err := io.Copy(dst, src)
|
2015-10-13 22:03:20 +00:00
|
|
|
log := fmt.Sprintf("Copied %d bytes from stdin.", bytes)
|
|
|
|
if err != nil {
|
|
|
|
log = log + " err=" + err.Error()
|
|
|
|
}
|
|
|
|
logrus.Debugf(log)
|
2015-07-19 00:15:02 +00:00
|
|
|
}()
|
2015-05-27 20:15:14 +00:00
|
|
|
}
|
|
|
|
|
2015-07-19 00:15:02 +00:00
|
|
|
// 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) {
|
2015-05-27 20:15:14 +00:00
|
|
|
// Anything that comes from the container named pipe stdout/err should be copied
|
|
|
|
// across to the stdout/err of the client
|
2015-07-19 00:15:02 +00:00
|
|
|
go func() {
|
|
|
|
defer src.Close()
|
|
|
|
bytes, err := io.Copy(dst, src)
|
2015-10-13 22:03:20 +00:00
|
|
|
log := fmt.Sprintf("Copied %d bytes from %s.", bytes, name)
|
|
|
|
if err != nil {
|
|
|
|
log = log + " err=" + err.Error()
|
|
|
|
}
|
|
|
|
logrus.Debugf(log)
|
2015-07-19 00:15:02 +00:00
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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")
|
2015-05-27 20:15:14 +00:00
|
|
|
}
|
|
|
|
}
|