mirror of
https://github.com/containers/podman.git
synced 2025-08-06 11:32:07 +08:00

Since conmon-rs also uses this code we moved it to c/common. Now podman should has this also to prevent duplication. [NO NEW TESTS NEEDED] Signed-off-by: Paul Holzinger <pholzing@redhat.com>
58 lines
1.1 KiB
Go
58 lines
1.1 KiB
Go
package util
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
)
|
|
|
|
// ErrDetach indicates that an attach session was manually detached by
|
|
// the user.
|
|
var ErrDetach = errors.New("detached from container")
|
|
|
|
// CopyDetachable is similar to io.Copy but support a detach key sequence to break out.
|
|
func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
|
|
buf := make([]byte, 32*1024)
|
|
for {
|
|
nr, er := src.Read(buf)
|
|
if nr > 0 {
|
|
preservBuf := []byte{}
|
|
for i, key := range keys {
|
|
preservBuf = append(preservBuf, buf[0:nr]...)
|
|
if nr != 1 || buf[0] != key {
|
|
break
|
|
}
|
|
if i == len(keys)-1 {
|
|
return 0, ErrDetach
|
|
}
|
|
nr, er = src.Read(buf)
|
|
}
|
|
var nw int
|
|
var ew error
|
|
if len(preservBuf) > 0 {
|
|
nw, ew = dst.Write(preservBuf)
|
|
nr = len(preservBuf)
|
|
} else {
|
|
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 != nil {
|
|
if er != io.EOF {
|
|
err = er
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return written, err
|
|
}
|