[minishell] 3. 시그널(Signal) 처리하기

이대현·2021년 2월 12일
1

42SEOUL

목록 보기
19/24

1. signal 이란?

특정 이벤트가 발생했을 때 프로세스에게 전달하는 신호. 즉, 프로세스끼리 서로 통신하기 위한 수단이다.

  • 특정 이벤트: 연산 오류, 사용자의 프로그램 종료 요청, 자식 프로세스의 종료 등
  • 인터럽트(interrupt)라고 부르기도 한다.
  • 예) 리눅스에서 ctrl+c, 윈도우에서 alt+f4 를 통해 프로그램을 종료

2. signal 종류

kill -l

혹은 man 7 signal 명령어를 통해 운영체제 마다 매크로로 정의되어 있는 시그널 상수를 확인할 수 있다.

https://user-images.githubusercontent.com/37580034/105322160-d00f6e80-5c0b-11eb-8a46-1c892637a241.png

이곳에 정의되어 있는 숫자는 핸들러에서 signo 로 활용할 수 있다.

3. 시그널 핸들러 (signal handler)

시그널을 받은 프로세스는 다음 3가지 반응 중 하나의 액션을 취한다.

  1. 프로세스 종료
  2. 시그널 무시
  3. 사용자가 지정한 함수(핸들러) 호출

minishell에서 왜 시그널 핸들러가 필요할까?

터미널을 종료시키는 인터럽트를 발생시켰을 때, 터미널이 종료되는게 아니라 우리의 minishell 프로그램만 종료되도록 액션을 변경해줘야 한다. 이런 핸들러 역할을 하는게 아래의 signal 함수이다.

#include <signal.h>

**sig_t signal(int sig, sig_t func);**
  • 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/bescape sequence depends on compiler to compiler.

  1. 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.

  2. The conventional backspace : Here, a “\b” means the normal backspace we use through our keyboards..

    Example:

char name1[]=”sachin”; 
char name2[]=”al”; 

printf(%s\b\b\b%s”, name1,name2); 

situation 1 would be

sacaln

situation 2 would be

sacal.

5.2. 부모 시그널과 자식 시그널을 따로 처리해줘야하는 이유

cat -e | 같은 것을 터미널에 입력한 뒤 자식프로세스가 대기 상태일 때 키보드 인터럽트가 발생되면 터미널에 출력되는 메세지가 부모 프로세스 일때랑 다르다.

  • ^C가 쉘에 출력되고 안되고의 차이가 있음

  • 자식프로세스 없을 때의 시그널은 pid==-1일 때로 분기해서 설정하기

profile
삽질의 기록들 👨‍💻

0개의 댓글