diff --git a/src/app/process/process.go b/src/app/process/process.go index a8ac3cd..919fe0b 100644 --- a/src/app/process/process.go +++ b/src/app/process/process.go @@ -5,6 +5,7 @@ import ( "io" "log" "os/exec" + "sync" ) var ( @@ -22,6 +23,9 @@ type Process struct { process *exec.Cmd stdout io.ReadCloser stderr io.ReadCloser + + wg_exit *sync.WaitGroup + exit chan struct{} } func NewProcess(command string) *Process { @@ -38,40 +42,57 @@ func NewProcess(command string) *Process { } p.StdoutChannel = make(chan string) p.StderrChannel = make(chan string) + p.wg_exit = &sync.WaitGroup{} + p.exit = make(chan struct{}) return p } -func (p Process) Start() error { +func (p *Process) Start() error { err := p.process.Start() if err != nil { return err } - return nil -} -func (p Process) Observe() { + p.wg_exit.Add(2) go func() { scanner := bufio.NewScanner(p.stdout) - for scanner.Scan() { - p.StdoutChannel <- scanner.Text() + for { + select { + case <-p.exit: + p.wg_exit.Done() + return + default: + for scanner.Scan() { + p.StdoutChannel <- scanner.Text() + } + } } }() go func() { scanner := bufio.NewScanner(p.stderr) - for scanner.Scan() { - p.StderrChannel <- scanner.Text() + for { + select { + case <-p.exit: + p.wg_exit.Done() + return + default: + for scanner.Scan() { + p.StderrChannel <- scanner.Text() + } + } } }() + + return nil } -func (p Process) Kill() { +func (p Process) Stop() { p.process.Process.Kill() } -func (p Process) Wait() error { - err := p.process.Wait() - if err != nil { - return err - } - return nil +func (p *Process) Wait() error { + _, err := p.process.Process.Wait() + close(p.exit) + p.wg_exit.Wait() + return err }