diff --git a/cmdext/cmdrunner.go b/cmdext/cmdrunner.go index ab61f8f..e471a09 100644 --- a/cmdext/cmdrunner.go +++ b/cmdext/cmdrunner.go @@ -36,8 +36,9 @@ func run(opt CommandRunner) (CommandResult, error) { } preader := pipeReader{ - stdout: stdoutPipe, - stderr: stderrPipe, + lineBufferSize: langext.Ptr(128 * 1024 * 1024), // 128MB max size of a single line, is hopefully enough.... + stdout: stdoutPipe, + stderr: stderrPipe, } err = cmd.Start() @@ -60,14 +61,17 @@ func run(opt CommandRunner) (CommandResult, error) { stdout, stderr, stdcombined, err := preader.Read(opt.listener) if err != nil { outputChan <- resultObj{stdout, stderr, stdcombined, err} + _ = cmd.Process.Kill() + return } err = cmd.Wait() if err != nil { outputChan <- resultObj{stdout, stderr, stdcombined, err} + } else { + outputChan <- resultObj{stdout, stderr, stdcombined, nil} } - outputChan <- resultObj{stdout, stderr, stdcombined, nil} }() var timeoutChan <-chan time.Time = make(chan time.Time, 1) diff --git a/cmdext/cmdrunner_test.go b/cmdext/cmdrunner_test.go index fa50bc2..8651cf4 100644 --- a/cmdext/cmdrunner_test.go +++ b/cmdext/cmdrunner_test.go @@ -280,7 +280,7 @@ func TestLongStdout(t *testing.T) { if res1.StdErr != "" { t.Errorf("res1.StdErr == '%v'", res1.StdErr) } - if len(res1.StdOut) != 375006 { + if len(res1.StdOut) != 375009 { t.Errorf("len(res1.StdOut) == '%v'", len(res1.StdOut)) } diff --git a/cmdext/pipereader.go b/cmdext/pipereader.go index 7a74624..4812eff 100644 --- a/cmdext/pipereader.go +++ b/cmdext/pipereader.go @@ -8,8 +8,9 @@ import ( ) type pipeReader struct { - stdout io.ReadCloser - stderr io.ReadCloser + lineBufferSize *int + stdout io.ReadCloser + stderr io.ReadCloser } // Read ready stdout and stdin until finished @@ -33,7 +34,6 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string, buf := make([]byte, 128) for true { n, out := pr.stdout.Read(buf) - if n > 0 { txt := string(buf[:n]) stdout += txt @@ -91,6 +91,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string, wg.Add(1) go func() { scanner := bufio.NewScanner(stdoutBufferReader) + if pr.lineBufferSize != nil { + scanner.Buffer([]byte{}, *pr.lineBufferSize) + } for scanner.Scan() { txt := scanner.Text() for _, lstr := range listener { @@ -98,6 +101,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string, } combch <- combevt{txt, false} } + if err := scanner.Err(); err != nil { + errch <- err + } combch <- combevt{"", true} wg.Done() }() @@ -107,6 +113,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string, wg.Add(1) go func() { scanner := bufio.NewScanner(stderrBufferReader) + if pr.lineBufferSize != nil { + scanner.Buffer([]byte{}, *pr.lineBufferSize) + } for scanner.Scan() { txt := scanner.Text() for _, lstr := range listener { @@ -114,6 +123,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string, } combch <- combevt{txt, false} } + if err := scanner.Err(); err != nil { + errch <- err + } combch <- combevt{"", true} wg.Done() }()