2017-07-28 37 views
1

我有一個奇怪的問題,我無法解決。這是我的代碼。爲什麼我無法從ioctl函數接收SIGPOLL信號?

#include <stdio.h> 
#include <stropts.h> 
#include <signal.h> 
#include <sys/types.h> 

void handle_signal(int s) 
{ 
    char c = getchar(); 
    printf("got char '%c'\n"); 
    if(c == 'q') 
    { 
     exit(0); 
    } 
} 

int main(int argc, char** argv) 
{ 
    sigset(SIGPOLL, handle_signal); 
    ioctl(0, I_SETSIG, S_RDNORM); 
    printf("type q to exit"); 
    while(1); 
    return 0; 
} 

當我運行這個程序,我在終端鍵入字符,但它沒有工作!我無法收到SIGPOLL信號。有人可以給我一些建議嗎?順便說一下,我的操作系統是Ubuntu 12.04。

+1

我懷疑你是否可以在信號處理程序中調用'getchar'。 –

+0

是不是你試圖用ioctl中'0'的不同值覆蓋SIGPOLL? – Serge

+0

@ZangMingJie謝謝你的建議,它只是一個測試程序。 – BrianChen

回答

0

在Linux上,需要在文件描述符上設置O_ASYNC標誌和F_SETOWN屬性以獲得SIGIO信號(SIGPOLL的同義詞)。和信號處理程序只能調用異步信號安全功能:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <ctype.h> 

void handle_signal(int) { // Can only use async-signal safe functions here. 
    char msg[] = "got char c\n"; 
    char* c = msg + (sizeof msg - 3); 
    if(1 != read(STDIN_FILENO, c, 1) || !isprint(*c)) 
     return; 
    write(STDOUT_FILENO, msg, sizeof msg - 1); 
    if(*c == 'q') 
     exit(EXIT_SUCCESS); 
} 

int main() { 
    printf("type q to exit\n"); 

    signal(SIGIO, handle_signal); 
    fcntl(STDIN_FILENO, F_SETFL, O_ASYNC | fcntl(STDIN_FILENO, F_GETFL)); 
    fcntl(STDIN_FILENO, F_SETOWN, getpid()); 

    sigset_t mask; 
    sigemptyset(&mask); 
    for(;;) 
     sigsuspend(&mask); 

    return EXIT_SUCCESS; 
} 

你可能也想看看F_SETSIG,以允許收到您的選擇和額外信息的信號到信號處理程序。

+0

感謝您的建議,它實際上在我的電腦中工作。它解決了我的問題。 – BrianChen

相關問題