fix fd0 read error on long stdout output (scanner buffer was too small)

This commit is contained in:
Mike Schwörer 2023-02-13 01:41:33 +01:00
parent 4a2b830252
commit 9f5612248a
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
3 changed files with 23 additions and 7 deletions

View File

@ -36,6 +36,7 @@ func run(opt CommandRunner) (CommandResult, error) {
} }
preader := pipeReader{ preader := pipeReader{
lineBufferSize: langext.Ptr(128 * 1024 * 1024), // 128MB max size of a single line, is hopefully enough....
stdout: stdoutPipe, stdout: stdoutPipe,
stderr: stderrPipe, stderr: stderrPipe,
} }
@ -60,14 +61,17 @@ func run(opt CommandRunner) (CommandResult, error) {
stdout, stderr, stdcombined, err := preader.Read(opt.listener) stdout, stderr, stdcombined, err := preader.Read(opt.listener)
if err != nil { if err != nil {
outputChan <- resultObj{stdout, stderr, stdcombined, err} outputChan <- resultObj{stdout, stderr, stdcombined, err}
_ = cmd.Process.Kill()
return
} }
err = cmd.Wait() err = cmd.Wait()
if err != nil { if err != nil {
outputChan <- resultObj{stdout, stderr, stdcombined, err} 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) var timeoutChan <-chan time.Time = make(chan time.Time, 1)

View File

@ -280,7 +280,7 @@ func TestLongStdout(t *testing.T) {
if res1.StdErr != "" { if res1.StdErr != "" {
t.Errorf("res1.StdErr == '%v'", 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)) t.Errorf("len(res1.StdOut) == '%v'", len(res1.StdOut))
} }

View File

@ -8,6 +8,7 @@ import (
) )
type pipeReader struct { type pipeReader struct {
lineBufferSize *int
stdout io.ReadCloser stdout io.ReadCloser
stderr io.ReadCloser stderr io.ReadCloser
} }
@ -33,7 +34,6 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string,
buf := make([]byte, 128) buf := make([]byte, 128)
for true { for true {
n, out := pr.stdout.Read(buf) n, out := pr.stdout.Read(buf)
if n > 0 { if n > 0 {
txt := string(buf[:n]) txt := string(buf[:n])
stdout += txt stdout += txt
@ -91,6 +91,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string,
wg.Add(1) wg.Add(1)
go func() { go func() {
scanner := bufio.NewScanner(stdoutBufferReader) scanner := bufio.NewScanner(stdoutBufferReader)
if pr.lineBufferSize != nil {
scanner.Buffer([]byte{}, *pr.lineBufferSize)
}
for scanner.Scan() { for scanner.Scan() {
txt := scanner.Text() txt := scanner.Text()
for _, lstr := range listener { for _, lstr := range listener {
@ -98,6 +101,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string,
} }
combch <- combevt{txt, false} combch <- combevt{txt, false}
} }
if err := scanner.Err(); err != nil {
errch <- err
}
combch <- combevt{"", true} combch <- combevt{"", true}
wg.Done() wg.Done()
}() }()
@ -107,6 +113,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string,
wg.Add(1) wg.Add(1)
go func() { go func() {
scanner := bufio.NewScanner(stderrBufferReader) scanner := bufio.NewScanner(stderrBufferReader)
if pr.lineBufferSize != nil {
scanner.Buffer([]byte{}, *pr.lineBufferSize)
}
for scanner.Scan() { for scanner.Scan() {
txt := scanner.Text() txt := scanner.Text()
for _, lstr := range listener { for _, lstr := range listener {
@ -114,6 +123,9 @@ func (pr *pipeReader) Read(listener []CommandListener) (string, string, string,
} }
combch <- combevt{txt, false} combch <- combevt{txt, false}
} }
if err := scanner.Err(); err != nil {
errch <- err
}
combch <- combevt{"", true} combch <- combevt{"", true}
wg.Done() wg.Done()
}() }()