我需要从 siginfo_t
结构中检索子进程的 PID。此代码适用于 Solaris:
siginfo_t *info;
//
// siginfo is initialized with proper data here
//
pid = info->__data.__proc.__pid;
但是当我尝试将代码移植到 Linux 时,出现编译错误:
error: ‘siginfo_t’ has no member named ‘__data’
pid = info->__data.__proc.__pid;
这是 Solaris 上 siginfo_t
的定义(来自 signal.h
):
typedef struct {
int si_signo;
int si_code;
int si_errno;
union {
int __pad[7];
struct {
pid_t __pid;
union {
struct {
uid_t __uid;
union sigval __value;
} __kill; /* si_code <= 0 SI_FROMUSER */
struct {
_CSTD clock_t __utime;
int __status; /* CLD_EXITED status, else signo */
_CSTD clock_t __stime;
} __chld; /* si_signo=SIGCHLD si_code=CLD_* */
} __pdata;
} __proc;
struct {
int __fltno;
void *__fltip;
void *__addr;
int __bdslot;
} __fault; /* si_signo=SIGSEGV,ILL,FPE,TRAP,BUS */
} __data;
} siginfo_t;
但是,Linux signal.h
有完全不同的定义。我不明白如何编写使用 siginfo_t
但同时适用于 Linux 和 Solaris 的代码,请解释一下。
最佳答案
The official specification of siginfo_t
(您必须搜索“siginfo_t”,抱歉,没有片段 anchor )没有显示您引用的任何结构。这是一个内部实现细节,您不应该直接使用。
(根据一般经验,您不应该在名称以两个下划线开头的系统 header 中直接使用任何内容。)
更改您的代码以读取
pid = info->si_pid;
并且它可以在 Solaris 和 Linux 上正常工作。如果您还没有,添加其中一个也是一个好主意
#define _POSIX_C_SOURCE 200809L
或
#define _XOPEN_SOURCE 700
到每个源文件的最顶部(它需要位于所有 #include
之前,否则将不起作用)(选择其中一个,而不是两者,具体取决于您是否需要 XSI 功能)。当前版本的 Solaris 和 Linux 默认为(大约)此模式,但显式激活它可以防止出现意外,尤其是对于较旧的系统。
对于siginfo_t
中的所有其他有用字段,还有以si_
开头的其他名称;我链接到的规范列出了普遍可用的规范。如果您需要使用特定于操作系统的字段,请在您找到 siginfo_t
的同一 header 中查找表单的 #define
#define si_pid __data.__proc.__pid
并使用si_
名称。
关于无法使用在 Solaris 上运行的代码在 Linux 上从 `siginfo_t` 检索 PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41937595/