From 1f70b1e15d0dea5f36395d325cbac2892e4f2e8a Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Thu, 4 Apr 2013 12:55:24 -0700 Subject: [PATCH] Implement an escape sequence in order to be able to detach from a container --- container.go | 2 +- utils.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/container.go b/container.go index a7a4de5563..5c4f8aa5fe 100644 --- a/container.go +++ b/container.go @@ -255,7 +255,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s if container.Config.StdinOnce && !container.Config.Tty { defer cStdin.Close() } - _, err := io.Copy(cStdin, stdin) + _, err := CopyEscapable(cStdin, stdin) if err != nil { Debugf("[error] attach stdin: %s\n", err) } diff --git a/utils.go b/utils.go index 5ee84239b1..398d6570bf 100644 --- a/utils.go +++ b/utils.go @@ -341,3 +341,53 @@ func TruncateId(id string) string { } return id[:shortLen] } + +// Code c/c from io.Copy() modified to handle escape sequence +func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) { + // If the writer has a ReadFrom method, use it to do the copy. + // Avoids an allocation and a copy. + if rt, ok := dst.(io.ReaderFrom); ok { + return rt.ReadFrom(src) + } + // Similarly, if the reader has a WriteTo method, use it to do the copy. + if wt, ok := src.(io.WriterTo); ok { + return wt.WriteTo(dst) + } + buf := make([]byte, 32*1024) + for { + nr, er := src.Read(buf) + if nr > 0 { + // ---- Docker addition + if nr == 1 && buf[0] == '' { + nr, er = src.Read(buf) + if nr == 1 && buf[0] == '' { + if err := src.Close(); err != nil { + return 0, err + } + return 0, io.EOF + } + } + // ---- End of docker + nw, ew := dst.Write(buf[0:nr]) + if nw > 0 { + written += int64(nw) + } + if ew != nil { + err = ew + break + } + if nr != nw { + err = io.ErrShortWrite + break + } + } + if er == io.EOF { + break + } + if er != nil { + err = er + break + } + } + return written, err +}