From 6c1fa2f06150e9c24ee155f55259b28abf950831 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Tue, 1 Aug 2023 05:09:48 +0000 Subject: [PATCH] fix timeout not working on linux/mac --- agent/agent.go | 56 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index a8db028..4020052 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -254,7 +254,7 @@ type CmdOptions struct { func (a *Agent) NewCMDOpts() *CmdOptions { return &CmdOptions{ Shell: "/bin/bash", - Timeout: 30, + Timeout: 60, } } @@ -322,38 +322,46 @@ func (a *Agent) CmdV2(c *CmdOptions) CmdStatus { } }() + statusChan := make(chan gocmd.Status, 1) // workaround for https://github.com/golang/go/issues/22315 - for i := 0; i < 5; i++ { - <-envCmd.Start() - - <-doneChan - - status := envCmd.Status() - - if errors.Is(status.Error, syscall.ETXTBSY) { - a.Logger.Errorln("CmdV2 syscall.ETXTBSY, retrying...") - time.Sleep(500 * time.Millisecond) - } else { - break - } - } - go func() { - select { - case <-doneChan: + for i := 0; i < 5; i++ { + finalStatus := <-envCmd.Start() + if errors.Is(finalStatus.Error, syscall.ETXTBSY) { + a.Logger.Errorln("CmdV2 syscall.ETXTBSY, retrying...") + time.Sleep(500 * time.Millisecond) + continue + } + statusChan <- finalStatus return - case <-ctx.Done(): - a.Logger.Debugf("Command timed out after %d seconds\n", c.Timeout) - pid := envCmd.Status().PID - a.Logger.Debugln("Killing process with PID", pid) - KillProc(int32(pid)) } }() + var finalStatus gocmd.Status + + select { + case <-ctx.Done(): + a.Logger.Debugf("Command timed out after %d seconds\n", c.Timeout) + pid := envCmd.Status().PID + a.Logger.Debugln("Killing process with PID", pid) + KillProc(int32(pid)) + finalStatus.Exit = 98 + ret := CmdStatus{ + Status: finalStatus, + Stdout: CleanString(stdoutBuf.String()), + Stderr: fmt.Sprintf("%s\nTimed out after %d seconds", CleanString(stderrBuf.String()), c.Timeout), + } + a.Logger.Debugf("%+v\n", ret) + return ret + case finalStatus = <-statusChan: + // done + } + // Wait for goroutine to print everything <-doneChan + ret := CmdStatus{ - Status: envCmd.Status(), + Status: finalStatus, Stdout: CleanString(stdoutBuf.String()), Stderr: CleanString(stderrBuf.String()), }