diff options
Diffstat (limited to 'vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy/stdcopy.go')
-rw-r--r-- | vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy/stdcopy.go | 175 |
1 files changed, 0 insertions, 175 deletions
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy/stdcopy.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy/stdcopy.go deleted file mode 100644 index b2c6004..0000000 --- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/stdcopy/stdcopy.go +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
1 | package stdcopy | ||
2 | |||
3 | import ( | ||
4 | "encoding/binary" | ||
5 | "errors" | ||
6 | "io" | ||
7 | |||
8 | "github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus" | ||
9 | ) | ||
10 | |||
11 | const ( | ||
12 | stdWriterPrefixLen = 8 | ||
13 | stdWriterFdIndex = 0 | ||
14 | stdWriterSizeIndex = 4 | ||
15 | |||
16 | startingBufLen = 32*1024 + stdWriterPrefixLen + 1 | ||
17 | ) | ||
18 | |||
19 | // StdType prefixes type and length to standard stream. | ||
20 | type StdType [stdWriterPrefixLen]byte | ||
21 | |||
22 | var ( | ||
23 | // Stdin represents standard input stream type. | ||
24 | Stdin = StdType{0: 0} | ||
25 | // Stdout represents standard output stream type. | ||
26 | Stdout = StdType{0: 1} | ||
27 | // Stderr represents standard error steam type. | ||
28 | Stderr = StdType{0: 2} | ||
29 | ) | ||
30 | |||
31 | // StdWriter is wrapper of io.Writer with extra customized info. | ||
32 | type StdWriter struct { | ||
33 | io.Writer | ||
34 | prefix StdType | ||
35 | sizeBuf []byte | ||
36 | } | ||
37 | |||
38 | func (w *StdWriter) Write(buf []byte) (n int, err error) { | ||
39 | var n1, n2 int | ||
40 | if w == nil || w.Writer == nil { | ||
41 | return 0, errors.New("Writer not instantiated") | ||
42 | } | ||
43 | binary.BigEndian.PutUint32(w.prefix[4:], uint32(len(buf))) | ||
44 | n1, err = w.Writer.Write(w.prefix[:]) | ||
45 | if err != nil { | ||
46 | n = n1 - stdWriterPrefixLen | ||
47 | } else { | ||
48 | n2, err = w.Writer.Write(buf) | ||
49 | n = n1 + n2 - stdWriterPrefixLen | ||
50 | } | ||
51 | if n < 0 { | ||
52 | n = 0 | ||
53 | } | ||
54 | return | ||
55 | } | ||
56 | |||
57 | // NewStdWriter instantiates a new Writer. | ||
58 | // Everything written to it will be encapsulated using a custom format, | ||
59 | // and written to the underlying `w` stream. | ||
60 | // This allows multiple write streams (e.g. stdout and stderr) to be muxed into a single connection. | ||
61 | // `t` indicates the id of the stream to encapsulate. | ||
62 | // It can be stdcopy.Stdin, stdcopy.Stdout, stdcopy.Stderr. | ||
63 | func NewStdWriter(w io.Writer, t StdType) *StdWriter { | ||
64 | return &StdWriter{ | ||
65 | Writer: w, | ||
66 | prefix: t, | ||
67 | sizeBuf: make([]byte, 4), | ||
68 | } | ||
69 | } | ||
70 | |||
71 | var errInvalidStdHeader = errors.New("Unrecognized input header") | ||
72 | |||
73 | // StdCopy is a modified version of io.Copy. | ||
74 | // | ||
75 | // StdCopy will demultiplex `src`, assuming that it contains two streams, | ||
76 | // previously multiplexed together using a StdWriter instance. | ||
77 | // As it reads from `src`, StdCopy will write to `dstout` and `dsterr`. | ||
78 | // | ||
79 | // StdCopy will read until it hits EOF on `src`. It will then return a nil error. | ||
80 | // In other words: if `err` is non nil, it indicates a real underlying error. | ||
81 | // | ||
82 | // `written` will hold the total number of bytes written to `dstout` and `dsterr`. | ||
83 | func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) { | ||
84 | var ( | ||
85 | buf = make([]byte, startingBufLen) | ||
86 | bufLen = len(buf) | ||
87 | nr, nw int | ||
88 | er, ew error | ||
89 | out io.Writer | ||
90 | frameSize int | ||
91 | ) | ||
92 | |||
93 | for { | ||
94 | // Make sure we have at least a full header | ||
95 | for nr < stdWriterPrefixLen { | ||
96 | var nr2 int | ||
97 | nr2, er = src.Read(buf[nr:]) | ||
98 | nr += nr2 | ||
99 | if er == io.EOF { | ||
100 | if nr < stdWriterPrefixLen { | ||
101 | logrus.Debugf("Corrupted prefix: %v", buf[:nr]) | ||
102 | return written, nil | ||
103 | } | ||
104 | break | ||
105 | } | ||
106 | if er != nil { | ||
107 | logrus.Debugf("Error reading header: %s", er) | ||
108 | return 0, er | ||
109 | } | ||
110 | } | ||
111 | |||
112 | // Check the first byte to know where to write | ||
113 | switch buf[stdWriterFdIndex] { | ||
114 | case 0: | ||
115 | fallthrough | ||
116 | case 1: | ||
117 | // Write on stdout | ||
118 | out = dstout | ||
119 | case 2: | ||
120 | // Write on stderr | ||
121 | out = dsterr | ||
122 | default: | ||
123 | logrus.Debugf("Error selecting output fd: (%d)", buf[stdWriterFdIndex]) | ||
124 | return 0, errInvalidStdHeader | ||
125 | } | ||
126 | |||
127 | // Retrieve the size of the frame | ||
128 | frameSize = int(binary.BigEndian.Uint32(buf[stdWriterSizeIndex : stdWriterSizeIndex+4])) | ||
129 | logrus.Debugf("framesize: %d", frameSize) | ||
130 | |||
131 | // Check if the buffer is big enough to read the frame. | ||
132 | // Extend it if necessary. | ||
133 | if frameSize+stdWriterPrefixLen > bufLen { | ||
134 | logrus.Debugf("Extending buffer cap by %d (was %d)", frameSize+stdWriterPrefixLen-bufLen+1, len(buf)) | ||
135 | buf = append(buf, make([]byte, frameSize+stdWriterPrefixLen-bufLen+1)...) | ||
136 | bufLen = len(buf) | ||
137 | } | ||
138 | |||
139 | // While the amount of bytes read is less than the size of the frame + header, we keep reading | ||
140 | for nr < frameSize+stdWriterPrefixLen { | ||
141 | var nr2 int | ||
142 | nr2, er = src.Read(buf[nr:]) | ||
143 | nr += nr2 | ||
144 | if er == io.EOF { | ||
145 | if nr < frameSize+stdWriterPrefixLen { | ||
146 | logrus.Debugf("Corrupted frame: %v", buf[stdWriterPrefixLen:nr]) | ||
147 | return written, nil | ||
148 | } | ||
149 | break | ||
150 | } | ||
151 | if er != nil { | ||
152 | logrus.Debugf("Error reading frame: %s", er) | ||
153 | return 0, er | ||
154 | } | ||
155 | } | ||
156 | |||
157 | // Write the retrieved frame (without header) | ||
158 | nw, ew = out.Write(buf[stdWriterPrefixLen : frameSize+stdWriterPrefixLen]) | ||
159 | if ew != nil { | ||
160 | logrus.Debugf("Error writing frame: %s", ew) | ||
161 | return 0, ew | ||
162 | } | ||
163 | // If the frame has not been fully written: error | ||
164 | if nw != frameSize { | ||
165 | logrus.Debugf("Error Short Write: (%d on %d)", nw, frameSize) | ||
166 | return 0, io.ErrShortWrite | ||
167 | } | ||
168 | written += int64(nw) | ||
169 | |||
170 | // Move the rest of the buffer to the beginning | ||
171 | copy(buf, buf[frameSize+stdWriterPrefixLen:]) | ||
172 | // Move the index | ||
173 | nr -= frameSize + stdWriterPrefixLen | ||
174 | } | ||
175 | } | ||