---
description: >-
  시그널을 받은 프로세스는 다음 3가지 반응 중 하나의 액션을 취한다. 1. 프로세스 종료 / 2. 시그널 무시 / 3. 사용자가 지정한
  함수(핸들러) 호출
---

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

## 1. **signal** 이란?

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

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

## 2. signal 종류

```c
kill -l
```

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

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/37580034-105322160-d00f6e80-5c0b-11eb-8a46-1c892637a241.png)

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

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

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

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

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

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

```c
#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?](https://superuser.com/questions/169051/whats-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?](https://www.quora.com/Whats-the-use-of-b-in-C)

The output of the`/b`escape 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:

```c
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일 때로 분기해서 설정하기
