2012-03-06 84 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在您的機器上實際上不是一個整數,那麼您的代碼將失敗,錯誤類似於您所得到的。所以,除非你的實現庫,你應該保持良好的狀態並使用庫提供的內容,而不是編寫你自己的標準函數的盜版版本。

相關問題