42cursus

[minitalk] sigaction 예제

todoni 2022. 3. 13. 16:16
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

struct	sigaction	act_new;
struct	sigaction	act_prev;

void sigint_handler(int signo)
{
   printf("Ctrl-C(SIGINT) received!!\n");
   printf("Press Ctrl-C again to terminate process.\n");
   sigaction(SIGINT, &act_prev, NULL);
   printf("You'll not see me anymore. bye. :(\n");
}

int main( void)
{
	act_new.sa_handler = sigint_handler; // 시그널 핸들러 지정
	sigemptyset(&act_new.sa_mask);      // 시그널 처리 중 블록될 시그널은 없음
	
	// SIGINT의 sigaction을 act_new로 새로 지정 해주고 act_prev에 원래 sigaction을 저장.
	sigaction(SIGINT, &act_new, &act_prev);

	while(1)
	{
		printf( "running...\n");
		sleep(1);
	}
	printf("bye\n");
	return (0);
}

sigaction 함수가 작동 하는 방식.

원래 Ctrl^C (SIGINT) 신호가 들어오면 ^C라고 뜨면서 터미널이 종료 되는 것을 알 것이다.

sigaction 함수로 action을 지정할 수 있다.

 

act_new의 handler를 우리가 만든 sigint_handler로 지정해준다.

sigaction의 두번째 인자는 새로 지정할 action 구조체의 주소, 세번째는 기존 action 구조체를 저장할 구조체의 주소.

sigaction(SIGINT, &act_new, &act_prev);

이걸 말로 풀어 쓰면

SIGINT의 sigaction을 act_new로 설정을 하겠다.

그리고 act_new로 바뀌기 전의 원래 sigaction은 act_prev에 저장을 하겠다.

가 된다.

 

그래서 처음 프로그램이 실행 되고 Ctrl^C를 하면

기존의 '프로세스 종료'가 아닌 sigint_handler가 호출이 된다.

sigint_handler 함수 내에서는 signal action을 처음에 sigaction을 지정 하기 전 상태인 act_prev로 다시 바꿔줬다.

그리고 다시 Ctrl^C를 하면 기존의 '프로세스 종료' 가 실행 된다.

 

bye는 출력 안 되는 걸로 봐서 저기 까지 안 가고 중간에 끝나버려서 그런건가?

알아 봐야 할 듯 🤔