Windows: Work around Windows BS/DEL behavior

In Windows containers in TP5, DEL is interpreted as the delete key, but
Linux generally interprets it as backspace. This prevents backspace from
working when using a Linux terminal or the native console terminal
emulation in Windows.

To work around this, translate DEL to BS in Windows containers stdin when
TTY is enabled. Do this only for builds that do not have the fix in
Windows itself.

Signed-off-by: John Starks <jostarks@microsoft.com>
Upstream-commit: f124829c9b35377de2a8316b7e23aa7a8c5d7b23
Component: engine
This commit is contained in:
John Starks
2016-05-20 19:04:20 -07:00
parent ed6e5fbdf6
commit fc3bf55518
3 changed files with 38 additions and 0 deletions
@@ -291,6 +291,9 @@ func (clnt *client) AddProcess(containerID, processFriendlyName string, procToAd
return err
}
// TEMP: Work around Windows BS/DEL behavior.
iopipe.Stdin = fixStdinBackspaceBehavior(iopipe.Stdin, procToAdd.Terminal)
// Convert io.ReadClosers to io.Readers
if stdout != nil {
iopipe.Stdout = openReaderFromPipe(stdout)
@@ -102,6 +102,9 @@ func (ctr *container) start() error {
}
ctr.startedAt = time.Now()
// TEMP: Work around Windows BS/DEL behavior.
iopipe.Stdin = fixStdinBackspaceBehavior(iopipe.Stdin, ctr.ociSpec.Process.Terminal)
// Convert io.ReadClosers to io.Readers
if stdout != nil {
iopipe.Stdout = openReaderFromPipe(stdout)
@@ -2,6 +2,8 @@ package libcontainerd
import (
"io"
"github.com/docker/docker/pkg/system"
)
// process keeps the state for both main container process and exec process.
@@ -25,3 +27,33 @@ func openReaderFromPipe(p io.ReadCloser) io.Reader {
}()
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, tty bool) io.WriteCloser {
if !tty || system.GetOSVersion().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)
}