2017-07-28 1 views
1

Ich habe ein seltsames Problem, das ich nicht lösen kann. Das ist mein Code.Warum kann ich das SIGPOLL-Signal nicht von der ioctl-Funktion empfangen?

#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; 
} 

Wenn ich dieses Programm ausführen, tippe ich Zeichen in Terminal, aber es hat nicht funktioniert !!! Ich kann das SIGPOLL-Signal nicht empfangen. Kann mir jemand einen Rat geben? Übrigens, mein Betriebssystem ist ubuntu 12.04.

+1

Ich bezweifle, wenn Sie 'getchar' in einem Signalhandler aufrufen können. –

+0

versuchen Sie nicht SIGPOLL mit einem anderen Wert in ioctl für '0' zu überschreiben? – Serge

+0

@ZangMingJie Danke für den Rat, es ist nur ein Programm für den Test. – BrianChen

Antwort

0

Unter Linux braucht es O_ASYNC Flagge und F_SETOWN Eigentum an der Datei setzen SIGIO Signal (ein Synonym für SIGPOLL) zu erhalten. Und das Signal-Handler kann nur Asynchron-Signal sichere Funktionen aufrufen:

#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; 
} 

Sie auch einen Blick auf F_SETSIG haben mögen, die ein Signal Ihrer Wahl und zusätzliche Informationen in den Signal-Handler ermöglicht Empfang.

+0

Danke für deinen Rat, es funktionierte tatsächlich in meinem Computer. Es hat mein Problem gelöst. – BrianChen

Verwandte Themen