2012-04-16 35 views
0

這是我用代碼中斷一個信號的過程。C中的Interrup信號

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <signal.h> 

int main(void){ 
    void sigint_handler(int sig); /* prototype */ 
    char s[200]; 

    if(signal(SIGINT, sigint_handler) == SIG_ERR){ 
     perror("signal"); 
     exit(1); 
    } 

    printf("Enter a string:\n"); 

    if(gets(s) == NULL) 
     perror("gets"); 
    else 
     printf("You entered: \"%s\"\n", s); 

    return 0; 
} 

void sigint_handler(int sig){ 
    printf("Not this time!\n"); 
} 

問題是如何捕獲信號,如SIGINT,SIGKILL,SIGHUP和SIGTERM?

回答

2

您的sigint_handler函數收到的參數int sig是被捕獲的信號。定義這些值的常量在<signal.h>中。因此,例如

void sigint_handler(int sig){ 
    if (sig == SIGINT) 
     printf("That was a SIGINT!\n"); 
} 
+0

感謝。它現在工作:) – AimanB 2012-04-16 14:49:14

1

或許有點過長後,但這裏是一些示例代碼一起玩:

有一些問題找到一個解決辦法會導致SIGILL沒有編譯器抱怨;但工程至少在GCC - 不過話又說回來了......

的gcc -Wall -pedantic -Wextra -ggdb -std = C89 -o eigabrt eigabrt.c

#include <stdio.h> 
#include <stdlib.h> /* exit() */ 
#include <signal.h> /* signal() */ 
#include <unistd.h> /* sleep() */ 

void explain_sig(int sig) 
{ 
    switch (sig) { 
    case SIGABRT: 
     printf("SIGABRT (abnormal termination)"); 
     break; 
    case SIGFPE: 
     printf("SIGFPE (arithmetic error)"); 
     break; 
    case SIGILL: 
     printf("SIGILL (invalid execution)"); 
     break; 
    case SIGINT: 
     printf("SIGINT ((asynchronous) interactive attention)"); 
     break; 
    case SIGSEGV: 
     printf("SIGSEGV (illegal storage access)"); 
     break; 
    case SIGTERM: 
     printf("SIGTERM ((asynchronous) termination request)"); 
     break; 
    } 
} 

void my_sigtrap(int sig) 
{ 
    printf("\nReceived signal %d, ", sig); 
    explain_sig(sig); 
    putchar('\n'); 

    switch (sig) { 
    case SIGABRT: 
     break; 
    case SIGFPE: 
     printf("Problem with your math\n"); 
     break; 
    case SIGILL: 
     exit(sig); 
     break; 
    case SIGINT: 
     printf("Try once more. I dare you.\n"); 
     /* exit(sig); */ 
     break; 
    case SIGSEGV: 
     /* Everything is udefined, do not free here */ 
     exit(sig); 
     break; 
    case SIGTERM: 
     break; 
    } 

    printf("Restoring to default\n"); 
    signal(sig, SIG_DFL); 
} 

/*void set_trap(void (*new_fun)(int), void (*signal)(int))*/ 
void set_trap(int set_sig, void (*new_fun)(int)) 
{ 
    void (*orig_sig_fun)(int); 

    orig_sig_fun = signal(set_sig, new_fun); 

    printf("Setting my own fun for "); 
    explain_sig(set_sig); 
    printf("\n -- "); 

    if (orig_sig_fun == SIG_IGN) { 
     printf("Was previously ignored.\n"); 
     signal(set_sig, SIG_IGN); 
    } else if (orig_sig_fun == SIG_DFL) { 
     printf("Was handled by default.\n"); 
    } else if (orig_sig_fun == SIG_ERR) { 
     perror("Failed to set signal.\nNo trap\n -- "); 
    } 
} 

void my_exit(void) 
{ 
    printf("my exit called\n"); 
} 

static const unsigned char insn[4] = { 0xff, 0xff, 0xff, 0xff }; 

/* ref. switch satement below for how to trigger various signals 
* I.e.: $ ./my_prog s , causes SIGSEGV */ 
int main(int argc, char *argv[]) 
{ 
    int i = 0; 
    unsigned char action = 'x'; /* default action, ref switch below */ 
    int loops_b4_act = 1;  /* loops before signal is trigged */ 

    int j = 0;    /* Used to cause SIGFPE */ 
    void (*sigill)(void) = (char*)insn; /* Used to cause SIGILL */ 
    int *segv;    /* Used to cause SIGSEGV */ 

    if (argc > 1) 
     action = argv[1][0]; 

    printf("Action to trigger: %c\n", action); 

    atexit(my_exit); 

    set_trap(SIGABRT, &my_sigtrap); 
    set_trap(SIGFPE, &my_sigtrap); 
    set_trap(SIGILL, &my_sigtrap); 
    set_trap(SIGINT, &my_sigtrap); 
    set_trap(SIGSEGV, &my_sigtrap); 
    set_trap(SIGTERM, &my_sigtrap); 

    setbuf(stdout, NULL); /* Turning off buffering */ 
    putchar('.'); 

    while (1) { 
     if (i++ == loops_b4_act) { 
      switch (action) { 
      case 'a': abort(); break; /* cause SIGABRT */ 
      case 'f': i /= j; break; /* casue SIGFPE */ 
      case 'l': sigill(); break; /* casue SIGILL */ 
      case 'i': raise(SIGINT); break; /* cause SIGINT, or, 
          * ie: Ctrl+C */ 
      case 's': *segv = i; break; /* casue SIGSEGV */ 
      case 't': raise(SIGTERM); break;/* cause SIGTERM, or, 
          * ie: kill -15 pid */ 
      case 'x': exit(0); break; /* exit by exit() */ 
      } 
     } 

     sleep(1); 
     putchar('.'); 
    } 

    return 0; 
} 
+0

哦,我的,非常感謝您的時間!它有助於 :) – AimanB 2012-04-16 14:48:56