118 lines
4.4 KiB
Go
118 lines
4.4 KiB
Go
package exiter
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"gitlab.com/CRThaze/cworthy/exit"
|
|
)
|
|
|
|
// ExitCode represents an unsigned 16 bit integer used to define exit statuses.
|
|
type ExitCode exit.ExitT
|
|
|
|
const (
|
|
ExitOK ExitCode = ExitCode(exit.EX_OK) // 0: successful termination
|
|
ExitError ExitCode = ExitCode(1) // 1: generic error
|
|
ExitUsage ExitCode = ExitCode(exit.EX_USAGE) // 64: command line usage error
|
|
ExitDataErr ExitCode = ExitCode(exit.EX_DATAERR) // 65: data format error
|
|
ExitNoInput ExitCode = ExitCode(exit.EX_NOINPUT) // 66: cannot open input
|
|
ExitNoUser ExitCode = ExitCode(exit.EX_NOUSER) // 67: addressee unknown
|
|
ExitNoHost ExitCode = ExitCode(exit.EX_NOHOST) // 68: host name unknown
|
|
ExitUnavailable ExitCode = ExitCode(exit.EX_UNAVAILABLE) // 69: service unavailable
|
|
ExitSoftware ExitCode = ExitCode(exit.EX_SOFTWARE) // 70: internal software error
|
|
ExitOSErr ExitCode = ExitCode(exit.EX_OSERR) // 71: system error (e.g., can't fork)
|
|
ExitOSFile ExitCode = ExitCode(exit.EX_OSFILE) // 72: critical OS file missing
|
|
ExitCantCreate ExitCode = ExitCode(exit.EX_CANTCREAT) // 73: can't create (user) output file
|
|
ExitIOErr ExitCode = ExitCode(exit.EX_IOERR) // 74: input/output error
|
|
ExitTempFail ExitCode = ExitCode(exit.EX_TEMPFAIL) // 75: temp failure; user is invited to retry
|
|
ExitProtocol ExitCode = ExitCode(exit.EX_PROTOCOL) // 76: remote error in protocol
|
|
ExitNoPerm ExitCode = ExitCode(exit.EX_NOPERM) // 77: permission denied
|
|
ExitConfig ExitCode = ExitCode(exit.EX_CONFIG) // 78: configuration error
|
|
ExitAbort ExitCode = ExitCode(exit.EX_ABORT) // 134: process was aborted
|
|
)
|
|
|
|
var exitCodeDescs [^ExitCode(0)]string
|
|
|
|
func init() {
|
|
exitCodeDescs = exit.GetAllExitCodeDescriptions()
|
|
exitCodeDescs[ExitError] = "generic error"
|
|
}
|
|
|
|
// Desc returns the description string for a given ExitCode.
|
|
func (e ExitCode) Desc() string {
|
|
return exitCodeDescs[e]
|
|
}
|
|
|
|
// RegisterNewExitCode reserves an ExitCode and stores its corresponding
|
|
// description string for recall.
|
|
// It returns an error if the given integer is already in use or outside the
|
|
// usable range. And also if the description string is empty.
|
|
func RegisterNewExitCode(num int, desc string) (ExitCode, error) {
|
|
if num < 0 || num > int(^ExitCode(0)) {
|
|
return 0, errors.New("New exit code out of range")
|
|
}
|
|
if num == 0 || num == int(exit.EX_ABORT) || (num >= int(exit.EX__BASE) && num <= int(exit.EX__MAX)) {
|
|
return 0, errors.New("New exit code not user reservable")
|
|
}
|
|
if exitCodeDescs[num] != "" {
|
|
return 0, errors.New("New exit code already defined")
|
|
}
|
|
if desc == "" {
|
|
return 0, errors.New("New exit code description cannot be blank")
|
|
}
|
|
exitCodeDescs[num] = desc
|
|
return ExitCode(num), nil
|
|
}
|
|
|
|
// RegisterNextExitCode find the next available ExitCode number and associates the
|
|
// given description string with it.
|
|
// It returns an error if there are no more available numbers to reserve.
|
|
func RegisterNextExitCode(desc string) (ExitCode, error) {
|
|
nextUsable := func(n int) int {
|
|
n++
|
|
for n == int(exit.EX_ABORT) || (n >= int(exit.EX__BASE) && n <= int(exit.EX__MAX)) {
|
|
n++
|
|
}
|
|
return n
|
|
}
|
|
for i := 1; i <= int(^ExitCode(0)); i = nextUsable(i) {
|
|
if exitCodeDescs[i] == "" {
|
|
exitCodeDescs[i] = desc
|
|
return ExitCode(i), nil
|
|
}
|
|
}
|
|
return 0, errors.New("Available exit codes exhausted")
|
|
}
|
|
|
|
func mapCodes(codes []string, offset int, m map[ExitCode]string) {
|
|
for i, desc := range codes {
|
|
if desc != "" {
|
|
m[ExitCode(i+offset)] = desc
|
|
}
|
|
}
|
|
}
|
|
|
|
// UserCodeMap returns a map of ExitCodes and their associated description strings
|
|
// with in the User-Definable range.
|
|
func UserCodeMap() (m map[ExitCode]string) {
|
|
m = map[ExitCode]string{}
|
|
mapCodes(exitCodeDescs[1:exit.EX__BASE], 1, m)
|
|
mapCodes(exitCodeDescs[exit.EX__MAX+1:exit.EX_ABORT], int(exit.EX__MAX)+1, m)
|
|
mapCodes(exitCodeDescs[exit.EX_ABORT+1:], int(exit.EX_ABORT)+1, m)
|
|
return
|
|
}
|
|
|
|
// FullCodeMap returns a map of all ExitCodes and their associated description
|
|
// strings.
|
|
func FullCodeMap() (m map[ExitCode]string) {
|
|
m = map[ExitCode]string{}
|
|
mapCodes(exitCodeDescs[:], 0, m)
|
|
return
|
|
}
|
|
|
|
// GetAllExitCodeDescriptions returns an array of all possible ExitCode description
|
|
// strings (where the index is the exit code). Any unreserved ExitCodes are also
|
|
// included with empty string descriptions.
|
|
func GetAllExitCodeDescriptions() [^ExitCode(0)]string {
|
|
return exitCodeDescs
|
|
}
|