1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
package linux
import (
"errors"
"os"
"os/exec"
"golang.org/x/sys/unix"
)
// GetErrno checks if the Go error is a kernel errno.
func GetErrno(err error) (errno error, iserrno bool) {
var sysErr *os.SyscallError
if errors.As(err, &sysErr) {
return sysErr.Err, true
}
var pathErr *os.PathError
if errors.As(err, &pathErr) {
return pathErr.Err, true
}
var tmpErrno unix.Errno
if errors.As(err, &tmpErrno) {
return tmpErrno, true
}
return nil, false
}
// ExitStatus extracts the exit status from the error returned by exec.Cmd.
// If a nil err is provided then an exit status of 0 is returned along with the nil error.
// If a valid exit status can be extracted from err then it is returned along with a nil error.
// If no valid exit status can be extracted then a -1 exit status is returned along with the err provided.
func ExitStatus(err error) (int, error) {
if err == nil {
return 0, err // No error exit status.
}
var exitErr *exec.ExitError
// Detect and extract ExitError to check the embedded exit status.
if errors.As(err, &exitErr) {
// If the process was signaled, extract the signal.
status, isWaitStatus := exitErr.Sys().(unix.WaitStatus)
if isWaitStatus && status.Signaled() {
return 128 + int(status.Signal()), nil // 128 + n == Fatal error signal "n"
}
// Otherwise capture the exit status from the command.
return exitErr.ExitCode(), nil
}
return -1, err // Not able to extract an exit status.
}
|