Merge pull request #6 from warpfork/exec-exitcodes
commit 14b6f0f554ecb0df2288b899fccece9618e61760 · parent 91a00c1f23 · parent e7168030d7
· browse this tree
Eric Myhre, 2021-09-26 21:25:23 UTC
testexec: getting exit codes correctly.
diff --git a/testexec/defaults.go b/testexec/defaults.go index 26d3ad6..3ecad65 100644 --- a/testexec/defaults.go +++ b/testexec/defaults.go @@ -3,6 +3,7 @@ package testexec import ( "io" "os/exec" + "syscall" "testing" ) @@ -12,8 +13,28 @@ func ExecFn_Exec(args []string, stdin io.Reader, stdout, stderr io.Writer) (exit cmd.Stdout = stdout cmd.Stderr = stderr err := cmd.Run() - // FIXME: get the error code. - return -1, err + // A bunch of processing is required to get typical unix error codes out of golang's exec system, unfortunately. + // We're going to: + // - Try to return the exit code, if we can parse it -- and then *not* return an error. + // - Try to return a negative number with the signal if that's what killed things -- and then again *not* return an error. + // - Or return -1000 and an error, for anything else we can't make sense of. + // The -1000 return probably doesn't matter much -- you should check the error first (and where testmark uses this callback, it does), + // but a non-zero value there seems like better defense-in-depth anyway. + if exitErr, ok := err.(*exec.ExitError); ok { + waitStatus, ok := exitErr.Sys().(syscall.WaitStatus) + if !ok { + return exitErr.ExitCode(), nil + } + if waitStatus.Exited() { + return waitStatus.ExitStatus(), nil + } else if waitStatus.Signaled() { + return -int(waitStatus.Signal()), nil + } + } + if err != nil { + return -1000, err + } + return 0, nil } func ScriptFn_ExecBash(script string, stdin io.Reader, stdout, stderr io.Writer) (exitcode int, oshit error) {