2012-03-06 65 views
0
#include <signal.h> 
#include <errno.h> 

#define SIGBAD(signo) ((signo) <= 0 || (signo) >= NSIG) 

int sigaddset(sigset_t *set, int signo) 
{ 
     if (SIGBAD(signo)) { errno = EINVAL; return(-1);} 

     *set |= 1 << (signo - 1); 
     return 0; 
} 

int sigdelset(sigset_t *set, int signo) 
{ 
     if (SIGBAD(signo)) { errno =EINVAL; return -1; } 

     *set &= ~(1 << (signo - 1)); 
     return 0; 
} 

int sigismember(const sigset_t *set, int signo) 
{ 
    if (SIGBAD(signo)) { errno = EINVAL; return -1; } 

    return ((*set & (1 << (signo -1))) != 0); 
} 
+1

你为什么要做手动信号位处理?那肯定有系统宏呢? – 2012-03-06 13:17:57

+2

那么,对于初学者,你可以停止将不透明类型视为整数。 – tbert 2012-03-06 13:19:39

+0

你从哪里拿这段代码? mm我认为他在编译现有代码(linux内核?)方面存在问题。他可能只是需要正确的编译器选项。 – vulkanino 2012-03-06 13:25:40

回答

3

这意味着您正试图对不是整数的东西进行位操作,例如,一个结构。

对于sigset_t已经存在名为sigaddset,sigdelsetsigismember的函数,您不应该重新实现它们。 sigset_t是不透明的东西,你不应该闲逛在它与其他但是sigXXXset()函数

2

Data Type: sigset_t

The sigset_t data type is used to represent a signal set. Internally, it may be implemented as either an integer or structure type.

For portability, use only the functions described in this section to initialize, change, and retrieve information from sigset_t objects—don't try to manipulate them directly.

编辑:这里是我的想法。你可能试图编译从某处(一本书,开源等)复制的代码。这些函数已经存在于库中,不应该被重写。但是,如果你真的想这样做,那么请记住原始代码编写者假定sigset_t是一个整数或整数类型,而不是结构。

由于在系统中你正在用sigset_t编译可能(而且我很确定它是)定义为一个结构,所以代码不会编译。

可能的解决方案:

  1. 重新定义sigset_t作为一个整数(不包括在原始sigset_t的定义的系统头)在
  2. 变化的代码编译与定义sigset_t,像下面的例子(超级危险)。

int sigaddset(sigset_t *set, int signo) 
{ 
     if (SIGBAD(signo)) 
     { 
      errno = EINVAL; 
      return(-1); 
     } 

     set->bits |= 1 << (signo - 1); 
     return 0; 
} 
1

修复代码。

位运算符&|运算符要求双方都有整数(两个整数操作数)。

您似乎是(重新)实现标准库函数。因此,您必须知道sigset_t类型的内部结构,但尚不清楚它的类型。如果你不知道类型的细节是什么,那么你没有业务重新实现这些功能。

在Mac OS X上,如果您通过系统头追踪得足够多,sigset_t__uint32_t,所以上面的代码看起来应该可以工作。如果sigset_t在您的机器上实际上不是一个整数,那么您的代码将失败,错误类似于您所得到的。所以,除非你的实现库,你应该保持良好的状态并使用库提供的内容,而不是编写你自己的标准函数的盗版版本。

相关问题