forked from containers/common
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pkg/util: add CopyDetachable from podman
conmon-rs currently depends on podmans utils.CopyDetachable(). Since podman wants to import conmon-rs go code this can cause many problems. To fix this we move the shared code to c/common so both projects can use it without trouble. see containers/conmon-rs#504 Signed-off-by: Paul Holzinger <[email protected]>
- Loading branch information
Showing
1 changed file
with
57 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
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 | ||
} |