Browse code

Implement an escape sequence in order to be able to detach from a container

Guillaume J. Charmes authored on 2013/04/05 04:55:24
Showing 2 changed files
... ...
@@ -255,7 +255,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
255 255
 				if container.Config.StdinOnce && !container.Config.Tty {
256 256
 					defer cStdin.Close()
257 257
 				}
258
-				_, err := io.Copy(cStdin, stdin)
258
+				_, err := CopyEscapable(cStdin, stdin)
259 259
 				if err != nil {
260 260
 					Debugf("[error] attach stdin: %s\n", err)
261 261
 				}
... ...
@@ -341,3 +341,53 @@ func TruncateId(id string) string {
341 341
 	}
342 342
 	return id[:shortLen]
343 343
 }
344
+
345
+// Code c/c from io.Copy() modified to handle escape sequence
346
+func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) {
347
+	// If the writer has a ReadFrom method, use it to do the copy.
348
+	// Avoids an allocation and a copy.
349
+	if rt, ok := dst.(io.ReaderFrom); ok {
350
+		return rt.ReadFrom(src)
351
+	}
352
+	// Similarly, if the reader has a WriteTo method, use it to do the copy.
353
+	if wt, ok := src.(io.WriterTo); ok {
354
+		return wt.WriteTo(dst)
355
+	}
356
+	buf := make([]byte, 32*1024)
357
+	for {
358
+		nr, er := src.Read(buf)
359
+		if nr > 0 {
360
+			// ---- Docker addition
361
+			if nr == 1 && buf[0] == '' {
362
+				nr, er = src.Read(buf)
363
+				if nr == 1 && buf[0] == '' {
364
+					if err := src.Close(); err != nil {
365
+						return 0, err
366
+					}
367
+					return 0, io.EOF
368
+				}
369
+			}
370
+			// ---- End of docker
371
+			nw, ew := dst.Write(buf[0:nr])
372
+			if nw > 0 {
373
+				written += int64(nw)
374
+			}
375
+			if ew != nil {
376
+				err = ew
377
+				break
378
+			}
379
+			if nr != nw {
380
+				err = io.ErrShortWrite
381
+				break
382
+			}
383
+		}
384
+		if er == io.EOF {
385
+			break
386
+		}
387
+		if er != nil {
388
+			err = er
389
+			break
390
+		}
391
+	}
392
+	return written, err
393
+}