Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 7339655

Browse files
committed
read until EOF in streamCopy
If either stdoutPipe or stderrPipe reads to EOF, do not close the other one so that it can read to EOF as well. Otherwise we might lose output in the other pipe. This works because if hyperstart ends the stdout/stderr streams, it always closes the writer part of both pipes. Then io.Copy() will get EOF and return success here. Also no need to wait stdin go routine because streamCopy() runs in a go routine itself thus no one is really waiting out there. Signed-off-by: Peng Tao <bergwolf@gmail.com>
1 parent c6dd76c commit 7339655

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

hypervisor/vm_states.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ func streamCopy(tty *TtyIO, stdinPipe io.WriteCloser, stdoutPipe, stderrPipe io.
172172
var wg sync.WaitGroup
173173
// old way cleanup all(expect stdinPipe) no matter what kinds of fails, TODO: change it
174174
var once sync.Once
175+
// cleanup closes tty.Stdin and thus terminates the first go routine
175176
cleanup := func() {
176177
tty.Close()
177178
// stdinPipe is directly closed in the first go routine
@@ -181,30 +182,32 @@ func streamCopy(tty *TtyIO, stdinPipe io.WriteCloser, stdoutPipe, stderrPipe io.
181182
}
182183
}
183184
if tty.Stdin != nil {
184-
wg.Add(1)
185185
go func() {
186186
_, err := io.Copy(stdinPipe, tty.Stdin)
187187
stdinPipe.Close()
188188
if err != nil {
189189
// we should not call cleanup when tty.Stdin reaches EOF
190190
once.Do(cleanup)
191191
}
192-
wg.Done()
193192
}()
194193
}
195194
if tty.Stdout != nil {
196195
wg.Add(1)
197196
go func() {
198-
io.Copy(tty.Stdout, stdoutPipe)
199-
once.Do(cleanup)
197+
_, err := io.Copy(tty.Stdout, stdoutPipe)
198+
if err != nil {
199+
once.Do(cleanup)
200+
}
200201
wg.Done()
201202
}()
202203
}
203204
if tty.Stderr != nil && stderrPipe != nil {
204205
wg.Add(1)
205206
go func() {
206-
io.Copy(tty.Stderr, stderrPipe)
207-
once.Do(cleanup)
207+
_, err := io.Copy(tty.Stderr, stderrPipe)
208+
if err != nil {
209+
once.Do(cleanup)
210+
}
208211
wg.Done()
209212
}()
210213
}

0 commit comments

Comments
 (0)