假设我正在使用Go语言实现
然而,我不知道如何实现"字符串"形式的信号分发,例如
真正的用例是一个更大的程序的一部分,该程序提示用户发送kill信号; 而不是
问题:
如何在任何支持的平台上,在运行时(或至少不编写针对编译时运行的特定平台代码)将有效的信号名称转换为信号编号?
我尝试过的:
kill
程序。 我可以从命令行接受数字信号和PID,并将它们发送给syscall.Kill
,这没问题。然而,我不知道如何实现"字符串"形式的信号分发,例如
kill -INT 12345
。真正的用例是一个更大的程序的一部分,该程序提示用户发送kill信号; 而不是
kill
的替代品。问题:
如何在任何支持的平台上,在运行时(或至少不编写针对编译时运行的特定平台代码)将有效的信号名称转换为信号编号?
我尝试过的:
- 保持一个静态的信号名称到数字的映射。这种方法在跨平台上不起作用(例如,在Mac OSX和现代Linux以及旧版Linux上,
kill -l
返回的信号列表是不同的)。要使此解决方案通用,唯一的方法是为每个操作系统创建映射,这将需要我了解每个操作系统的行为,并随着它们添加新的信号支持而保持更新。 - 调用GNU
kill
工具并捕获其信号列表。这种方法不够优雅,有点自相矛盾,还需要a)能够找到kill
,b)具有执行子进程的能力/权限,c)能够预测/解析kill
-the-binary的输出。 - 使用各种
Signal
类型的String
方法。这只返回包含信号编号的字符串,例如os.Signal(4).String() == "signal 4"
,这并不实用。 - 调用私有函数
runtime.signame
,它恰好做我想要的事情。使用go://linkname
的方法也可以,但我认为这种做法是被反对的。
我尚未尝试的想法/事情:
- 以某种方式使用CGo。对于一个否则不需要低级本地集成的项目,我宁愿不涉足CGO领域。如果这是唯一的选择,我会考虑,但不知道从哪里开始。
- 使用模板和代码生成器在编译时基于外部源构建信号列表。出于与CGo相同的原因,这不是首选方法。
- 反射并解析以
SIG
开头的syscall
成员。据说这是不可能的,因为名称被编译掉了;对于像信号名称这样基本的东西,有没有地方它们没有被编译掉呢?
strsignal
或使用sys_siglist
数组吗? - Jean-Baptiste Yunèsfor (int i=0; i<NSIG; i++) printf("%d %s (short %s)\n",i,sys_siglist[i],sys_signame[i]);
。实际上我没有练习过 Go 语言。 - Jean-Baptiste Yunès