2017-03-17 3 views
1

In C ändern, möchte ich die SIGINT Signal fangen und ausdrucken eine Meldung wie „SIGINT erhalten“ unter Verwendung sigaction und Übergabe eines neuen Handler, um es überKann nicht Standardaktion für SIGINT

sa.sa_sigaction = handler; 

I don Ich möchte das Programm nicht beenden.

Wenn ich mein Programm durch die Shell laufen lasse und das Signal mit Strg + C erzeuge, fängt der Signalhandler das Signal ab und druckt meine Nachricht aus.

Anschließend wird die Standardaktion durchgeführt, die den Prozess beendet.

Was mache ich falsch?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <fcntl.h> 
#include <string.h> 
#include <signal.h> 

static void handler(int sig, siginfo_t* si, void *unused){ 
    if(sig == SIGINT){ 
     printf("Signal %i received\n",si->si_signo); 
    } 
} 

int main(int argc, char* argv[]){ 
    char s [256]; 


    struct sigaction sa; 

    sigemptyset(&sa.sa_mask); 
    sigaddset(&sa.sa_mask, SIGINT); 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = handler; 

    if(sigaction(SIGINT, &sa, NULL) < 0){ 
     perror("sigaction"); 
    } 

    fgets(s,sizeof(s), stdin); 
    printf("%s", s); 
    return 0; 
} 
+0

Was machst du nach der sigaction und vor der Rückkehr von der Hauptleitung? – rici

+0

Ich habe den Code aktualisiert. Ich wiederhole einfach die Benutzereingabe. –

+0

Woher weißt du, dass das Sigint dein Programm beendet? Ich denke, es endet gerade, weil Fgets zurückkommt. – rici

Antwort

1

Das Problem ist, dass fgets den read Systemaufruf rufen wird, und die syscall einen Fehler zurück, wenn sie von SIGINT unterbrochen, man-Seite von Lese sehen:

EINTR Der Aufruf wurde von einem unterbrochen Signal bevor irgendwelche Daten gelesen wurden; siehe Signal (7).

So sollten Sie die errno von fgets überprüfen und wenn es EINTR weiterhin fgets nennen. Versuchen Sie mein aktuelles Programm:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <fcntl.h> 
#include <string.h> 
#include <signal.h> 
#include <errno.h> 

static void handler(int sig, siginfo_t* si, void *unused){ 
    if(sig == SIGINT){ 
     printf("Signal %i received\n",si->si_signo); 
    } 
} 

int main(int argc, char* argv[]){ 
    char s [256]; 


    struct sigaction sa = {0}; 

    sigemptyset(&sa.sa_mask); 
    sigaddset(&sa.sa_mask, SIGINT); 
    sa.sa_flags = SA_SIGINFO; 
    sa.sa_sigaction = handler; 

    if(sigaction(SIGINT, &sa, NULL) < 0){ 
     perror("sigaction"); 
    } 

    char *p; 
    do { 
     p = fgets(s,sizeof(s), stdin); 
    } while (!p && errno == EINTR); 
    printf("%s\n", s); 
    return 0; 
} 
+0

Du hast Recht ... Ich habe den System-Lese-Aufruf vergessen ..... Ich habe es gerade mit einer Endlosschleife (wihle (1)) versucht und es hat funktioniert .... Vielen Dank! –

+0

Gern geschehen! : P – fluter

Verwandte Themen