From 813eadeae1cb046c2ecb05dff6321424a76151eb Mon Sep 17 00:00:00 2001 From: Rafael Quintela Date: Thu, 29 Oct 2020 19:06:11 -0300 Subject: [PATCH] fix stream output --- pkg/wtc/wtc.go | 101 +++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/pkg/wtc/wtc.go b/pkg/wtc/wtc.go index 956393f..96e0a34 100644 --- a/pkg/wtc/wtc.go +++ b/pkg/wtc/wtc.go @@ -6,6 +6,7 @@ import ( "context" "flag" "fmt" + "io" "io/ioutil" "log" "os" @@ -532,87 +533,76 @@ func trig(rule *Rule, pkg, path string) error { return nil } -func pipeChar(tpe, id string, isStderr bool) (*os.File, error) { - ww, rr, err := pty.Open() - if err != nil { - return nil, err - } +func pipeChar(rr io.Reader, tpe, id string, isStderr bool) { reader := bufio.NewReader(rr) - go func() { - defer rr.Close() - me := false + me := false - cancel := make(chan struct{}) + cancel := make(chan struct{}) - for { - r, _, err := reader.ReadRune() - - if !me { - acquire <- struct{}{} - me = true - go func() { - <-cancel - }() - } + for { + r, _, err := reader.ReadRune() - cancel <- struct{}{} + if !me { + acquire <- struct{}{} + me = true + go func() { + <-cancel + }() + } - if err != nil { - (&Rune{Type: tpe, Title: id, End: true, IsStderr: isStderr}).Log() - me = false - <-acquire - return - } + cancel <- struct{}{} - if r == BR { - (&Rune{Type: tpe, Title: id, Rune: r, IsStderr: isStderr}).Log() - me = false - <-acquire - continue - } + if err != nil { + (&Rune{Type: tpe, Title: id, End: true, IsStderr: isStderr}).Log() + me = false + <-acquire + return + } + if r == BR { (&Rune{Type: tpe, Title: id, Rune: r, IsStderr: isStderr}).Log() - - go func() { - select { - case <-cancel: - case <-time.After(time.Second / 2): - me = false - <-acquire - } - }() + me = false + <-acquire + continue } - }() - return ww, nil + (&Rune{Type: tpe, Title: id, Rune: r, IsStderr: isStderr}).Log() + + go func() { + select { + case <-cancel: + case <-time.After(time.Second / 2): + me = false + <-acquire + } + }() + } } func run(ctx context.Context, name, command string, env []string) error { cmd := exec.Command("sh", "-c", command) - stdout, err := pipeChar(TypeCommandOK, name, false) + stdout, tty, err := pty.Open() if err != nil { return err } - cmd.Stdin = stdout - cmd.Stdout = stdout - defer stdout.Close() + defer tty.Close() - stderr, _ := pipeChar(TypeCommandErr, name, true) + stderr, tty2, err := pty.Open() if err != nil { return err } - cmd.Stderr = stderr - defer stderr.Close() + defer tty2.Close() + + cmd.Stdin = os.Stdin + cmd.Stdout = tty + cmd.Stderr = tty2 cmd.Env = env - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setctty: true, - Setsid: true, - } + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} if err := cmd.Start(); err != nil { return err @@ -631,6 +621,9 @@ func run(ctx context.Context, name, command string, env []string) error { close(exit) }() + go pipeChar(stdout, TypeCommandOK, name, false) + go pipeChar(stderr, TypeCommandErr, name, true) + err = cmd.Wait() if err != nil && uint32(cmd.ProcessState.Sys().(syscall.WaitStatus)) == uint32(syscall.SIGKILL) { err = context.Canceled