2017-01-30 13 views
1

Мне нужно получить PID дочернего процесса из структуры siginfo_t. Этот код работает на Solaris:Не удается получить PID из `siginfo_t` в Linux, используя код, который работал на 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; 

Это определение siginfo_t на Solaris (от 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

Имена, начинающиеся с двух символов подчеркивания, зарезервированы для реализации. Это само по себе должно быть индикатором, чтобы не касаться этих полей из вашего приложения. – Olaf

ответ

2

The official specification of siginfo_t (вам нужно будет найти «siginfo_t», нет фрагментов якорей, извините) не показывает любой структуры, которую вы указали. Это внутренняя деталь реализации, которую вы не должны использовать напрямую.

(Как общее правило, вы не должны напрямую использовать ничего в заголовке системы, чье имя начинается с двух символов подчеркивания.)

Изменить код для чтения

pid = info->si_pid; 

, и он будет корректно работать как на Solaris, так и на Linux. Если вы уже не имеете его, также было бы хорошей идеей, чтобы добавить либо

#define _POSIX_C_SOURCE 200809L 

или

#define _XOPEN_SOURCE 700 

до самой верхней части каждого исходного файла (он должен прийти прежде, чем все #include s или он не будет работать) (выберите один или другой, а не оба, в зависимости от того, нужны ли вам функции XSI). Текущие версии Solaris и Linux по умолчанию используют (примерно) этот режим, но активируя его явно, могут предотвратить неожиданности, особенно в старых системах.

Другие полезные ископаемые, начинающиеся с si_ для всех других полезных полей в siginfo_t; спецификация, к которой я привязан, перечисляет общедоступные. Если вам нужно использовать поля, которые являются OS-специфическим, посмотрите в том же заголовке, где вы нашли siginfo_t для #define с видом

#define si_pid __data.__proc.__pid 

и использовать имя si_.

+0

спасибо, попробуй. информация, которую я получил, находится по адресу http://www.qnx.com/developers/docs/660/index.jsp?topic=%2Fcom.qnx.doc.neutrino.lib_ref%2Ftopic%2Fs%2Fsiginfo_t.html –

+0

Oh ghod , что документация просто ужасна. Не доверяйте ему ни за что. – zwol

+1

@girishs: Не верьте этому сайту ничем, кроме того, что выпустил QNX! В любом случае, вы также хотите '#define POSIX_C_SOURCE 200809L' перед' #include ', чтобы обеспечить' siginfo_t' и т. Д.предоставляется в библиотеке GNU C (и вариантах); этот макрос сообщает библиотеке C (заголовкам) раскрывать функциональность POSIX.1 (вплоть до POSIX.1-2008), которая стандартизировала этот материал, как описано на странице zwol, связанной с. –