github.com/portworx/docker@v1.12.1/libcontainerd/process_windows.go (about)

     1  package libcontainerd
     2  
     3  import (
     4  	"io"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/Microsoft/hcsshim"
     9  )
    10  
    11  // process keeps the state for both main container process and exec process.
    12  type process struct {
    13  	processCommon
    14  
    15  	// Platform specific fields are below here.
    16  
    17  	// commandLine is to support returning summary information for docker top
    18  	commandLine string
    19  	hcsProcess  hcsshim.Process
    20  }
    21  
    22  func openReaderFromPipe(p io.ReadCloser) io.Reader {
    23  	r, w := io.Pipe()
    24  	go func() {
    25  		if _, err := io.Copy(w, p); err != nil {
    26  			r.CloseWithError(err)
    27  		}
    28  		w.Close()
    29  		p.Close()
    30  	}()
    31  	return r
    32  }
    33  
    34  // fixStdinBackspaceBehavior works around a bug in Windows before build 14350
    35  // where it interpreted DEL as VK_DELETE instead of as VK_BACK. This replaces
    36  // DEL with BS to work around this.
    37  func fixStdinBackspaceBehavior(w io.WriteCloser, osversion string, tty bool) io.WriteCloser {
    38  	if !tty {
    39  		return w
    40  	}
    41  	v := strings.Split(osversion, ".")
    42  	if len(v) < 3 {
    43  		return w
    44  	}
    45  
    46  	if build, err := strconv.Atoi(v[2]); err != nil || build >= 14350 {
    47  		return w
    48  	}
    49  
    50  	return &delToBsWriter{w}
    51  }
    52  
    53  type delToBsWriter struct {
    54  	io.WriteCloser
    55  }
    56  
    57  func (w *delToBsWriter) Write(b []byte) (int, error) {
    58  	const (
    59  		backspace = 0x8
    60  		del       = 0x7f
    61  	)
    62  	bc := make([]byte, len(b))
    63  	for i, c := range b {
    64  		if c == del {
    65  			bc[i] = backspace
    66  		} else {
    67  			bc[i] = c
    68  		}
    69  	}
    70  	return w.WriteCloser.Write(bc)
    71  }
    72  
    73  type stdInCloser struct {
    74  	io.WriteCloser
    75  	hcsshim.Process
    76  }
    77  
    78  func createStdInCloser(pipe io.WriteCloser, process hcsshim.Process) *stdInCloser {
    79  	return &stdInCloser{
    80  		WriteCloser: pipe,
    81  		Process:     process,
    82  	}
    83  }
    84  
    85  func (stdin *stdInCloser) Close() error {
    86  	if err := stdin.WriteCloser.Close(); err != nil {
    87  		return err
    88  	}
    89  
    90  	return stdin.Process.CloseStdin()
    91  }
    92  
    93  func (stdin *stdInCloser) Write(p []byte) (n int, err error) {
    94  	return stdin.WriteCloser.Write(p)
    95  }