【问题标题】:sigaction: incorrect member namesigaction:会员名不正确
【发布时间】:2016-08-02 18:42:00
【问题描述】:

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

根据UNIX spec一个struct sigaction应该至少有4个成员; sa_handlersa_masksa_flagssa_sigaction

当我如下定义一个结构时,一切看起来都很正常。

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

但是当我尝试为sa_handler 赋值时,该成员不存在。相反,我看到了这个:

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

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

从 键入'void (*)(int)'

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

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

系统信息:

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

更新 - 2016 年 8 月 3 日

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

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

【问题讨论】:

    标签: c include eclipse-cdt sigaction


    【解决方案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);
      };
    

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

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

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

    ascdsig.sa_handler = &sig_handle;
    

    它会正常工作的。

    【讨论】:

      【解决方案2】:

      &lt;sigaction.h&gt;,你会发现以下#define

      # define sa_sigaction   __sigaction_handler.sa_sigaction
      

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

      sa.__sigaction_handler.sa_sigaction
      

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

      【讨论】:

      • 我在发帖前检查过,signal.h 和 sigaction.h 都有上面提到的行。如果我从未直接编辑过我的系统标头,是否有任何理由导致它们出现问题?
      • 以双下划线开头的名称保留用于实现。应用程序不应依赖它们来实现可移植性。
      • @Nick 这可能意味着未定义 __USE_POSIX199309 功能宏。你能检查一下你的&lt;features.h&gt; 是否有这个定义吗?你是用-std=c99 编译的吗? sigaction 不是 C99 标准的特性,除其他外,将取消对 __USE_POSIX199309 的定义。
      • @Daniel &lt;features.h&gt; 定义 __USE_POSIX99309 1 如果 (_POSIX_C_SOURCE - 0) &gt;= 199309L_POSIX_C_SOURCE 定义为 ((! __STRICT_ANSI__ || (_XOPEN_SOURCE -0) &gt;= 500) &amp;&amp; ! _POSIX_SOURCE &amp;&amp; ! _POSIX_C_SOURCE)。据我所知,应该满足这些标准。
      • @Olaf,感谢您的建议。但更糟糕的是,该软件被设计为在单个系统上运行,因此可移植性不是大问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多