| ... | ... |
@@ -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 |
+} |