2

我正在将程序的信号处理从 signal() 转换为 sigaction()。

根据UNIX 规范, astruct sigaction至少应该有 4 个成员;sa_handler, sa_mask,sa_flagssa_sigaction.

当我如下定义一个结构时,一切似乎都很正常。

...
#include <signal.h>
...
struct sigaction sa;

但是当我尝试为 赋值时sa_handler,该成员不存在。相反,我看到了这个: 图片:显示 __sigaction_handler : {sigaction.h:1092} 而不是 sa_handler

我查看了我的signal.hand bits/sigaction.h(如果你想知道的话,两者都没有 1092 行),似乎没有任何问题。

我也尝试按原样使用此成员名称,但编译器抱怨

从类型'void(*)(int)'分配给类型'union'时无法比较的类型

这让我觉得我的编译器/IDE 处理结构定义的方式有问题,但这超出了我的诊断范围。

任何帮助或建议将不胜感激。

系统信息:

  • Debian 8
  • linux 3.16.0-4-amd64
  • gcc 4.9.2 (Debian 4.9.2-10)
  • 日食-cdt 3.8.1

更新 - 2016 年 8 月 3 日

在此处此处找到这两个线程,建议分别定义预处理器符号_POSIX_C_SOURCE_XOPEN_SOURCE。我定义了每一个(一次一个)并且都“修复”了不兼容的类型问题(我成功地为 sa.__sigaction_handler 分配了一个值)。但是它们都破坏了我的软件使用类型 intptr_t(用于线程函数管理)的能力,并因此被删除。

但是,这样做可以解决问题。我现在可以为 sa.sa_handler 分配一个变量,而编译器不会抛出错误。IDE 仍将其显示为不存在的成员(与上面链接的图像相同),但恕我直言,这是一个小问题。

4

2 回答 2

1

struct sigaction是我的系统标头中定义的方式:

/* Structure describing the action to be taken when a signal arrives.  */
struct sigaction
  {
    /* Signal handler.  */
#ifdef __USE_POSIX199309
    union
      {
    /* Used if SA_SIGINFO is not set.  */
    __sighandler_t sa_handler;
    /* Used if SA_SIGINFO is set.  */
    void (*sa_sigaction) (int, siginfo_t *, void *);
      }
    __sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction   __sigaction_handler.sa_sigaction
#else
    __sighandler_t sa_handler;
#endif

    /* Additional set of signals to be blocked.  */
    __sigset_t sa_mask;

    /* Special flags.  */
    int sa_flags;

    /* Restore handler.  */
    void (*sa_restorer) (void);
  };

注意 if__USE_POSIX199309是如何定义的(它在我的系统上,并且可能在你的系统上),然后它没有直接命名为sa_handlerand的字段sa_sigaction,而是有一个名为__sigaction_handler, 联合类型的字段,它又具有名为sa_handlerand的字段sa_sigaction。因此,可以通过__sigaction_handler.sa_handler和访问字段__sigaction_handler.sa_sigaction,但为了满足规范,它还定义了宏sa_handlersa_sigaction,分别扩展为__sigaction_handler.sa_handler__sigaction_handler.sa_sigaction,因此您可以使用这些宏来命名字段。

现在,Eclipse 不明白这两个宏应该充当字段名称,因此当您调用内容辅助时,它只提供完成建议。

尽管如此,您应该可以将它们用作代码中的字段名称。也就是说,只需键入:

ascdsig.sa_handler = &sig_handle;

它会正常工作。

于 2017-01-07T20:54:34.793 回答
0

<sigaction.h>中,您会发现以下内容#define

# define sa_sigaction   __sigaction_handler.sa_sigaction

如果您希望修复此特定错误,可以将此行添加到代码中以解决问题或直接访问它:

sa.__sigaction_handler.sa_sigaction

但是,我感觉这表明您的系统标头存在更深层次的问题。你能检查一下<signal.h>#include <bits/sigaction.h>?你能检查一下sigaction.h#define

于 2016-08-02T19:10:54.487 回答