如何将syscall.Errno传递给os.Exit?

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).