我需要从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上运行的代码,请解释一下。
答案 0 :(得分:2)
The official specification of siginfo_t
(您必须搜索&#34; siginfo_t&#34;,没有片段锚,抱歉)没有显示任何结构你引。这是一个你不应该直接使用的内部实现细节。
(作为一般经验法则,您不应该在名称以两个下划线开头的系统标题中直接使用任何。)
将您的代码更改为
pid = info->si_pid;
它将在Solaris和Linux上正常运行。如果您还没有,那么添加
也是个好主意#define _POSIX_C_SOURCE 200809L
或
#define _XOPEN_SOURCE 700
到每个源文件的最顶层(它需要在所有#include
之前或者它不会工作)(选择一个或另一个,而不是两个,取决于你是否需要{ {3}}功能)。当前版本的Solaris和Linux默认(大约)此模式,但显式激活它可以防止意外,特别是对于旧系统。
对于si_
中的所有其他有用字段,还有以siginfo_t
开头的其他名称;我链接的规范列出了普遍可用的规范。如果您需要使用特定于操作系统的字段,请查看您找到siginfo_t
形式的#define
的相同标题
#define si_pid __data.__proc.__pid
并使用si_
名称。