Let's say I try to acquire a lock, fail, and want to exit the program.
err = syscall.Flock(lockfd, syscall.LOCK_EX|syscall.LOCK_NB)
if err == syscall.EAGAIN {
os.Exit(err)
}
The problem is you need to pass an integer to os.Exit.
I've tried:
os.Exit(int(err))
os.Exit(syscall.EAGAIN)
// Compiles fine, but the cast fails.. no idea why
eerr, _ := err.(*syscall.Errno); os.Exit(int(*eerr))
// panics
reflect.ValueOf(err).Int()
It seems like you can compare the syscall.Errno to other integers, but actually trying to get the value of it is escaping me...
You can normally just convert a syscall.Errno
to an int
if err == syscall.EAGAIN {
os.Exit(int(err))
}
syscall.Errno
is defined as a uintptr
, which can be converted directly to an int
. There's no interface, assertion, or reflection involved.
But when receiving it as an error
interface, you need to assert it first.
if err == syscall.EAGAIN {
os.Exit(int(err.(syscall.Errno)))
}
The syscall.Errno
is used as a value, not a pointer, no need to try and dereference it with *
.
Don't use errno
values as exit codes.
Exit values and errno
values may both be integers, but they otherwise have nothing in common.
In particular, EPERM
is often (always?) "1" but shells often handle/expect that an exit code of one is "alternate success" rather than failure (for example, when grep
doesn't find a match).
An additional example, the sysexits(3) manpage for the BSDs define some values for use with exit
.
However, Go (being more OS agnostic) doesn't use these. E.g. the flag package exits with "2" instead of "64" (EX_USAGE
) as recommended by BSD. (Note, on BSD 64 as an errno value is EHOSTDOWN
).