package libcontainerd import ( "io" "strconv" "strings" "github.com/Microsoft/hcsshim" ) // process keeps the state for both main container process and exec process. type process struct { processCommon // Platform specific fields are below here. // commandLine is to support returning summary information for docker top commandLine string hcsProcess hcsshim.Process } func openReaderFromPipe(p io.ReadCloser) io.Reader { r, w := io.Pipe() go func() { if _, err := io.Copy(w, p); err != nil { r.CloseWithError(err) } w.Close() p.Close() }() return r } // fixStdinBackspaceBehavior works around a bug in Windows before build 14350 // where it interpreted DEL as VK_DELETE instead of as VK_BACK. This replaces // DEL with BS to work around this. func fixStdinBackspaceBehavior(w io.WriteCloser, osversion string, tty bool) io.WriteCloser { if !tty { return w } v := strings.Split(osversion, ".") if len(v) < 3 { return w } if build, err := strconv.Atoi(v[2]); err != nil || build >= 14350 { return w } return &delToBsWriter{w} } type delToBsWriter struct { io.WriteCloser } func (w *delToBsWriter) Write(b []byte) (int, error) { const ( backspace = 0x8 del = 0x7f ) bc := make([]byte, len(b)) for i, c := range b { if c == del { bc[i] = backspace } else { bc[i] = c } } return w.WriteCloser.Write(bc) } type stdInCloser struct { io.WriteCloser hcsshim.Process } func createStdInCloser(pipe io.WriteCloser, process hcsshim.Process) *stdInCloser { return &stdInCloser{ WriteCloser: pipe, Process: process, } } func (stdin *stdInCloser) Close() error { if err := stdin.WriteCloser.Close(); err != nil { return err } return stdin.Process.CloseStdin() } func (stdin *stdInCloser) Write(p []byte) (n int, err error) { return stdin.WriteCloser.Write(p) }