2016-09-01 3 views
0

sigaction()を使用してsiginterrupt()を実装してください。sigaction()を使用してsiginterrupt()を実装しますか?

#define _XOPEN_SOURCE 700 

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

void helpAndLeave(const char *progname, int status); 
void pexit(const char *fCall); 
int interrupt(int, int); 
void handler(int); 

int main(int argc, char *argv[]) { 
    if (argc != 1) { 
     helpAndLeave(argv[0], EXIT_FAILURE); 
    } 

    /* struct sigaction act; 
     act.sa_handler = &handler; 
    */ 

    interrupt(2,1); 
// while(1); 

    exit(EXIT_SUCCESS); 
} 

void helpAndLeave(const char *progname, int status) { 
    FILE *stream = stderr; 

    if (status == EXIT_SUCCESS) { 
     stream = stdout; 
    } 

    fprintf(stream, "Usage: %s", progname); 
    exit(status); 
} 

void pexit(const char *fCall) { 
    perror(fCall); 
    exit(EXIT_FAILURE); 
} 

int interrupt(int signal, int flag) { 

    printf("interrupt block\n"); 
    struct sigaction act; 
    act.sa_handler = &handler; 

    if (sigaction(SIGINT, NULL, &act) == -1) { 
     return -1; 
    } 

    if (flag) { 
     act.sa_flags &= ~SA_RESTART; 
    } else { 
     act.sa_flags &= SA_RESTART; 
    } 

    if (sigaction(SIGINT, &act, NULL) == -1) { 
     printf("sigaction error\n"); 
     return -1; 
    } 
    printf("exit occur\n"); 
    while(1); 
} 

void handler(int signal) { 
    printf("OMG, INTERRUPTION!!!!!\n"); 
} 

ここでは、(ctrl + c)を入力するとハンドラ関数にはなりません。

ですので、解決策を教えてください。

この例は、this linkにあります。

+0

初めて 'sigaction'を呼び出すと' act'が上書きされますので、 'act.sa_hアンドラーは失われる。 – Barmar

答えて

2

sigaction(SIGINT, NULL, &act)に電話すると、actが信号の現在のハンドラで上書きされます。したがって、act.sa_handlerへの割り当ては上書きされます。あなたはの後にその割り当ての後にする必要があります。

とビットマスクで上のビットをオンにする方法はとても

act.sa_flags &= SA_RESTART; 

があるべき、|、ない&である:

act.sa_flags |= SA_RESTART; 

だから、全体の機能は次のようになります。

int interrupt(int signal, int flag) { 

printf("interrupt block\n"); 
struct sigaction act; 

if (sigaction(SIGINT, NULL, &act) == -1) { 
    return -1; 
} 

act.sa_handler = &handler; 

if (flag) { 
    act.sa_flags &= ~SA_RESTART; 
} else { 
    act.sa_flags |= SA_RESTART; 
} 

if (sigaction(SIGINT, &act, NULL) == -1) { 
    printf("sigaction error\n"); 
    return -1; 
} 
printf("exit occur\n"); 
while(1); 
} 
関連する問題