[minishell] 3. 시그널(Signal) 처리하기
시그널을 받은 프로세스는 다음 3가지 반응 중 하나의 액션을 취한다. 1. 프로세스 종료 / 2. 시그널 무시 / 3. 사용자가 지정한 함수(핸들러) 호출
1. signal 이란?
특정 이벤트가 발생했을 때 프로세스에게 전달하는 신호. 즉, 프로세스끼리 서로 통신하기 위한 수단이다.
특정 이벤트: 연산 오류, 사용자의 프로그램 종료 요청, 자식 프로세스의 종료 등
인터럽트(interrupt)라고 부르기도 한다.
예) 리눅스에서 ctrl+c, 윈도우에서 alt+f4 를 통해 프로그램을 종료
2. signal 종류
혹은 man 7 signal
명령어를 통해 운영체제 마다 매크로로 정의되어 있는 시그널 상수를 확인할 수 있다.
이곳에 정의되어 있는 숫자는 핸들러에서 signo
로 활용할 수 있다.
3. 시그널 핸들러 (signal handler)
시그널을 받은 프로세스는 다음 3가지 반응 중 하나의 액션을 취한다.
프로세스 종료
시그널 무시
사용자가 지정한 함수(핸들러) 호출
minishell에서 왜 시그널 핸들러가 필요할까?
터미널을 종료시키는 인터럽트를 발생시켰을 때, 터미널이 종료되는게 아니라 우리의 minishell 프로그램만 종료되도록 액션을 변경해줘야 한다. 이런 핸들러 역할을 하는게 아래의 signal 함수이다.
int sig 는 시그널 번호,
sig_t func 는 해당 시그널을 처리할 핸들러.
4. 미니쉘에서 다루는 signal
출처 : What's the difference between ^C and ^D for UNIX/Mac OS X terminal?
ctrl+C (2, SIGINT)
키보드로부터 오는 인터럽트 시그널
실행을 중지하고 프로세스를 종료시킨다.
프롬프트를 다시 띄우게 된다.
ctrl+ (3, SIGQUIT)
키보드로부터 오는 인터럽트 시그널
실행을 중지
하고 프로세스를 종료시킨 뒤 코어 덤프(core dump).
코어 덤프(core dump)는 프로그램이 비정상적으로 종료되었을 때 작정 중이던 메모리 상태를 기록한 파일이다.
ctrl+D (15, SIGTERM)
Terminate의 약자로 프로세스를 정상 종료 시킴.
standard input 에 EOF(End Of File)를 등록한다. 쉘에 더 이상 명령을 입력하지 않겠다는 뜻.
즉, 프로세스 할 일 다 마치고 터미널 종료 시킴.
kill 명령의 기본 시그널
5. 구현
5.1. 키보드 인터럽트가 발생했을 때 터미널에 입력되는 ^C 문자를 지우는 방법
참고 : What's the use of \b in C?
The output of the/b
escape sequence depends on compiler to compiler.
Various possible outputs are:Non-destructive backspace : Here, a “\b” just makes the cursor shift backwards , without erasing any data and replacing the current character encountered with the new entered one.
The conventional backspace : Here, a “\b” means the normal backspace we use through our keyboards..
Example:
situation 1 would be
sacaln
situation 2 would be
sacal.
5.2. 부모 시그널과 자식 시그널을 따로 처리해줘야하는 이유
cat -e | 같은 것을 터미널에 입력한 뒤 자식프로세스가 대기 상태일 때 키보드 인터럽트가 발생되면 터미널에 출력되는 메세지가 부모 프로세스 일때랑 다르다.
^C
가 쉘에 출력되고 안되고의 차이가 있음자식프로세스 없을 때의 시그널은 pid==-1일 때로 분기해서 설정하기
Last updated