MCPcopy
hub / github.com/moby/moby / StdCopy

Function StdCopy

api/pkg/stdcopy/stdcopy.go:50–146  ·  view source on GitHub ↗

StdCopy is a modified version of [io.Copy] to de-multiplex messages from "multiplexedSource" and copy them to destination streams "destOut" and "destErr". StdCopy demultiplexes "multiplexedSource", assuming that it contains two streams, previously multiplexed using a writer created with [NewStdWrit

(destOut, destErr io.Writer, multiplexedSource io.Reader)

Source from the content-addressed store, hash-verified

48// The "written" return holds the total number of bytes written to "destOut"
49// and "destErr" combined.
50func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written int64, _ error) {
51 var (
52 buf = make([]byte, startingBufLen)
53 bufLen = len(buf)
54 nr, nw int
55 err error
56 out io.Writer
57 frameSize int
58 )
59
60 for {
61 // Make sure we have at least a full header
62 for nr < stdWriterPrefixLen {
63 var nr2 int
64 nr2, err = multiplexedSource.Read(buf[nr:])
65 nr += nr2
66 if errors.Is(err, io.EOF) {
67 if nr < stdWriterPrefixLen {
68 return written, nil
69 }
70 break
71 }
72 if err != nil {
73 return 0, err
74 }
75 }
76
77 // Check the first byte to know where to write
78 stream := StdType(buf[stdWriterFdIndex])
79 switch stream {
80 case Stdin:
81 fallthrough
82 case Stdout:
83 // Write on stdout
84 out = destOut
85 case Stderr:
86 // Write on stderr
87 out = destErr
88 case Systemerr:
89 // If we're on Systemerr, we won't write anywhere.
90 // NB: if this code changes later, make sure you don't try to write
91 // to outstream if Systemerr is the stream
92 out = nil
93 default:
94 return 0, fmt.Errorf("unrecognized stream: %d", stream)
95 }
96
97 // Retrieve the size of the frame
98 frameSize = int(binary.BigEndian.Uint32(buf[stdWriterSizeIndex : stdWriterSizeIndex+4]))
99
100 // Check if the buffer is big enough to read the frame.
101 // Extend it if necessary.
102 if frameSize+stdWriterPrefixLen > bufLen {
103 buf = append(buf, make([]byte, frameSize+stdWriterPrefixLen-bufLen+1)...)
104 bufLen = len(buf)
105 }
106
107 // While the amount of bytes read is less than the size of the frame + header, we keep reading

Callers

nothing calls this directly

Calls 5

StdTypeTypeAlias · 0.85
ErrorfMethod · 0.80
ReadMethod · 0.45
IsMethod · 0.45
WriteMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…