2017-06-14 64 views
0

我在GNU庫中發現了記錄在SIGU信號中的SIGIO信號。據說只要有輸入(特別是套接字),系統就有可能發送信號。 根據創建此類信號的文檔,我應該將O_ASYNC標誌設置爲相應的filedescritor。 我的問題是,我的GNU版本(GCC 6.3.0)不承認這樣的關鍵字:在GNU中設置標準信號SIGIO

error: ‘O_ASYNC’ undeclared (first use in this function)

我用以下塊設置一個標誌:

/* Set socket status async */ 
int status = fcntl(sockfd, F_SETFL, O_ASYNC);; 
if (status < 0) error("Can't set async mode"); 
else printf("Async is set for signal %d\n", SIGIO); 

我用Cigwin GCC 6.3 0.0

的代碼如下:

static void OnTimer(int sig) 
{ 
    /* write request to socket BIO */ 
} 
static void OnTick(int sig) 
{ 
    char read[BUFSIZE] = {}; 
    int received; 

    received = SSL_read(ssl, read, sizeof(read)); 
    /* Handle errors here */ 
    /* print the server's reply */ 
    printf("%s\n\n", read); 
} 

void connectSSL() 
{ 
    /* do all socket set-up and connection */ 

    /* Establish handler for I/O signal */ 
    saction.sa_flags = 0; 
    saction.sa_handler = OnTick; 
    sigemptyset(&saction.sa_mask); 
    sigaddset(&saction.sa_mask, SIGALRM); 
    if (sigaction(SIGIO, &saction, NULL) == -1) error("sigaction"); 
    else printf("OnTick handler created\n"); 

    /* Set socket status async */ 
    int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | FASYNC); 
    if (status < 0) error("Can't set async mode"); 
    else printf("Async is set for signal %d\n", SIGIO); 

    /* Select the process to receive the signal */ 
    int process = fcntl(sockfd, F_SETOWN, getpid()); 
    if (process < 0) error("Can't set address process"); 
    else printf("Process %d is set\n", getpid()); 

    /* do the rest SSL staff here */ 
} 

int main(int argc, char argv[]) 
{ 
    sigset_t mask, oldmask; 
    /* Wait for OnTimer event*/ 
    sigemptyset(&oldmask); 
    sigaddset(&oldmask, SIGALRM); 
    sigemptyset(&mask); 
    sigaddset(&mask, SIGALRM); 
    sigaddset(&mask, SIGIO); 
    sigprocmask(SIG_BLOCK, &mask, &oldmask); 
    connectSSL(); 
    createTimer(500000000); 
    while(1) 
    { 
     printf("\nWaiting OnTimer %d\n", count + 1); 
     sigsuspend(&oldmask); 
    } 

    return 0; 
} 
+0

除了下面我實際的回答:在我的經驗信號控制的I/O開闢了更多的問題比它實際上解決。一旦你從一個信號處理程序(你的操作系統查找「異步安全函數」)中知道你實際上可能做了什麼*,你可能想要將你的設計恢復爲'select'。 – tofro

+0

也許你是對的。不過我想嘗試一下。目前我無法設置這個信號。 –

+0

我並不完全滿意select的一個原因是select在socket中有實際輸入消息之前被調用4次。我猜想select會連續輪詢所有I/O描述符,並在所有其他fds準備就緒時回退1。我需要更快的解決方案 –

回答

0

最大的可能是你忘了,包括不管是間接的還是直接的。這是定義標誌的地方。

如果未定義O_ASYNC,則可嘗試使用該標誌的功能等效前驅FASYNC

另外,還要確保你已經在執行

int flags; 

/* Install signal handler here... */ 

/* Set flags to receive SIGIO (and SIGURG) signals */ 
flags = fcntl (F_GETFL, 0); 
flags = fcntl (F_SETFL, flags | FASYNC); 

/* Bind our process as receiver of SIGIO signals */ 
flags = fcntl (F_SETOWN, getpid()); 
+0

我已經包含了fcntl.h,它用於O_NONBLOCK狀態標誌。我檢查fcntl.h,sys/fcntl.h和_default_fcntl.h的所有三個文件。沒有提到像O_ASYNC這樣的宏。 –

+0

您可以使用'FASINC'嗎?這應該是功能上等同的前身。 – tofro

+0

'FASYNC'我打算寫 – tofro