Linux/TCP IP Socket Programming

Signal handler 코드

값진 2021. 4. 4. 22:34

- SIGINT 처리 예

(유닉스에서 ctrl c 누를 경우 프로세스가 죽음. 이 때 프로그램이 어떻게 시그널로 처리되는지)

- 시스템 콜 수행중의 시그널 처리

- 중복 블록된 시그널 처리

- SIGALARM에 의한 read()의 timeout 예

 

SIGINT 시그널의 기본동작

프로세스를 종료

 

SIGINT 시그널이 발생하면 종료되는 대신, catch_sigint() 함수를 호출하는 프로그램

파일명 : catch_sin3.c
컴파일: gcc -o catch_sin3 catch_sin3.c
실행 : catch_sin3

//헤더파일
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h> //global변수이면서(=전역변수-프로그램의 어느 곳에서라도 참조할 수 있는 변수) & system에서 기본적으로 제공하는 변수. local변수(지역변수)로 사용할 수 없다.
#include<signal.h>

//시그널 핸들러 = 어떠한 시그널이 발생하면 바로 catch_sigint를 처리하도록(점프) 함
void catch_sigint(int signum){
        int count;
        printf("\n(count=%d) CTRL-C pressed!\n",count);
        return;
}

int main(int argc,char*argv[]){
struct sigaction act;         //sigaction 구조체

sigset_t masksets;
int i;
int count;
char buf[10];

sigfillset(&masksets);          //sigfillset호출. maskset이라는 변수의 모든시그널을저장


시그널 핸들러 설치

act.sa_handler=catch_sigint;
//sa_handler에 catch_sigint라는 이름으로 시그널핸들러 저장, catch_sigint라고 이름만지정 (그냥 빈 함수이름)

 //sigaction 구조체에서 많이 사용하는 3가지는 sa_handler (시그널 핸들러), sa_mask (시그널 핸들러 실행중에 블록시킬 시그널을 저장), int sa_flags(환경설정)


//시그널 핸들러가 실행되는 동안 모든 시그널을 블록함

act.sa_mask=masksets;
act.sa_flags=0;
sigaction(SIGINT,&act,NULL);        //sigint발생시 act로 이동

             
for(count=0; count<3; count++){ 
        read(0,buf,sizeof(buf));
return 0;
}

//sigaction은, sigint라는 interrupt가 발생하면(Ctrl-c), act에 저장했던 액션대로 행동해라. 그 액션은 곧 catch_sigint라는 함수로 점프해라

//read에서 0은 키보드에서 읽어라, sizeof(buf)는 buf만큼 읽어라

//키보드에서 어떤 이벤트가 발생하면 buf에 저장하라. 키보드에 입력이 들어올때까지 멈춤상태임(ctrl-c전까지)

여기서ctrl-c를 누르면 sigaction으로가고 act실행, act에서 catch_sigint로 점프 void catch_sigint실행됨

 

//read에서 ctrl-c누르면 sigaction으로 가는 반응은 있지만,

act.sa_flags=0; 이기때문에 read수행을 못하고

그말은 즉, (ctrl-c)입력을 읽지는 못한다.

 

결과값

 

이때 read로 가서 기다림, ctrl-c누르면 catch_sigint실행