<4D F736F F F696E74202D BDC3B1D7B3CEB0FA20BDC3B1D7B3CE20C3B3B8AE2E707074>

Similar documents
Microsoft PowerPoint - 10_Signal

본 강의에 들어가기 전

Microsoft PowerPoint - ch07_시그널 [호환 모드]

Microsoft PowerPoint - SP6장-시그널.ppt [호환 모드]

2009년 상반기 사업계획

좀비프로세스 2

제1장 Unix란 무엇인가?

슬라이드 1

1장. 유닉스 시스템 프로그래밍 개요

Chap04(Signals and Sessions).PDF

/chroot/lib/ /chroot/etc/

ABC 11장

The Pocket Guide to TCP/IP Sockets: C Version

System Programming Lab

Microsoft PowerPoint - 09-Pipe

3. 다음장에나오는 sigprocmask 함수의설명을참고하여다음프로그램의출력물과그출력물이화면이표시되는시점을예측하세요. ( 힌트 : 각줄이표시되는시점은다음 4 가지중하나. (1) 프로그램수행직후, (2) kill 명령실행직후, (3) 15 #include <signal.

<C1A63130C0E5C7C1B7CEBCBCBDBA2E687770>

<4D F736F F F696E74202D FC7C1B7CEBCBCBDBA20BBFDBCBAB0FA20BDC7C7E0205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

Chapter #01 Subject

6주차.key

10.

K&R2 Reference Manual 번역본

제9장 프로세스 제어

int main(void) int a; int b; a=3; b=a+5; printf("a : %d \n", a); printf("b : %d \n", b); a b 3 a a+5 b &a(12ff60) &b(12ff54) 3 a 8 b printf(" a : %x \

슬라이드 1

금오공대 컴퓨터공학전공 강의자료

chap12(process).hwp

Microsoft PowerPoint - chap9 [호환 모드]

리눅스 프로세스 관리

untitled

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

3. 다음장에나오는 sigprocmask 함수의설명을참고하여다음프로그램의출력물과그출력물이화면이표시되는시점을예측하세요. ( 힌트 : 각줄이표시되는시점은다음 6 가지중하나. (1) 프로그램수행직후, (2) 5 초후 (3) 10 초후 (4) 15 #include <signa

Microsoft PowerPoint - 10_Process

슬라이드 1

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

歯9장.PDF

4. What will be the output of this program? Explain results for each variable and each thread. #include "apue.h" int var=1; pthread_mutex_t lock; void

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

제1장 Unix란 무엇인가?

C 언어 프로그래밊 과제 풀이

Frama-C/JESSIS 사용법 소개

Microsoft PowerPoint - chap11-포인터의활용.pptx

Microsoft PowerPoint - chap10-함수의활용.pptx

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

11장 포인터

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

제1장 Unix란 무엇인가?

UI TASK & KEY EVENT

슬라이드 1

5. 소켓 프로그래밍

11장 포인터

untitled

2009년 상반기 사업계획

Microsoft PowerPoint - ch09_파이프 [호환 모드]

2009년 상반기 사업계획

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint - chap05-제어문.pptx

Infinity(∞) Strategy

PowerPoint 프레젠테이션

제1장 Unix란 무엇인가?

chap7.key

UI TASK & KEY EVENT

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

SYN flooding

Microsoft PowerPoint - 12 ¼ÒÄÏÀ» ÀÌ¿ëÇÑ Åë½Å 1.ppt

PowerPoint 프레젠테이션

2015 개정교육과정에따른정보과평가기준개발연구 연구책임자 공동연구자 연구협력관

The Pocket Guide to TCP/IP Sockets: C Version


PowerPoint 프레젠테이션

<4D F736F F F696E74202D FB8DEB8F0B8AE20B8C5C7CE205BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

UI TASK & KEY EVENT

chap 5: Trees

untitled

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

2009년 상반기 사업계획

<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

제12장 파일 입출력

chap8.PDF

학번 : 이름 1. 다음프로그램실행결과를예측하시오. $./a.out & [1] 7216 $ kill -USR $ kill -USR 아래학생이작성한쓰레드코드의문제점을설명하시오. void* thread_main() { pthread_mutex_t

Microsoft PowerPoint - chap06-2pointer.ppt

설계란 무엇인가?

3. 1 포인터란 3. 2 포인터변수의선언과사용 3. 3 다차원포인터변수의선언과사용 3. 4 주소의가감산 3. 5 함수포인터

윤성우의 열혈 TCP/IP 소켓 프로그래밍

C++ Programming

쉽게 풀어쓴 C 프로그래밍

03장.스택.key

Chapter_06

Transcription:

10 장시그널과시그널처리 시그널과시그널처리 - sigemptyset, sigfillset - sigaddset, sigdelset, sigismember - sigaction - sigprocmask - kill, raise - alarm - pause 1

1. 서론 시그널의종류 이름설명 DA SIGABRT abort() 를호출할때발생 SIGALRM 설정된알람시간이경과한겨우발생 SIGCHLD 자식프로세스가일시중단되거나종료될때발생 SIGINT CTRL-C 를눌렀을때발생 SIGKILL 프로세스를강제종료시킬때사용 SIGPIPE reader 가종료되었는데 write 하는경우발생 SIGQUIT CTRL- 를눌렀을때발생 TC T IGN T T T TC SIGSEGV 잘못된메모리참조시발생 SIGUSR1 사용자가임의의목적으로사용 SIGUSR2 사용자가임의의목적으로사용 TC T T 2

1. 서론 시그널을받은프로세스는다음중한가지방법으로대응한다. 1. default action ( 대부분의시그널에대해서프로세스는종료하게된다.) 2. ignore signal ( 단, SIGKILL 과 SIGSTOP 은무시될수없다.) 3. catch signal ( 프로그래머가지정한함수 ( 시그널핸들러 ) 를호출한다.) 아무런설정도하지않은경우 default action 을취한다. 시그널을무시하거나시그널핸들러가호출되도록설정 할수있다. 3

1. 서론 signal 함수 시그널이전달되었을때어떻게대응할것인가를설정 void (*signal (int signo, void (*func) (int)))(int); signo 시그널번호 func void f(int) 와같은형태의함수에대한포인터 반환값 성공하면이전에설정된 disposition 을반환하고, 실패하면 SIG_ERR 을반환한다. 4

1. 서론 시그널을받았을때 default action 을취하도록설정 signal(sigint, SIG_DFL); Signal(SIGQUIT, SIG_DFL); 시그널을받았을때무시하도록설정 signal(sigint, SIG_IGN); signal(sigquit, SIG_IGN); signal() 을호출한이후에전달된시그널에대해서만적용됨. 시그널을받았을때시그널핸들러가호출되도록설정 signal(sigint, f); signal(sigquit, g); void f(int signo) void g(int signo) 5

1. 서론 CTRL-C 를눌러도죽지않는프로그램 #include <stdio.h> main() signal(sigint, SIG_IGN); while (1) printf( Die Hard n ); sleep(1); 6

1. 서론 CTRL-C 를눌렀을때시그널핸들러 f() 가호출되는프로그램 (1) #include <stdio.h> void f(int signo); int counter = 0; main() signal(sigint, f); 시그널이발생하여핸들러가호출되면 이전에설정된내용은지워지고 SIG_DFL 로설정이변경되어버린다. while (counter < 10) printf( Die Hard n ); sleep(1); printf( I am dying n ); void f(int signo) printf( signo = %d, counter = %d n, signo, counter); counter++; 7

1. 서론 CTRL-C 를눌렀을때시그널핸들러 f() 가호출되는프로그램 (2) #include <stdio.h> void f(int signo); int counter = 0; main() signal(sigint, f); 시그널이발생하여핸들러가호출되면이전에설정된내용은지워지고 SIG_DFL 로설정이변경되어버린다. 따라서핸들러에서는항상재설정을해주어야한다. while (counter < 10) printf( Die Hard n ); sleep(1); printf( I am dying n ); void f(int signo) signal(sigint, f); printf( signo = %d, counter = %d n, signo, counter); counter++; 8

1. 서론 시그널을다루기위해필요한시스템호출 / 표준라이브러리함수 함수 의미 sigemptyset 시그널집합을공집합으로만든다. sigfillset 시그널집합을모든시그널이포함된전체집합으로만든다. sigaddset 시그널집합에특정시그널을추가한다. sigdelset 시그널집합에서특정시그널을제외시킨다. sigaction 특정시그널에대한프로세스의행동을설정한다. sigprocmask 봉쇄 (block) 할시그널의목록을변경한다. kill 특정프로세스에게특정시그널을보낸다. raise 자기자신에게특정시그널을보낸다. alarm 설정된시간이경과한후 SIGALRM 시그널을받는다. pause 시그널이도착할때까지대기상태가된다. 9

예제 예제프로그램 (1/2) #include <unistd.h> void handler(int signum); int flag = 5; main() struct sigaction act; sigset_t set; sigemptyset(&(act.sa_mask)); sigaddset(&(act.sa_mask), SIGALRM); sigaddset(&(act.sa_mask), SIGINT); sigaddset(&(act.sa_mask), SIGUSR1); act.sa_handler = handler; sigaction(sigalrm, &act, NULL); sigaction(sigint, &act, NULL); sigaction(sigusr1, &act, NULL); printf("call raise(sigusr1) before blocking n"); raise(sigusr1); sigemptyset(&set); sigaddset(&set, SIGUSR1); sigprocmask(sig_setmask, &set, NULL); 10

예제 예제프로그램 (2/2) while (flag) printf("input SIGINT [%d] n", flag); sleep(1); printf("call kill(getpid(), SIGUSR1) after blocking n"); kill(getpid(), SIGUSR1); printf("sleep by pause.. zzzz n"); printf("pause return %d n", pause()); printf("2 seconds sleeping..zzz n"); alarm(2); pause(); void handler(int signum) flag--; switch(signum) case SIGINT: printf("sigint(%d) n", signum); break; case SIGALRM: printf("sigalrm(%d) n", signum); break; case SIGUSR1: printf("sigusr1(%d) n", signum); break; default: printf("signal(%d) n", signum); 11

실행결과 $ ex10-01 call raise(sigusr1) before blocking SIGUSR1(10) input SIGINT [4] input SIGINT [4] SIGINT(2) input SIGINT [3] SIGINT(2) input SIGINT [2] input SIGINT [2] SIGINT(2) input SIGINT [1] SIGINT(2) call kill(getpid(), SIGUSR1) after blocking sleep by pause.. zzzz SIGINT(2) pause return -1 2 seconds sleeping..zzz SIGALRM(14) 12

2. sigemptyset, sigfillset, sigaddset, sigdelset, sigismember 시그널집합을생성하거나조작한다. int sigemptyset(sigset_t *set); 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); set sigset_t 타입의시그널집합이다. signum 시그널번호이다. 반환값 성공하면 0 을반환하고, 실패하면 -1 을반환한다. 단 sigisnumber 는성공하면 1 이나 0 을반환하고실패하면 -1 을반환한다. 시그널을다루려면시그널집합을만들어야한다. 13

2. sigemptyset, sigfillset, sigaddset, sigdelset, sigismember sigemptyset(set) set 으로주어진시그널집합을아무런시그널도포함되어있지않은 공집합으로만든다. sigfillset(set) sigemptyset 와는반대로모든시그널이포함된상태로시그널집합을초기화한다. sigaddset, sigdelset 시그널집합에서지정한시그널을추가하거나제거한다. sigismember 시그널집합에지정한시그널이포함되어있는지를검사한다. 14

예제 10-2 ex10-02.c #include <unistd.h> main() sigset_t set; int result; $ ex10-02 SIGALRM is not a member SIGALRM is a member SIGCHLD is a member SIGCHLD is not a member sigemptyset(&set); result = sigismember(&set, SIGALRM); printf("sigalrm is %s a member n", result? "" : "not"); sigaddset(&set, SIGALRM); result = sigismember(&set, SIGALRM); printf("sigalrm is %s a member n", result? "" : "not"); sigfillset(&set); result = sigismember(&set, SIGCHLD); printf("sigchld is %s a member n", result? "" : "not"); sigdelset(&set, SIGCHLD); result = sigismember(&set, SIGCHLD); printf("sigchld is %s a member n", result? "" : "not"); 15

3. sigaction 특정한시그널을받았을때프로세스가취해야할행동을지정한다 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); signum 시그널번호이다. SIGKILL 과 SIGSTOP 은적용할수없다. act 시그널에대해서취할행동에관한정보가담겨져있다. oldact 이전에설정되어있던시그널에대한행동에관한정보를가지고온다. 이정보가필요없다면 NULL 값을준다. 반환값 호출이성공할경우 0 을반환하고, 실패하면 -1 을반환한다. signum 으로지정한시그널에대해서 act 로지정한행동을취한다. 새로운행동인 act 가등록되면서기존의행동은 oldact 에저장된다. 16

3. sigaction sigaction 구조체 struct sigaction void (*sa_handler)(int); sigset_t sa_mask; int sa_flags; void (*sa_handler)(int); signum 으로지정된시그널이왔을때호출할함수를지정한다. SIG_DFL 기본적으로설정된행동. 대부분의시그널에대해서프로세스는종료 SIG_IGN 해당시그널을무시. ( 단, SIGSTOP 과 SIGKILL 은무시할수없음 ) 핸들러주소 사용자가정의한시그널핸들러에대한주소이다. 17

3. sigaction sigset_t sa_mask; 시그널마스크 : 봉쇄 (block) 할시그널을집합으로나타낸다. sa_mask 에등록된시그널은시그널핸들러가실행되는동안 봉쇄된다. 봉쇄 (blocking) 무시가아니라시그널핸들러실행이완료될때까지처리를미룬다. 현재처리중인시그널도봉쇄된다. 봉쇄로인해프로세스에게아직전달되지않은시그널은 pending 되어있다고한다. 18

3. sigaction int sa_flags; 시그널처리에대한옵션을설정하는데사용된다. 값 의미 SA_NOCLDSTOP signum 이 SIGCHLD 일때자식프로세스가일시중단되었을때 SIGCHLD 가발생되지않도록한다. 자식프로세스가종료되었을때에는 SIGCHLD 가발생함. SA_RESETHAND 시그널발생에의해핸들러호출시 SIG_DFL 로 reset 한다. 19

예제 10-3 ex10-03.c #include <unistd.h> int num = 0; main() static struct sigaction act; void int_handle(int); act.sa_handler = int_handle; sigfillset(&act.sa_mask); sa.sa_flags = 0; sigaction(sigint, &act, NULL); while (1) printf("i'm sleepy.. n"); sleep(1); if (num >= 3) exit(0); void int_handle(int signum) printf("sigint:%d n", signum); printf("int_handle called %d times n", ++num); $ ex10-03 i'm sleepy.. SIGINT:2 int_handle called 1 times i'm sleepy.. i'm sleepy.. SIGINT:2 int_handle called 2 times i'm sleepy.. SIGINT:2 int_handle called 3 times $ 20

예제 10-4 ex10-04.c #include <unistd.h> int num = 0; main() static struct sigaction act; void int_handle(int); act.sa_handler = int_handle; sigfillset(&act.sa_mask); act.sa_flags = 0; 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); $ ex10-04 i'm sleepy.. SIGINT:2 int_handle called 1 times i'm sleepy.. SIGINT:2 int_handle called 2 times i'm sleepy.. $ 21

예제 10-4 ex10-04.c #include <unistd.h> int num = 0; main() static struct sigaction act; void int_handle(int); act.sa_handler = int_handle; sigfillset(&act.sa_mask); act.sa_flags = SA_RESETHAND; 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); $ ex10-04 i'm sleepy.. SIGINT:2 int_handle called 1 times i'm sleepy.. i'm sleepy.. $ 22

4. sigprocmask 봉쇄할시그널들을지정하거나해제하는데사용된다. int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); how sigprocmask 함수의행동방식을지정한다. set 새롭게적용할시그널마스크이다. oldset 이전에적용되어있는시그널마스크값을가져온다. 반환값 호출이성공할경우 0 을반환하고, 실패하면 -1 을반환한다. 프로세스가대단히중요한코드를실행중일때작업에방해를받지않기위해시그널을무시할수도있다. 시그널봉쇄 중요한작업수행 시그널봉쇄해제 23

4. sigprocmask int how 값 의미 SIG_BLOCK 현재봉쇄설정된시그널목록에두번째인자 set 로주어진시그널들을추가한다. SIG_UNBLOCK 현재봉쇄설정된시그널목록에서두번째인자 set 로주어진시그널들을제외한다. SIG_SETMASK 현재봉쇄설정된시그널목록을두번째인자 set 로주어진시그널들로대체한다. If there are any pending, unblocked signals after the call to sigprocmask, at least one of these signals is delivered to the process before sigprocmask returns. 24

예제 10-5 ex10-05.c #include <unistd.h> main() sigset_t set; int count = 3; sigemptyset(&set); sigaddset(&set, SIGINT); $ ex10-05 don't disturb me (3) don't disturb me (2) don't disturb me (1) you did not disturb me!! $ ex10-05 don't disturb me (3) don't disturb me (2) 이쯤에서 CTRL-C 입력 don't disturb me (1) $ sigprocmask(sig_block, &set, NULL); while (count) printf("don't disturb me (%d) n", count--); sleep(1); sigprocmask(sig_unblock, &set, NULL); printf("you did not disturb me!! n"); 25

5. kill, raise kill 은특정프로세스나프로세스그룹에게지정한시그널을전달 raise 는자기자신에게지정한시그널을전달 #include <sys/types.h> int kill(pid_t pid, int sig); int raise(int sig); pid 프로세스의식별번호이다. sig 시그널번호이다. 반환값 호출이성공하면 0 을반환하고, 실패하면 -1 을반환한다. 26

5. kill, raise kill 의 pid 의값에따른의미 pid 의미 pid > 0 프로세스의식별번호이다. 해당프로세스에게만시그널을보낸다 pid = 0 자신과같은그룹에있는모든프로세스에게시그널을보낸다. pid = -1 자신과같은그룹에있는모든프로세스에게시그널을보낸다. 단, 프로세스식별번호가 1 인프로세스를제외한다. pid < -1 pgid 가 pid 인모든프로세스에게시그널을보낸다. 즉, pid 가 -100 이라면 pgid 가 100 인모든프로세스에게시그널을보낸다. kill 과 raise raise(sig) = kill(getpid(), sig); 27

예제 10-6 ex10-06.c #include <unistd.h> #include <sys/types.h> main() pid_t pid; int count = 5; $ ex10-06 [child] count is 5 [child] count is 4 $ if ((pid = fork()) > 0) sleep(2); kill(pid, SIGINT); raise(sigint); printf("[parent] bye! n"); else if (pid == 0) while (count) printf("[child] count is %d n", count--); sleep(1); 28

6. alarm 지정한시간이경과한후에자신에게 SIGALRM 시그널을보낸다 #include <unistd.h> unsigned int alarm(unsigned int seconds); seconds 초단위의시간이다. 반환값 알람을설정한후남은시간을반환한다. 0 이상의값이다. 알람설정은한번에하나만등록할수있다. 여러개를누적해서등록할수없다. 마지막에등록한하나의알람만유효하다. 알람을재등록할경우이전에등록된알람은취소된다. 알람을해제하려면 alarm(0) 를호출한다. 지금까지사용했던 sleep() 함수는 SIGALRM 과 pause() 함수를사용하여구현되었다. sleep() 과 alarm() 은함께사용하지않는것이좋다. 29

예제 10-7 ex10-07.c #include <unistd.h> void timeover(int signum) printf(" n ntime over!! n n"); exit(0); main() char buf[1024]; char *alpha = "abcdefghijklmnopqrstuvwxyz"; int timelimit; struct sigaction act; $ ex10-07 input timelimit (sec).. 100 START!! > abcdefghijklmnopqrstuvwxyz well done.. you succeed! $ ex10-07 input timelimit (sec).. 3 START!! > abcdefghijk time over!! $ act.sa_handler = timeover; sigaction(sigalrm, &act, NULL); printf("input timelimit (sec).. n"); scanf("%d", &timelimit); alarm(timelimit); printf("start!! n > "); scanf("%s", buf); if (strcmp(buf, alpha) == 0) printf("well done.. you succeed! n"); else printf("sorry.. you fail! n"); 30

6. alarm SIGALRM 과 pause() 를이용하여간단하게구현해본 sleep() 함수 #include <unistd.h> static void sig_alrm(int signo) return; Int sleep(int nsecs) If (signal(sigalrm, sig_al rm) == SIG_ERR) return nsecs; alarm(nsecs); pause(); return (alarm(0)); 31

7. pause 시그널이전달될때까지대기한다 #include <unistd.h> int pause(void); 반환값 항상 -1 을반환한다. pause() 를호출한프로세스는임의의시그널이전달될때까지대기 상태가된다. 아무시그널이나상관없다. 수신된시그널이프로세스를종료시키는것이라면프로세스는 pause 상태에서벗어나자마자종료된다. 무시하도록설정된시그널에대해서는반응하지않는다. 시그널핸들러가등록된시그널이라면시그널핸들러를실행하고나서 pause 상태를벗어난다. 32

예제 10-8 ex10-08.c #include <unistd.h> void f(int signo) main() signal(sigint, f); printf("pause return %d n", pause()); $ ex10-08 pause return -1 Ctrl+C 를입력한다. $ 33

예제 10-9 ex10-09.c #include <unistd.h> void handler(int signum); main() struct sigaction act; $ ex10-09 SIGINT cought pause return -1 $ sigfillset(&(act.sa_mask)); act.sa_handler = handler; sigaction(sigint, &act, NULL); printf("pause return %d n", pause()); void handler(int signum) printf(" nsigint cought n"); Ctrl+C 를입력한다. 34