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

时间:2015-01-23 21:45:26

标签: go system-calls

假设我尝试获取锁定,失败并想要退出程序。

err = syscall.Flock(lockfd, syscall.LOCK_EX|syscall.LOCK_NB)
if err == syscall.EAGAIN {
    os.Exit(err)
}

问题是你需要将一个整数传递给os.Exit。

我试过了:

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

似乎你可以将syscall.Errno与其他整数进行比较,但实际上试图获取它的值正在逃避我......

2 个答案:

答案 0 :(得分:2)

您通常只需将syscall.Errno转换为int

即可
if err == syscall.EAGAIN {
    os.Exit(int(err))
}

syscall.Errno定义为uintptr,可以直接转换为int。没有涉及的界面,断言或反思。

但是当它作为error接口接收时,你需要先断言它。

if err == syscall.EAGAIN {
    os.Exit(int(err.(syscall.Errno)))
}

syscall.Errno用作值,而不是指针,无需尝试使用*取消引用它。

答案 1 :(得分:0)

请勿使用errno值作为退出代码。

退出值和errno值可能都是整数,但它们没有任何共同之处。

特别是,EPERM通常(总是?)“1”但是shell经常处理/期望一个退出代码是“替代成功”而不是失败(例如,当grep时找不到匹配项。)

另一个例子, sysexits(3) manpage 对于BSD,定义了一些用于exit的值。

但是,Go(更多操作系统不可知)不使用这些。 例如。根据BSD的建议,标志包以“2”而不是“64”(EX_USAGE)退出。 (注意,在BSD 64上,errno值为EHOSTDOWN)。