Merge remote-tracking branch 'robryk/cmdstream-deadlock'

This commit is contained in:
Solomon Hykes 2013-03-29 13:20:17 -07:00
commit fdae64d8d7
2 changed files with 23 additions and 5 deletions

View File

@ -55,17 +55,21 @@ func CmdStream(cmd *exec.Cmd) (io.Reader, error) {
return nil, err
}
pipeR, pipeW := io.Pipe()
errChan := make(chan []byte)
go func() {
errText, e := ioutil.ReadAll(stderr)
if e != nil {
errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")")
}
errChan <- errText
}()
go func() {
_, err := io.Copy(pipeW, stdout)
if err != nil {
pipeW.CloseWithError(err)
}
errText, e := ioutil.ReadAll(stderr)
if e != nil {
errText = []byte("(...couldn't fetch stderr: " + e.Error() + ")")
}
errText := <-errChan
if err := cmd.Wait(); err != nil {
// FIXME: can this block if stderr outputs more than the size of StderrPipe()'s buffer?
pipeW.CloseWithError(errors.New(err.Error() + ": " + string(errText)))
} else {
pipeW.Close()

View File

@ -1,12 +1,26 @@
package docker
import (
"io"
"io/ioutil"
"os"
"os/exec"
"testing"
)
func TestCmdStreamLargeStderr(t *testing.T) {
// This test checks for deadlock; thus, the main failure mode of this test is deadlocking.
cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
out, err := CmdStream(cmd)
if err != nil {
t.Fatalf("Failed to start command: " + err.Error())
}
_, err = io.Copy(ioutil.Discard, out)
if err != nil {
t.Fatalf("Command should not have failed (err=%s...)", err.Error()[:100])
}
}
func TestCmdStreamBad(t *testing.T) {
badCmd := exec.Command("/bin/sh", "-c", "echo hello; echo >&2 error couldn\\'t reverse the phase pulser; exit 1")
out, err := CmdStream(badCmd)