无法使用在Solaris上运行的代码从Linux上的`siginfo_t`中检索PID

时间:2017-01-30 13:54:10

标签: c linux unix signals pid

我需要从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上运行的代码,请解释一下。

1 个答案:

答案 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_名称。