sigaction() 

Posix의 시그널 핸들러 구현체

#include <signal.h>

int sigaction (int signum, cnost strcut sigaction *act, struct sigaction *oldact);

-signum: 시그널 번호. SIGINT, SIG_IGN, SIG_DFL 등등

-act: 설치할 시그널 핸들러

-oldact: 새 핸들러 설치전 시그널 핸들러 백업. 불필요시 NULL

-return:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct sigaction {
    void     (*sa_handler)(int);   
    // 시그널 핸들러가 호출할 함수. 혹은 매크로 지정 SIG_DFL, SIG_IGN
    // 기본 행동 명시(동작:SIG_DFL, 무시:SIG_IGN)
 
    void     (*sa_sigaction)(int, siginfo_t *void *);  
    // 확장된 시그널 핸들러 사용시 호출할 함수
 
    sigset_t   sa_mask; 
    // 시그널 블로킹 마스크가 저장되는 시그널 세트
   
    int sa_flags;  
    //옵션 플래그
    void (*sa_restorer)(void); 
};
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

블로킹 마스크:sigfillset, sigemptyset, sigaddset, sigdelset 함수로 조작

예)sa_mask가1로채워지만SIGKILL,SIGSTOP제외하고모두블록

 

void (*sa_sigaction)(int, siginfo_t *, void *); 

sa_handler대신에 사용 할 수 있다. 

sa_handler에 비해 추가 정보를 알 수 있다. 

sa_sigaction과 sa_handler 중에 하나만 사용 한다.

sa_sigaction을 사용하려면 sa_flags를 SA_SIGINFO 로 지정 한다.

 

sigset_t  sa_mask; 

시그널마스크:시그널 집합을 의미한다.

 sa_mask에 등록 된 시그널은 시그널핸들러가 실행되는 동안 봉쇄된다. 봉쇄(blocking) 

무시가 아니라 시그널핸들러 실행이 완료 될 때 까지 처리가 미뤄진다. 현재 처리 중인 시그널도봉쇄된다.

 

int sa_flags; 시그널 처리 절차를 수정하는데 사용된다.

SA_SIGINFO sa_handler 대신에 sa_sigaction을 선택한다.

SA_NOCLDSTOP signum이 SIGCHLD일 때 자식 프로세스가 종료되거나 중단되더라도 부모 프로세스는 이를 알려고 하지 않는다.

SA_ONESHOT signum에 대해서 시그널 핸들러를 최초에 한번만 실행하고 그 다움부터는 동일한 시그널에 대해서 SIG_DFL에 해당하는 기본적인 동작만 수행하게 된다.

SA_RESETHAND SA_ONESHOT과 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
 
int num=0;
 
void int_handle(int signum){
    printf("SIGINT:%d\n",signum);
    printf("int_handle called %d times\n",++num);
}
 
main() {
    static struct sigaction act;
    void int_handle(int);
 
    act.sa_handler=int_handle;
    sigfillset(&(act.sa_mask));
    sigaction(SIGINT,&act,NULL);
 
    while(1) {
        printf("i'm sleepy...\n");
        sleep(1);
        if(num>=3)
            exit(0);
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
 
int num=0;
void int_handle(int);
main()
{
    static struct sigaction act;
 
    void int_handle(int);
 
    act.sa_handler=int_handle;
    sigfillset(&(act.sa_mask));
    sigaction(SIGINT,&act,NULL);
 
    while(1) {
        printf("i'm sleepy..\n");
        sleep(1);
 
        if(num>=2){
            act.sa_handler = SIG_DFL;
            sigaction(SIGINT,&act,NULL);
        }
    }
}
 
void int_handle(int signum){
    printf("SIGINT:%d\n",signum);
    printf("int_handle called %d times\n",++num);
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

Signal sets

시그널 세트(signal set)

-복수 개의 시그널(multiple signals)을 표현하는 데이터 형

-sigprocmask 함수 등에서 사용(블록될 시그널을 지정)

 

시그널 세트 데이터 형 (data type)

-변수의 각 비트가 하나의 시그널을 지칭

-31개까지의 시그널은 정수형 변수로 표현 (4.3+BSD)

-시그널 개수가 많은 경우 sigset_t형의 변수를 사용

 

#include int sigemptyset(sigset_t *set); //set sigset_t형의 시그널 집합, signum 시그널 번호

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set, int signum);

int sigdelset(sigset_t *set, int signum);

int sigismember(const sigset_t *set, int signum);

 

시그널 집합에 지정한 시그널이 포함되어 있는지를 검사

sigemptyset(set) set으로 주어진 시그널 집합을 아무런 시그널도 포함되어 있지 않은 비어 있는 상태로 초기화

sigfillset(set) sigemptyset와는 반대로 모든 시그널이 포함된 상태로 시그널 집합을 초기화한다.

sigaddset, sigdelset 시그널 집합에서 지정한 시그널을 추가하거나 제거한다.

 

sigset_t 조작 함수

int sigemptyset(sigset_t *set); 모두 비우는 함수. set를 모두 0으로 만든다.

int sigaddset(sigset_t *set, int signo); 시그널 세트 특정 시그널 번호에게 1개 비트 채운다.

int sigdelset(sigset_t *set, int signo); 시그널 세트 특정 시그널 번호에 1개 비트 지운다.

int sigfillset(sigset_t *set); 모든 시그널 채운다.

int sigismember(const sigset_t *set, int signo);

 

보통 채울 시그널이 많으면 sigfillset로 채우고 sigemptyset으로 채우지 않을 시그널을 뺀다.

채울 시그널이 적으면 sigemptyst으로 모두 비우고 sigaddset으로 채울 시그널만 지정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <signal.h>
#include <string.h>
#include <stdio.h>
void sa_handler_usr(int signum); 
int main()
{
    struct sigaction sa_usr1;
    struct sigaction sa_usr2; 
 
    memset(&sa_usr1, 0sizeof(struct sigaction));  
    sa_usr1.sa_handler = sa_handler_usr; 
    sigfillset(&sa_usr1.sa_mask); 
 
    memset(&sa_usr2, 0sizeof(struct sigaction)); 
    sa_usr2.sa_handler = sa_handler_usr;    
    sigemptyset(&sa_usr2.sa_mask); 
 
    sigaction(SIGUSR1, &sa_usr1, NULL); // filled sa_mask
    sigaction(SIGUSR2, &sa_usr2, NULL); // empty sa_mask 
 
    printf("[MAIN] SIGNAL-Handler installed, pid(%d)\n",getpid());
 
    for(;;)
    {
        pause();
        printf("[MAIN] Recv SIGNAL...\n");
    }
    return 0;
}
 
 
void sa_handler_usr(int signum){
    int i;
    for(i=0;i<10;i++)
    {
        printf("\tSignal (%s) : %d sec.\n",
        signum==SIGUSR1 ? "USR1" : "USR2",i);
        sleep(1);
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

+ Recent posts