Search
๐Ÿš

minishell

Created
2021/08/24
tag
42์„œ์šธ
42Seoul
minishell
Write a Shell in C
Redirection
Pipe
Built-In Commands
Various Operators

Subjects

โ€ข
โ€ข

1. External Functions

minishell์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค์€ ์ด์ „ ๊ณผ์ œ๋“ค๊ณผ ๋น„๊ตํ•˜์—ฌ ๊ต‰์žฅํžˆ ๋ฐฉ๋Œ€ํ•œ ํŽธ์ธ๋ฐ, ๊ธฐ์กด์— ์†Œ๊ฐœ๊ฐ€ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค์— ๋Œ€ํ•ด์„  ์•„๋ž˜ Toggle์„ ํŽผ์ณ์„œ ํ™•์ธํ•ด๋ณด์ž.
get_next_line์—์„œ ์†Œ๊ฐœ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค
ft_printf์—์„œ ์†Œ๊ฐœ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค
miniRT์—์„œ ์†Œ๊ฐœ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค
pipex์—์„œ ์†Œ๊ฐœ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค
Philosophers์—์„œ ์†Œ๊ฐœ ๋˜์—ˆ๋˜ ํ•จ์ˆ˜๋“ค
์ด์™ธ์˜ ํ•จ์ˆ˜๋“ค
์œ„์—์„œ ์ œ์‹œ๋œ ํ•จ์ˆ˜๋“ค ์™ธ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋“ค์ด ํ—ˆ์šฉ๋˜๋Š”๋ฐ, ์ด๋“ค์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค.
<dirent.h> ์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
<term.h> ์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
<sys/termios.h> ์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
<sys/ioctl.h>, <sys/wait.h> ์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
<unistd.h>, <stdlib.h>, <signal.h>์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
<readline/readline.h>, <readline/history.h>์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค
์œ„ ํ•จ์ˆ˜๋“ค์„ <math.h> ํ˜น์€ <pthread.h> ๋ฐ <semaphore.h>์™€ ๊ฐ™์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณ„๋กœ ๋œฏ์–ด์„œ ๊ธ€์„ ์จ๋ณด๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ, ์ œ์‹œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๋ชจ๋‘ ํ›‘์–ด๋ณด๋‹ˆ ๊ทธ ์–‘์ด ์ •๋ง ๋งŽ์•˜๋‹ค. ๋”ฐ๋ผ์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด์˜ ๋‚˜๋จธ์ง€ ํ•จ์ˆ˜๋“ค์€ ์ถ”ํ›„์— ํ•„์š”ํ•  ๋•Œ ์ฐพ์•„๋ณด๊ธฐ๋กœ ํ•˜๊ณ , ๋‹น์žฅ์€ minishell๊ณผ ๊ด€๋ จ๋œ ํ•จ์ˆ˜๋“ค๋งŒ์ด๋ผ๋„ ์ •ํ™•ํžˆ ์ˆ™์ง€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํƒ€ํ˜‘ํ–ˆ๋‹ค.

2. on <dirent.h>

1) opendir

1. ์˜์กด์„ฑ

#include <dirent.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

DIR *opendir(const char *name);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

name์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์„ ์ฐธ์กฐํ•˜๋Š” DIR * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ name์— ํ•ด๋‹นํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†๊ฑฐ๋‚˜ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด, DIR * ํƒ€์ž…์˜ ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜ ๊ฐ’์€ NULL์ด ๋œ๋‹ค.
DIR์ด๋ผ๋Š” ํƒ€์ž…์€ <dirent.h> ๋‚ด์— ์ •์˜๋œ ๊ตฌ์กฐ์ฒด์ด๋‹ค. ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์— ์œ ์ง€ํ•˜๊ณ  ์žˆ๋Š” ๋ณ€์ˆ˜๋Š” ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์œผ๋ฉฐ, ์ „๋ฐ˜์ ์œผ๋กœ ์—ด๋ฆฐ ์ƒํƒœ์˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ธฐ์ˆ ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜๋“ค์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, DIR ๊ตฌ์กฐ์ฒด๋Š” ์ฃผ๋กœ ๋””๋ ‰ํ† ๋ฆฌ ์กฐ์ž‘์„ ์œ„ํ•œ ์ˆ˜๋‹จ์œผ๋กœ ์ด์šฉ๋œ๋‹ค.
DIR์ด๋ผ๋Š” ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ ํƒ€์ž…์ธ DIR *์„ ํ”ํžˆ ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด๋Š” ์ •๊ทœ ํŒŒ์ผ ์กฐ์ž‘์„ ์œ„ํ•œ ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์ธ FILE *์™€ ๋น„์Šทํ•œ ํ˜•์‹์œผ๋กœ ์ด์šฉ๋œ๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ ๋ฐ ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์—์„œ ๋งํ•˜๋Š” ์ŠคํŠธ๋ฆผ์ด๋ž€ ํŠน์ • ์ž‘์—…์„ ์šฉ์ดํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ƒํ™”๋œ ์ค‘๊ฐ„ ๋งค๊ฐœ์ฒด์˜ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„  ์ŠคํŠธ๋ฆผ์˜ ์œ ๋ž˜์— ๋Œ€ํ•ด ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
Unix์—์„œ๋Š” ์žฅ์น˜๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์žฅ์น˜ ์ž์ฒด๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ํŒŒ์ผ๋กœ์จ ์ด์šฉํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ์žฅ์น˜ ์ž์ฒด๋ฅผ ํŒŒ์ผ๋กœ ํ‘œํ˜„ํ•œ๋‹ค๋Š” ๋ง์€ ํŒŒ์ผ์˜ ์กฐ์ž‘์„ ํ†ตํ•ด ์žฅ์น˜๊ฐ€ ๊ฐ–๋Š” ์ž…์ถœ๋ ฅ์— ๋Œ€ํ•ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ, ๊ธฐ์กด์˜ ๋น„ํšจ์œจ์ ์ธ ๋งŽ์€ ์ˆ˜์ž‘์—…์„ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด ๋•Œ ํ•ด๋‹น ํŒŒ์ผ์ด ์ฃผ๊ณ  ๋ฐ›๋Š” ์ผ๋ จ์˜ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์ŠคํŠธ๋ฆผ์ด๋ผ๊ณ  ์ •์˜ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
๊ณผ๊ฑฐ์˜ ์ปดํ“จํ„ฐ๋Š” ์ฒœ๊ณต ์นด๋“œ, ๋””์Šคํฌ, ์ž”์ž ํ…Œ์ดํ”„ ๋“ฑ์˜ ์ˆ˜์ž‘์—…์„ ํ†ตํ•ด ์ž…์ถœ๋ ฅ์— ๋Œ€ํ•ด ์„ค์ •์ด ์ด๋ค„์กŒ๋Š”๋ฐ, ์žฅ์น˜๋ฅผ ํŒŒ์ผ๋กœ ์ถ”์ƒํ™” ํ•ด๋ƒ„์œผ๋กœ์จ ์ด๋ฅผ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์—ฐ๊ฒฐ๋œ ์žฅ์น˜๋“ค์€ /dev ๋””๋ ‰ํ† ๋ฆฌ์— ๋งˆ์šดํŠธ๋˜์–ด ํŒŒ์ผ ํ˜•ํƒœ๋กœ ์œ ์ง€๋˜๊ณ  ์žˆ๋‹ค.
์œ„์™€ ๊ฐ™์€ ์œ ๋ž˜๋ฅผ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์€ ๋””๋ ‰ํ† ๋ฆฌ์™€ ๊ด€๋ จ๋œ ์ž‘์—…์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„์ด๊ณ  ์ด๋ฅผ ์ถ”์ƒํ™”ํ•œ ๊ตฌ์กฐ์ฒด๊ฐ€ DIR์ด๋ผ๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

2) closedir

1. ์˜์กด์„ฑ

#include <dirent.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int closedir(DIR *dirp);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

opendir ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์—ด์–ด๋‘” ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. closedir์˜ ํ˜ธ์ถœ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

3) readdir

1. ์˜์กด์„ฑ

#include <dirent.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

struct dirent *readdir(DIR *dirp);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์—ด์–ด๋‘” ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์„ ์ธ์ž๋กœ ๋ฐ›์•„ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ ์—”ํŠธ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜๋Š” dirent ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” NULL์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋””๋ ‰ํ† ๋ฆฌ ์ŠคํŠธ๋ฆผ์˜ ๋์— ๋„๋‹ฌํ•˜์—ฌ ๋” ์ด์ƒ์˜ ์—”ํŠธ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ NULL์ด ๋ฐ˜ํ™˜๋œ๋‹ค.
์ŠคํŠธ๋ฆผ์˜ ๋์— ๋„๋‹ฌํ•œ ๊ฒฝ์šฐ์™€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๊ฒฝ์šฐ ๋ชจ๋‘ NULL์ด ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ, ๋‘ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด์„œ ๊ตฌ๋ถ„์ง€์„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๊ตฌ๋ถ„์€ errno๋ฅผ ํ†ตํ•ด ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ŠคํŠธ๋ฆผ์˜ ๋์— ๋„๋‹ฌํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ์กด์— ์„ค์ •๋˜์–ด ์žˆ๋Š” errno์— ๋ณ€๋™์ด ์—†๊ณ , ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ ์ƒํ™ฉ์— ๋งž๋Š” errno๋กœ ๋ณ€๋™์ด ์ƒ๊ธด๋‹ค. ๋”ฐ๋ผ์„œ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„  NULL ๊ฒ€์‚ฌ ์ดํ›„ errno ๊ฐ’์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ด ์š”๊ตฌ๋œ๋‹ค.
๋ฐ˜ํ™˜๋ฐ›์€ ์—”ํŠธ๋ฆฌ๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด dirent ๊ตฌ์กฐ์ฒด์˜ ํ˜•ํƒœ๋ฅผ ํŒŒ์•…ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. Mac OS X์—์„œ ์‚ฌ์šฉ๋˜๋Š” dirent๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ __DARWIN_STRUCT_DIRENTY๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์—”ํŠธ๋ฆฌ์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ •๋ณด๋“ค์ด ์œ ์ง€๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
Mac OS X ๋‚ด์—์„œ๋Š” ์—”ํŠธ๋ฆฌ์˜ ํƒ€์ž…์„ dirent ๊ตฌ์กฐ์ฒด ์ž์ฒด์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ์ด์šฉํ•˜๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” ์ด์šฉํ•  ์ˆ˜ ์—†์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” <stat.h>์—์„œ stat ๊ตฌ์กฐ์ฒด์™€ stat ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ํŒŒ์ผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜จ ํ›„, ํŒŒ์ผ์˜ ํƒ€์ž…์„ ํ™•์ธํ•˜๋Š” ๋งคํฌ๋กœ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค. minishell์—์„œ๋Š” ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์ด ํ—ˆ์šฉ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๋ฟ๋”๋Ÿฌ ๋‹จ์ˆœํžˆ dirent ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, <stat.h>์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค๋งŒ ์•Œ์•„๋‘๋ฉด ๋œ๋‹ค.
readdir ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์–ป์€ dirent ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ, ํฌ์ธํ„ฐ๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์˜ ๊ณต๊ฐ„์€ ์ •์ ์œผ๋กœ ํ• ๋‹น๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„๋กœ free ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

4) ์˜ˆ์‹œ

<dirent.h>๋ฅผ ์ด์šฉํ•œ ์˜ˆ์‹œ์—์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŠน์ • ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ฝ๊ณ , ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด๋ถ€์˜ ์—”ํŠธ๋ฆฌ๋“ค์„ ํ™•์ธํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.
#include <dirent.h> #include <errno.h> #include <stdbool.h> #include <stdio.h> void classify(struct dirent *ent) { printf("%s\t", ent->d_name); if (ent->d_type == DT_BLK) printf("Block Device\n"); else if (ent->d_type == DT_CHR) printf("Character Device\n"); else if (ent->d_type == DT_DIR) printf("Directory\n"); else if (ent->d_type == DT_LNK) printf("Symbolic Link\n"); else if (ent->d_type == DT_REG) printf("Regular File\n"); else if (ent->d_type == DT_SOCK) printf("Unix Domain Socket\n"); else printf("Unknown Type File\n"); } int main(void) { int temp; DIR *dirp; struct dirent *file; dirp = opendir("test_dir"); if (!dirp) { printf("error\n"); return (1); } while (true) { temp = errno; file = readdir(dirp); if (!file && temp != errno) { printf("error\n"); break ; } if (!file) break ; classify(file); } closedir(dirp); return (0); }
C

3. on <term.h>

<term.h> ๋‚ด์— ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค์„ ํ™•์ธํ•˜๊ธฐ ์ „์— <term.h>์—์„œ ์š”๊ตฌ๋˜๋Š” ๊ฐœ๋…๋“ค์„ ๋จผ์ € ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. Mac OS X์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” <term.h>๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ„ฐ๋ฏธ๋„ ์ƒ์˜ ๊ธฐ๋Šฅ๋“ค์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค. ํ„ฐ๋ฏธ๋„ ์ƒ์—์„œ ์ปค์„œ๋ฅผ ์ œ์–ดํ•œ๋‹ค๊ฑฐ๋‚˜, ํ„ฐ๋ฏธ๋„ ์ƒ์˜ ํ™”๋ฉด ์ผ๋ถ€๋ฅผ ์ง€์šด๋‹ค๊ฑฐ๋‚˜, ํ˜„์žฌ ๋ณด์ด๋Š” ์ƒ‰์ƒ์— ๋ณ€ํ™”๋ฅผ ์ฃผ๋Š” ๋“ฑ์˜ ์ž‘์—…์„ <term.h>๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์„ ๋ฟ ์•„๋‹ˆ๋ผ, ํ„ฐ๋ฏธ๋„ ์ƒ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์‹คํ–‰ํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ์ถœ๋ ฅํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ž๋“ค์„ ์ด์šฉํ•˜์—ฌ ํ„ฐ๋ฏธ๋„๊ณผ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋Š”๋ฐ ์ด ๋•Œ๋„ <term.h>๊ฐ€ ์ด์šฉ๋œ๋‹ค.

1) NCURSES

๊ณผ์ œ์—์„œ ํ—ˆ์šฉ๋œ ํ•จ์ˆ˜๋“ค์„ <term.h> ๋‚ด์—์„œ ์ฐพ์•„๋ณด๋ฉด, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด NCURSES ๋งคํฌ๋กœ ์ •์˜๋กœ ๋ฌถ์—ฌ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. NCURSES๋Š” New Curses์˜ ์•ฝ์ž์ด๊ณ , Terminal Emulator ์ƒ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” GUI ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ํˆดํ‚ท์œผ๋กœ ๋‹ค์–‘ํ•œ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์—ฌ๋Ÿฌ ์ฐฝ๋“ค์„ ๋„์šฐ๊ฑฐ๋‚˜, ํ‚ค๋ณด๋“œ ํ˜น์€ ์ปค์„œ ์ œ์–ด๋ฅผ ํ•œ๋‹ค๋“ ๊ฐ€ ์ƒ‰์ƒ์„ ๋„ฃ๋Š” ์ž‘์—… ๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ฃผ๋กœ Unix ์ƒ์—์„œ ์ด์šฉ๋œ๋‹ค. ์œ„ ๊ทธ๋ฆผ์— ๋”ฐ๋ผ <term.h>๋Š” NCURSES์˜ ํ„ฐ๋ฏธ๋„ ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
NCURSES๋Š” Cursor Optimization์„ ์œ„ํ•œ ๊ธฐ์กด์˜ CURSES๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์œ ๋ž˜๋˜์—ˆ๊ณ , ์ด๋Š” Unix ๊ณ„์—ด ์šด์˜์ฒด์ œ๋ฅผ ์œ„ํ•œ ์ œ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. 1990๋…„ ๋Œ€์— ๊ฐœ๋ฐœ์ด ์ค‘๋‹จ ๋˜์—ˆ๋‹ค๊ฐ€, GNU์—์„œ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๋ฉด์„œ NCURSES๋กœ ๋ช…๋ช…๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ Unix ๊ณ„์—ด ์‹œ์Šคํ…œ ์ค‘ ์ตœ์‹  ๋ฒ„์ „์„ ์ด์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” GCC์˜ ์„ค์น˜ ์‹œ ์ž๋™์œผ๋กœ ํ•จ๊ป˜ ์„ค์น˜๋œ๋‹ค.
NCURSES์˜ ํ„ฐ๋ฏธ๋„ ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋™์ž‘ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” <term.h> ์™ธ์—๋„ <termcap.h>๊ฐ€ ์žˆ๋Š”๋ฐ, ํ„ฐ๋ฏธ๋„ ์ œ์–ด๋ฅผ ์œ„ํ•œ ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์—ญํ• ์€ ์„œ๋กœ ๋™์ผํ•˜๋‹ค. ๋‹ค๋งŒ ๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—ด์–ด ํ™•์ธํ•ด๋ณด๋ฉด, <term.h>๊ฐ€ NCURSES ์™ธ์˜ ๊ธฐ๋Šฅ๋“ค๋„ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„ ๊ทธ๋ฆผ์€ <termcap.h>์— ์žˆ๋Š” NCURSES ๋งคํฌ๋กœ ์ •์˜๋กœ ๋ฌถ์ธ ๋ถ€๋ถ„์ธ๋ฐ, <term.h>์˜ ๊ทธ๋ฆผ๊ณผ ๋น„๊ตํ•ด๋ณด๋ฉด NCURSES์˜ ์ค‘๋ณต ํฌํ•จ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋งคํฌ๋กœ ์ •์˜๋งŒ ๋‹ค๋ฅผ ๋ฟ NCURSES๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜จ ๊ธฐ๋Šฅ๋“ค์€ ๋ชจ๋‘ ๋™์ผํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
<term.h> ํ˜น์€ <termcap.h>์—์„œ NCURSES๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜จ ํ•จ์ˆ˜๋“ค์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ํ•จ์ˆ˜์˜ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ณผ์ •๋„ ํ•„์š”ํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด NCURSES๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜จ ํ•จ์ˆ˜๋“ค ์ค‘ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผ ํ•ด๋ณด๋ฉด, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๊ณ  ์ปดํŒŒ์ผ์— ์‹คํŒจํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
์ปดํŒŒ์ผ์ด ๋˜์ง€ ์•Š์€ ์ด์œ ๋Š” NCURSES_EXPORT๋ฅผ ํ†ตํ•ด ๋‚ด๋ณด๋‚ด์ง„ ํ•จ์ˆ˜๋“ค์˜ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ์•Š์•˜๊ธฐ ๋–„๋ฌธ์ด๋ฏ€๋กœ, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด -l์ด๋ผ๋Š” ์ปดํŒŒ์ผ ์˜ต์…˜์œผ๋กœ NCURSES๋ฅผ ๋ช…์‹œํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ปดํŒŒ์ผ์ด ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

2) TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜

<term.h>๊ฐ€ ํ„ฐ๋ฏธ๋„ ์ œ์–ด๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ ๋งŒํผ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค. ๋”ฐ๋ผ์„œ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€, TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์™œ ํ•„์š”ํ•œ์ง€, TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’๋“ค์— ๋Œ€ํ•ด ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ž€?

TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” ๋กœ๊ทธ์ธ ํ„ฐ๋ฏธ๋„์˜ ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜์ด๋‹ค. ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํ„ฐ๋ฏธ๋„์˜ ํƒ€์ž…์ด๋ž€ ์–ด๋–ค ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์ด์šฉํ•˜๋Š”์ง€๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค. TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ์—ญํ• ์€ ์ง€๊ทนํžˆ ๋ช…ํ™•ํ•œ๋ฐ, ์ด๋Š” ํ„ฐ๋ฏธ๋„ ์ƒ์—์„œ ์‹คํ–‰๋  ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—๊ฒŒ ํ„ฐ๋ฏธ๋„๊ณผ ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•ด์•ผํ•˜๋Š”์ง€๋ฅผ ์•Œ๋ฆฌ๋Š”๋ฐ ์žˆ๋‹ค. ์ฆ‰, TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜ํ•ด ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ณ , ์ด ๋•Œ์˜ ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ„ฐ๋ฏธ๋„๊ณผ์˜ ์ƒํ˜ธ์ž‘์šฉ์€ ์ž…์ถœ๋ ฅ ์ž‘์—…๊นŒ์ง€๋„ ํฌํ•จ๋œ๋‹ค.

TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ํ•„์š”์„ฑ?

์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ„ฐ๋ฏธ๋„ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์€ Escape Sequence๋ฅผ ํ†ตํ•ด์„œ ์ด๋ค„์ง€๋Š”๋ฐ, ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ ํ‚ค๋ณด๋“œ, ์ปค์„œ, ํ„ฐ๋ฏธ๋„ ํ™”๋ฉด์— ๋Œ€ํ•ด ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, Escape Sequence์˜ ํ‘œ์ค€์ด ๋ช…ํ™•ํžˆ ์ •ํ•ด์ง„ ๊ฒƒ์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณผ๊ฑฐ์˜ ๋ฌผ๋ฆฌ์ ์ธ ํ„ฐ๋ฏธ๋„๋“ค์€ ํ„ฐ๋ฏธ๋„์˜ ํƒ€์ž…์— ๋”ฐ๋ผ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Escape Sequence์— ์ฐจ์ด๊ฐ€ ์žˆ์—ˆ๋‹ค.
์ด์™€ ๊ฐ™์€ Escape Sequence๋“ค์„ ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •ํ™•ํžˆ ์•Œ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ, ์˜๋ฏธ ์—†๋Š” ๋ฌธ์ž๋“ค์ด ์กฐํ•ฉ๋œ ๋ชจ๋“  Escape Sequence๋“ค์„ ์™ธ์›Œ์„œ ์ด์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ต‰์žฅํžˆ ์–ด๋ ค์šด ์ผ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์›ํ•˜๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ๋ฅผ ์šด์˜์ฒด์ œ์— ๋ณด๋‚ด๋ฉด, ์šด์˜์ฒด์ œ๋Š” ์ด์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ ์ ˆํ•œ Escape Sequence๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์šด์˜์ฒด์ œ ์ž…์žฅ์—์„œ๋Š” ์ด์™€ ๊ฐ™์€ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•˜๋ ค๋ฉด ํŠน์ • ํƒ€์ž…์˜ ํ„ฐ๋ฏธ๋„์ด ์ด์šฉํ•˜๋Š” Escape Sequence๋ฅผ ๋ชจ๋‘ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์šด์˜์ฒด์ œ๋Š” ์ด๋ฅผ ์ ์ ˆํžˆ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ถ€์— DB๋ฅผ ๊ฐ–๊ณ  ์žˆ๋„๋ก ์„ค๊ณ„์—ˆ๋‹ค. ์ด๋ฅผ Terminal Capability (TermCap)์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
์ตœ๊ทผ์˜ ๋งŽ์€ ์‹œ์Šคํ…œ์—์„œ๋Š” TermCap ๋Œ€์‹ ์— TermInfo๋ผ๋Š” DB๊ฐ€ ์ด์šฉ๋œ๋‹ค. TermCap๊ณผ TermInfo ๋“ฑ ํ„ฐ๋ฏธ๋„๊ณผ ๊ด€๋ จ๋œ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
[Linux] shmat - ๊ณต์œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์—ฐ์‚ฐ
์ด์žฅ์€ ํ™”์†Œ(pixel)๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜์ง€์•Š๋Š”, ๋ฌธ์ž๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๋Š” ํ™”๋ฉด ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์„ ๋‹ค๋ฃฌ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋ฌธ์ž(character)๋ฅผ ๋งํ•  ๋•Œ, ๋ฌธ์ž๋Š” ๋ฌธ์ž์ง‘ํ•ฉ(charset)์— ๋”ฐ๋ผ ๋ณ€ํ™”๋˜๋Š” ํ™”์†Œ(pixel)์˜ ์กฐํ•ฉ์„ ์˜๋ฏธํ•œ๋‹ค. ํ…์ŠคํŠธ(text)๊ฐ€ ํ™”์†Œ(pixel) ๊ทธ๋ž˜ํ”ฝ๋ณด๋‹ค ๋งค์šฐ ๋นจ๋ฆฌ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ(graphic card)๋Š” ์ด๋ฏธ ํ•œ๊ฐœ์ด์ƒ์˜ ๋ฌธ์ž์ง‘ํ•ฉ(charset)์„ ์ œ๊ณตํ•˜๊ณ , ๊ธฐ๋ณธ์ ์œผ๋กœ ํ…์ŠคํŠธ(charset) ๋ชจ๋“œ์—์„œ ๋™์ž‘ํ•œ๋‹ค. ๊ฐ„๋‹จ(๋ฌด๋”˜)ํ•˜๊ณ  ์ง€๊ฒจ์šด ํ…์ŠคํŠธ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ ์ด์ƒ์œผ๋กœ ๋‹จ๋ง๊ธฐ๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.
์ •๋ฆฌํ•ด๋ณด๋ฉด, ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์›ํ•˜๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด์„œ ์šด์˜์ฒด์ œ๊ฐ€ TermCap์—์„œ ์ ์ ˆํ•œ Escape Sequence๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์œผ๋ ค๋ฉด ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•˜๋ ค๋Š” ํ„ฐ๋ฏธ๋„์˜ ํƒ€์ž…์„ ๋จผ์ € ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ด๊ณ , ์ด ๋•Œ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์ด์šฉ๋œ๋‹ค.
์ตœ๊ทผ์—๋Š” Escape Sequence์— ๋Œ€ํ•œ ํ‘œ์ค€์ด ์ •๋ฆฌ๋œ ์ƒํƒœ์ด๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ํ„ฐ๋ฏธ๋„๋“ค์ด ์ด๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์— ๋”ฐ๋ผ ์ œ๊ณต๋˜๋Š” ๊ธฐ๋Šฅ์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ DB ์ž์ฒด๋Š” ํ•„์š”ํ•˜์ง€๋งŒ, TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ฐ’์— ๋”ฐ๋ผ ๊ธฐ๋Šฅ์ ์œผ๋กœ ์—„์ฒญ ํฐ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ํ‘œ์ค€์œผ๋กœ ์ •์˜๋œ Escape Sequence๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’?

TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ ๋Œ€์ฒด์ ์œผ๋กœ ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์™€ ๊ทธ ์ด๋ฆ„์ด ๋™์ผํ•œ๋ฐ, ์ด ๋•Œ๋ฌธ์— TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค๊ณ  ์ดํ•ดํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์™€ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ด์šฉ๋˜๋Š” ๊ฐ’์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gnome-terminal์„ ์ด์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๊ผญ gnome-terminal๋กœ๋งŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. gnome-terminal์„ ์ด์šฉํ•˜๋”๋ผ๋„ xterm ํ˜น์€ xterm-256color๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์— ๋”ฐ๋ผ ์ƒํ˜ธ์ž‘์šฉ ๋ฐฉ์‹๋งŒ ๋ฐ”๋€๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ด์šฉํ•˜๋Š” ๊ฐ’์— ์ •๋‹ต์ด ์žˆ์„๊นŒ?
์‹œ์Šคํ…œ ๋ณ„๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์˜ ๋ชฉ๋ก์€ ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ๊ฐ’์œผ๋กœ ์–ด๋–ค ๊ฒƒ์„ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ ๋ช…ํ™•ํžˆ ์ •ํ•ด์ง„ ๋‹ต์ด ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, xterm ํ˜น์€ xterm-256color๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ GUI๋ฅผ ์ง€์›ํ•˜๋Š” ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋Š” xterm์ด๋ผ๋Š” ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์„ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด์— ๋Œ€ํ•ด์„  ssh์™€ ๊ฐ™์€ ์›๊ฒฉ ํ†ต์‹ ์˜ ์ƒํ™ฉ์„ ํ†ตํ•ด ์กฐ๊ธˆ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋–ค ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ํ™˜๊ฒฝ์„ AA๋ผ๊ณ  ํ•˜๊ณ , ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํ™˜๊ฒฝ์„ BB๋ผ๊ณ  ํ•ด๋ณด์ž. ์ฆ‰, BB ํ™˜๊ฒฝ์—์„œ ssh๋ฅผ ํ†ตํ•ด AA ํ™˜๊ฒฝ์—์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ„ฐ๋ฏธ๋„๊ณผ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๊ณ  ์žˆ๋Š” ํ™˜๊ฒฝ์€ AA์ด๋ฏ€๋กœ, BB ํ™˜๊ฒฝ์—์„œ ์ œ์–ด๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ์ ์ ˆํ•œ TermCap์„ ์ด์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด AA ํ™˜๊ฒฝ์˜ ์—”ํŠธ๋ฆฌ ์—ญ์‹œ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์›๊ฒฉ ํ†ต์‹  ์ƒ์—์„œ๋Š” ๋‘ ํ„ฐ๋ฏธ๋„์˜ ํƒ€์ž…์„ ๋™์ผํ•˜๊ฒŒ ๋งž์ถœ ํ•„์š”๊ฐ€ ์žˆ๋Š”๋ฐ, xterm์ด ๋„๋ฆฌ ์ด์šฉ๋˜์–ด ์™”๊ณ  ํ˜ธํ™˜์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— xterm์œผ๋กœ ๊ณ ์ •ํ•ด๋‘๊ณ  ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.
๋ฌผ๋ก  ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์™€ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๊ฐ™์œผ๋ฉด ํ„ฐ๋ฏธ๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋Š” ์ž์‹ ์˜ ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋ฉด ๋˜๋ฏ€๋กœ, ํ„ฐ๋ฏธ๋„ ์ž…์žฅ์—์„œ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ธก๋ฉด์—์„œ ๋“์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž…์žฅ์—์„œ๋Š” ์ฟผ๋ฆฌ๋งŒ ๋ณด๋‚ด๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด์— ๋”ฐ๋ฅธ ์˜ํ–ฅ์ด ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—๊ฒŒ ์ฃผ๋Š” ์ฐจ์ด๋Š” ๋ฏธ๋ฏธํ•˜๋‹ค. ๋”ฐ๋ผ์„œ xterm ํ˜น์€ xterm-256color์™€ ๊ฐ™์ด ๋” ๋„๋ฆฌ ์ด์šฉ๋˜๋Š” ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.
xterm ํ˜น์€ xterm-256color ๊ฐ„์—๋„ ์—„์ฒญ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. xterm-256color๋Š” ์ด๋ฆ„์ฒ˜๋Ÿผ 256๊ฐœ์˜ Text Color๋ฅผ ์ง€์›ํ•˜๋Š”๋ฐ, ๊ทธ๋ ‡๋‹ค๊ณ  xterm์ด ์ƒ‰์ƒ ์ง€์›์„ ์•ˆํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ์ƒ‰์ƒ ํ‘œํ˜„์˜ ์ˆ˜์—์„œ์˜ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ์„ ๋ฟ, xterm๋„ Text Color๋ฅผ ์ง€์›ํ•œ๋‹ค.

3) ํ„ฐ๋ฏธ๋„ ์ œ์–ด ๋ฐฉ๋ฒ•

ํ„ฐ๋ฏธ๋„ ์ œ์–ด๋ฅผ ์œ„ํ•ด์„  ์œ„์—์„œ ์–ธ๊ธ‰๋˜์—ˆ๋˜ TermCap ํ˜น์€ TermInfo์˜ ์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๊ณ , ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์ „์— ์—”ํŠธ๋ฆฌ๋ฅผ ๋จผ์ € ๋“ฑ๋กํ•ด์ฃผ๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค. ์ด์™€ ๊ฐ™์€ ์—”ํŠธ๋ฆฌ ๋“ฑ๋ก ๋ฐ ์ฟผ๋ฆฌ ์ž‘์—…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ„ฐ๋ฏธ๋„ ์ž์ฒด์˜ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ€์žฅ ์ฒ˜์Œ์—๋Š” ํ„ฐ๋ฏธ๋„์—์„œ ์ƒํ˜ธ์ž‘์šฉํ•˜๋ ค๋Š” ๋Œ€์ƒ์˜ ์†์„ฑ ๊ฐ’์„ ๋จผ์ € ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
์ƒํ˜ธ์ž‘์šฉ ๋Œ€์ƒ์˜ ์†์„ฑ ๊ฐ’ ์„ค์ •์€ termios๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. tcflag_t, cc_t, speed_t์™€ ๊ฐ™์€ ํƒ€์ž…์€ unsigned long, unsigned char ๋“ฑ์œผ๋กœ ์ •์˜๋œ ํƒ€์ž…์ผ ๋ฟ์ด๊ณ , termios ๋‚ด์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์˜ ์—ญํ• ์€ ์œ„ ๊ทธ๋ฆผ์— ๋‚˜ํƒ€๋‚œ ์ฃผ์„์œผ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ฐ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์€ ํ„ฐ๋ฏธ๋„ ์†์„ฑ ๊ฐ’ ์„ค์ •์„ ์œ„ํ•œ ํ”Œ๋ž˜๊ทธ๋กœ์จ ์ด์šฉ๋˜๋Š”๋ฐ, ๊ฐ ํ”Œ๋ž˜๊ทธ์— ํ• ๋‹น๋˜๋Š” ๊ฐ’์„ ๋‹ค๋ฅด๊ฒŒ ํ•ด๋ณด๋ฉด ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ ์ž‘์—…์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์ดํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๊ฐ ํ”Œ๋ž˜๊ทธ์— ํ• ๋‹น๋˜๋Š” ๊ฐ’์€ <sys/termios.h> ๋‚ด๋ถ€์— input flag, output flag ์ฒ˜๋Ÿผ ๊ทธ๋ฆผ์— ๋‚˜ํƒ€๋‚œ ์ฃผ์„์„ ๊ฒ€์ƒ‰ํ•ด๋ณด๋ฉด ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ๊ฐ’๋“ค์€ Bit ์—ฐ์‚ฐ์œผ๋กœ์จ ์ด์šฉ๋˜๋Š” ๊ฐ’์ž„์„ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ„ฐ๋ฏธ๋„์—์„œ ๋™์ž‘ํ•˜๋Š” ์‰˜์„ ๊ตฌํ˜„ํ•  ๋•Œ ๊ธฐ๋Œ€๋˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค๋ฉด termios ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ ˆํžˆ ์กฐ์ž‘ํ•˜๋ฉด ๋œ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ฐพ์•„์ง€์ง€ ์•Š๊ฑฐ๋‚˜ ์ดํ•ด๊ฐ€ ์•ˆ ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ์—์„œ ํ”Œ๋ž˜๊ทธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒํ•œ๋‹ค.
<term.h>๋ฅผ ํฌํ•จํ–ˆ๋‹ค๋ฉด, ๋ณ„๋„๋กœ <sys/termios.h>๋ฅผ ํฌํ•จ์‹œํ‚ฌ ํ•„์š”๋Š” ์—†๋‹ค. <term.h>๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด <termios.h>๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , <termios.h> ๋‚ด์—์„œ๋Š” <sys/termios.h>๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
termios ๊ตฌ์กฐ์ฒด๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ํ„ฐ๋ฏธ๋„ ์†์„ฑ ๊ฐ’์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด์„  ๊ธฐ์กด์˜ ํ„ฐ๋ฏธ๋„ ์†์„ฑ ๊ฐ’์„ termios * ํƒ€์ž…์œผ๋กœ ๊ฐ€์ ธ์˜จ ๋’ค, ๊ฐ€์ ธ์˜จ termios ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•œ ํ›„ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์ด์™€ ๊ฐ™์€ ์ž‘์—…๋“ค์„ ๊ฐ๊ฐ tcgetattr๊ณผ tcsetattr์ด๋ผ๋Š” ํ•จ์ˆ˜๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ„ฐ๋ฏธ๋„ ์†์„ฑ ๊ฐ’ ๊ฒฐ์ •์ด ๋๋‚œ ํ›„์—๋Š” ์ฒ˜์Œ์— ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ TermCap ํ˜น์€ TermInfo์ด ์ฟผ๋ฆฌ๋ฅผ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก, ์–ด๋–ค ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์„ ์ด์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ์—”ํŠธ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ฌ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ์ž‘์—…์„ tgetent์ด๋ผ๋Š” Routine ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
์—”ํŠธ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ฉด์„œ ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์„ ์ •ํ•˜๋ฉด, TermCap ํ˜น์€ TermInfo์˜ ์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํ•จ์ˆ˜๋“ค์„ Routine์ด๋ผ๊ณ  ํ•œ๋‹ค. TermCap์„ ์ด์šฉํ•˜๋Š”์ง€ TermInfo๋ฅผ ์ด์šฉํ•˜๋Š”์ง€์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•˜๋Š” Routine ํ•จ์ˆ˜๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š”๋ฐ, minishell์—์„œ๋Š” TermCap์˜ ํ•จ์ˆ˜๋“ค์ด ํ—ˆ์šฉ๋˜์–ด ์žˆ๋‹ค. ์ด์— ํ•ด๋‹น๋˜๋Š” ํ•จ์ˆ˜๋“ค์€ tgetstr, tputs, tgetflag, tgetnum, tgoto ๋“ฑ์˜ Routine์ด ์žˆ๋‹ค.
์ด์ „์— ์–ธ๊ธ‰ํ–ˆ๋˜ ๋Œ€๋กœ <term.h>์—๋Š” <termcap.h>์˜ ํ•จ์ˆ˜๋“ค์ด ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ <termcap.h>๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ํฌํ•จํ•  ํ•„์š”๋Š” ์—†๋‹ค. tgetent๋„ ์—”ํŠธ๋ฆฌ ์ด๋ฆ„์„ ์ฟผ๋ฆฌ๋กœ ์ด์šฉํ•˜๋Š” Routine์ด๋‹ค.
Routine ๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ๋Š” ๋ชจ๋‘ ๋‹ค๋ฅด๋ฉฐ, ์ฟผ๋ฆฌ๋Š” Routine ํ•จ์ˆ˜์˜ char * ํƒ€์ž…์˜ id๋ผ๋Š” ์ธ์ž๋กœ ์ด์šฉ๋œ๋‹ค. ๊ฐ Routine์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

4) tcgetattr

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tcgetattr(int fd, struct termios *t);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ƒํ˜ธ์ž‘์šฉ ํ•˜๋ ค๋Š” ๋Œ€์ƒ์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ๋Œ€์ƒ์˜ ์†์„ฑ ๊ฐ’์„ ๊ธฐ๋กํ•  termios ๊ตฌ์กฐ์ฒด๋ฅผ ํฌ์ธํ„ฐ ํƒ€์ž…์œผ๋กœ ํ• ๋‹นํ•œ๋‹ค. ์†์„ฑ ๊ฐ’์€ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ธฐ๋กํ•˜๋ฏ€๋กœ ๋ฐ˜ํ™˜ ๊ฐ’์€ tcgetattr ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ์น˜๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

5) tcsetattr

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tcsetattr(int fd, int action, const struct termios *t);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ƒํ˜ธ์ž‘์šฉ ํ•˜๋ ค๋Š” ๋Œ€์ƒ์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ๋Œ€์ƒ์˜ ์†์„ฑ ๊ฐ’์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด termios ๊ตฌ์กฐ์ฒด๋ฅผ ํฌ์ธํ„ฐ ํƒ€์ž…์œผ๋กœ ํ• ๋‹นํ•œ๋‹ค. termios ๊ตฌ์กฐ์ฒด์˜ ์†์„ฑ ๊ฐ’์„ ์–ด๋Š ํƒ€์ด๋ฐ์— ์ ์šฉํ• ์ง€๋Š” action์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
action์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ ์œ„ ๊ทธ๋ฆผ์—์„œ ๋ณด์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ 4์ข…๋ฅ˜์ด๋‹ค. TCSANOW๋Š” termios ๊ตฌ์กฐ์ฒด์˜ ๊ฐ’์œผ๋กœ ์ฆ‰์‹œ ๋ณ€๊ฒฝ์„ ์˜๋ฏธํ•œ๋‹ค. TSCADRAIN๊ณผ TCSAFLUSH๋Š” ๋Œ€์ƒ์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์— ๋Œ€ํ•ด ๋ชจ๋“  ์“ฐ๊ธฐ ์ž‘์—…์ด ์ด๋ค„์ง„ ํ›„์— ๋ณ€๊ฒฝ์„ ์˜๋ฏธํ•˜๋Š”๋ฐ, ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋ฉด TCSAFLUSH๋Š” ์ฒ˜๋ฆฌ๋˜๊ณ  ์žˆ๋Š” ์ž…๋ ฅ ์ž‘์—…์„ ํ๊ธฐํ•˜๊ณ  TCSADRAIN์€ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. TCSASOFT๊ฐ€ ์ด์šฉ๋  ๊ฒฝ์šฐ์—๋Š” termios ๊ตฌ์กฐ์ฒด ๋‚ด์˜ c_cflag, c_ispeed, c_ospeed์˜ ๊ฐ’๋“ค์ด ๋ฌด์‹œ๋œ๋‹ค.
ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ์น˜๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

6) tgetent

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tgetent(char *bp, const char *name);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

name์— ํ•ด๋‹นํ•˜๋Š” ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์˜ ์—”ํŠธ๋ฆฌ๋กœ ์„ค์ •ํ•˜์—ฌ, ํ•ด๋‹น ์—”ํŠธ๋ฆฌ์— ๋Œ€ํ•œ TermCap์˜ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” Routine์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ name์— ํ• ๋‹นํ•˜๋Š” ๊ฐ’์€ TERM ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ํ• ๋‹น๋œ ํ„ฐ๋ฏธ๋„ ํƒ€์ž…์„ ์ด์šฉํ•œ๋‹ค. ์ด ๋•Œ bp๋ผ๊ณ  ํ•˜๋Š” Buffer Pointer๋Š” ๋ฌด์‹œ๋˜๋Š” ์ธ์ž์ด๋ฏ€๋กœ NULL์„ ํ• ๋‹นํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.
Buffer Pointer๋ฅผ ๋ฌด์‹œํ•˜์ง€ ์•Š๊ณ  ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋ช‡ ์—†๋‹ค. ๋งŒ์ผ Buffer Pointer๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด๋ฅผ ๋‹ค๋ฅธ Routine ํ•จ์ˆ˜์—์„œ๋„ ์ด์šฉํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์—๋Š” Buffer Pointer๋Š” ๋ฌด์‹œ๋˜๊ณ , Routine๋“ค์ด ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” Buffer๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ํ• ๋‹นํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
Routine์˜ ์ž‘์—…์ด ์„ฑ๊ณต์ ์ด๋ผ๋ฉด 1์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , Routine ์ˆ˜ํ–‰ ์‹œ name์˜ ๊ฐ’์ด ๋„ ๋ฌธ์ž์—ด๊ณผ ๊ฐ™์ด ๋น„์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. name์˜ ์—”ํŠธ๋ฆฌ๋ฅผ DB์—์„œ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๋“ฑ์˜ Routine ์ˆ˜ํ–‰์˜ ์‹คํŒจ์˜ ๊ฒฝ์šฐ์—๋Š” -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

7) tgetflag

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tgetflag(char *id);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ฟผ๋ฆฌ๋กœ ์‚ฌ์šฉํ•  ์ด๋ฆ„์„ id๋ผ๋Š” ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ํ”Œ๋ž˜๊ทธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ๋ผ๋ฉด true (1)์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด false (0)์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

8) tgetnum

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tgetnum(char *id);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ฟผ๋ฆฌ๋กœ ์‚ฌ์šฉํ•  ์ด๋ฆ„์„ id๋ผ๋Š” ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ฟผ๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์„ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

9) tgetstr

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *tgetstr(char *id, char **area);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ฟผ๋กœ๋ฆฌ ์‚ฌ์šฉํ•  ์ด๋ฆ„์„ id๋ผ๋Š” ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ฟผ๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” Escape Sequence๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. area๋ผ๋Š” ์ธ์ž๋Š” tgetent์—์„œ ์‚ฌ์šฉ๋˜์—ˆ๋˜ Buffer Pointer๋ฅผ ์˜๋ฏธํ•˜๋Š”๋ฐ, ๋ฌด์‹œ๋˜๋Š” ์ธ์ž์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” NULL์„ ์ค€๋‹ค.
tgetent๋ผ๋Š” Routine์—์„œ Buffer Pointer๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ํ• ๋‹น๋˜์–ด ์ด์šฉ๋˜์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, area ์—ญ์‹œ ๋ฌด์‹œ๋œ๋‹ค๊ณ ๋Š” ํ•˜์ง€๋งŒ ์•„์˜ˆ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‚ด๋ถ€์ ์œผ๋กœ ํ• ๋‹น๋˜์–ด ์ด์šฉ๋˜๊ณ  ์žˆ๋‹ค. ํ‘œ๋ฉด์ ์œผ๋กœ ์ด์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ธก๋ฉด์—์„œ ๋ฌด์‹œ๋œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

10) tgoto

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *tgoto(const char *cap, int col, int row);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

col์€ ํ„ฐ๋ฏธ๋„์˜ ์„ธ๋กœ์—ด์˜ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•˜๊ณ , row๋Š” ํ„ฐ๋ฏธ๋„์˜ ๊ฐ€๋กœํ–‰์˜ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. cap์€ Capability๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ Cursor Motion์ธ cm์— ๋Œ€ํ•œ Escape Sequence๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋ฌผ๋ก  ๋‹ค๋ฅธ Escape Sequence๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ Cursor Motion์— ๋Œ€ํ•œ Escape Sequence๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๊ฐ€์žฅ ์•ˆ์ „ํ•˜๊ธฐ ๋•Œ๋ฌธ์— tgoto๋ผ๋Š” Routine์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค๋ฅธ Escape Sequence๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
tgoto๋ผ๋Š” Routine์€ col๊ณผ row๋ฅผ ๊ณ ๋ คํ•œ Cursor Motion์˜ Escape Sequence๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋ฌธ์ž์—ด์„ tputs์˜ ์ธ์ž๋กœ ์‚ฌ์šฉํ•˜๋ฉด, ํ„ฐ๋ฏธ๋„ ์ƒ์˜ ์ปค์„œ๊ฐ€ ์ด๋™๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Routine์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹คํŒจํ•  ์‹œ์—๋Š” NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

11) tputs

1. ์˜์กด์„ฑ

#include <term.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int tputs(const char *str, int affcnt, int (*putc)(int));
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

tputs๋Š” Escape Sequence์— ๋Œ€ํ•œ ํ„ฐ๋ฏธ๋„ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋Š” Routine์œผ๋กœ์จ, str์ด๋ผ๋Š” ์ธ์ž๊ฐ€ tgetstr ํ˜น์€ tgoto๋ฅผ ํ†ตํ•ด ์–ป์€ Escape Sequence์ด๋‹ค. affcnt๋Š” tputs๋กœ ์˜ํ–ฅ์„ ๋ผ์น  ์ค„ ์ˆ˜๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ ์ค„์— ์˜ํ–ฅ์„ ๋ผ์น  ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด 1๋กœ ์ฃผ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค. putc๋ผ๋Š” ์ธ์ž๋Š” int ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›๊ณ  int ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” ASCII ๋ฌธ์ž ๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์•„ ํ‘œ์ค€ ์ถœ๋ ฅ์˜ ์“ฐ๊ธฐ ์ž‘์—…์œผ๋กœ ํ„ฐ๋ฏธ๋„์— ASCII ๋ฌธ์ž ๊ฐ’์„ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.
tputs๋ผ๋Š” Routine์ด ๋ฌธ์ œ ์—†์ด ์ˆ˜ํ–‰๋˜๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

12) ์˜ˆ์‹œ

์ผ๋ฐ˜์ ์ธ ์‰˜์—์„œ๋Š” ๋ฐฉํ–ฅํ‚ค ๋“ฑ์„ ํ†ตํ•ด ํ‚ค ์กฐ์ž‘์„ ํ•˜๋ฉด ์ด์ƒํ•œ ๊ธฐํ˜ธ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๊ณ  ์ •ํ•ด์ง„ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ์œ„ ๋ฐฉํ–ฅํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ด์ „์— ์ž…๋ ฅํ–ˆ๋˜ ์ปค๋งจ๋“œ๋“ค์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ๋™ํ•œ ํ›„์—๋Š” ๋ฐฉํ–ฅํ‚ค ๋“ฑ์˜ ํ‚ค ์กฐ์ž‘์„ ํ•˜๋ฉด ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์ด์ƒํ•œ ๊ธฐํ˜ธ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. <term.h>๋ฅผ ๋‹ค๋ฃจ๋Š” ์˜ˆ์‹œ์—์„œ๋Š” ํ„ฐ๋ฏธ๋„ ์„ค์ • ๊ฐ’๊ณผ NCURSES๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์›ํ•˜๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ‚ค ์กฐ์ž‘์— ๋ณ€ํ™”๋ฅผ ์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.
์ œ์‹œ๋œ ์ฝ”๋“œ์—์„œ๋Š” ํ‘œ์ค€ ์ž…๋ ฅ์— ๋Œ€ํ•œ ์„ค์ •์„ ๋ฐ”๊พธ๋Š”๋ฐ, ๊ธฐ์กด์˜ Canonical ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๊ณ  ์žˆ๋Š” ํ‘œ์ค€ ์ž…๋ ฅ์„ Non-Canonical ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พธ๋ฉด์„œ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค. ํ‘œ์ค€ ์ž…๋ ฅ์—์„œ์˜ Canonical์ด๋ž€, ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๊ธธ์ด์˜ ๋ฌธ์ž๋Š” 255๋กœ ๋‘๊ณ  ์ž…๋ ฅ์„ ํ•œ ์ค„ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋ฅผ Non-Canonical๋กœ ๋ฐ”๊ฟ€ ๋•Œ๋Š” ICANON๊ณผ ๊ฐ™์€ ๋กœ์ปฌ ํ”Œ๋ž˜๊ทธ์™€ VMIN, VTIME๊ณผ ๊ฐ™์€ ์ปจํŠธ๋กค ๋ฌธ์ž๋ฅผ ์ฃผ๋กœ ์ด์šฉํ•œ๋‹ค.
Canonical์ด๋ผ๋Š” ์šฉ์–ด๋Š” ๊ทœ์ •์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ณ , ๋ฐ˜๋Œ€๋กœ Non-Canonical์ด๋ผ๋Š” ์˜๋ฏธ๋Š” ๊ทœ์ •์„ ๋”ฐ๋ฅด์ง€ ์•Š๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
๊ธฐ์กด์˜ ํ„ฐ๋ฏธ๋„ ์„ค์ • ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด์„œ Non-Canonical๋กœ ๋งŒ๋“ค๋ฉด์„œ ์กฐ์ž‘ํ•˜๋Š” ํ”Œ๋ž˜๊ทธ๋“ค์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์˜ˆ์‹œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
termios ๊ตฌ์กฐ์ฒด์˜ ํ”Œ๋ž˜๊ทธ ์„ค์ • ๊ฐ’๊ณผ TermCap์˜ ์ฟผ๋ฆฌ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ ์•„๋ž˜ ๋งํฌ๋“ค์„ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•˜์ž.
#include <ctype.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <term.h> #include <unistd.h> #define ERROR -1 #define KEY_LEFT 4479771 #define KEY_RIGHT 4414235 #define KEY_UP 4283163 #define KEY_DOWN 4348699 #define KEY_BACKSPACE 127 #define CURPOS "\033[6n" const char *g_cm; const char *g_ce; const char *g_dc; bool init_term(struct termios *t) { if (tcgetattr(STDIN_FILENO, t) == ERROR) return (false); t->c_lflag &= ~(ICANON | ECHO); t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 0; if (tcsetattr(STDIN_FILENO, TCSANOW, t) == ERROR) return (false); return (true); } bool init_query(void) { if (tgetent(NULL, "xterm") == ERROR) return (false); g_cm = tgetstr("cm", NULL); g_ce = tgetstr("ce", NULL); g_dc = tgetstr("dc", NULL); if (!g_cm || !g_ce) return (false); return (true); } int putchar(int c) { if (write(STDOUT_FILENO, &c, 1) == ERROR) return (0); return (1); } bool get_position(int *col, int *row) { int i; int ret; char buf[1024]; if (write(STDOUT_FILENO, CURPOS, strlen(CURPOS)) == ERROR) return (false); ret = read(STDIN_FILENO, buf, 1024); if (ret == ERROR) return (false); buf[ret] = '\0'; i = 0; while (!isdigit(buf[i])) ++i; *row = atoi(&buf[i]) - 1; while (isdigit(buf[i])) ++i; while (!isdigit(buf[i])) ++i; *col = atoi(&buf[i]) - 1; return (true); } bool cur_left(int *col, int *row) { if (*col) { --(*col); if (tputs(tgoto(g_cm, *col, *row), 1, putchar) == ERROR) return (false); } return (true); } bool cur_right(int *col, int *row) { ++(*col); if (tputs(tgoto(g_cm, *col, *row), 1, putchar) == ERROR) return (false); return (true); } bool cur_up(int *col, int *row) { if (*row) { --(*row); if (tputs(tgoto(g_cm, *col, *row), 1, putchar) == ERROR) return (false); } return (true); } bool cur_down(int *col, int *row) { ++(*row); if (tputs(tgoto(g_cm, *col, *row), 1, putchar) == ERROR) return (false); return (true); } bool cur_backspace(int *col, int *row) { if (*col) { --(*col); if (tputs(tgoto(g_cm, *col, *row), 1, putchar) == ERROR) return (false); } if (tputs(g_dc, 1, putchar) == ERROR) return (false); return (true); } bool key_handle(int ch, int *col, int *row) { if (ch == KEY_LEFT) { if (!cur_left(col, row)) return (false); } else if (ch == KEY_RIGHT) { if (!cur_right(col, row)) return (false); } else if (ch == KEY_UP) { if (!cur_up(col, row)) return (false); } else if (ch == KEY_DOWN) { if (!cur_down(col, row)) return (false); } else if (ch == KEY_BACKSPACE) { if (!cur_backspace(col, row)) return (false); } else { ++(*col); if (!putchar(ch)) return (false); } return (true); } bool read_char(void) { int ch; int ret; int col; int row; while (true) { if (!get_position(&col, &row)) return (false); ret = read(STDIN_FILENO, &ch, sizeof(ch)); if (ret == ERROR) return (false); if (!ret) return (true); if (!key_handle(ch, &col, &row)) return (false); ch = 0; } } int main(void) { struct termios t; if (!init_term(&t) || !init_query() || !read_char()) return (1); return (0); }
C
์˜ˆ์‹œ ์ฝ”๋“œ์—์„œ ์–ป๋Š” ๊ฒฐ๊ณผ๋Š” ์ง์ ‘ ๊ตฌ๋™ํ•ด์„œ ์ปค์„œ๋‚˜ ํ‚ค๋ณด๋“œ ๊ฐ’์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.
์œ„ ์ฝ”๋“œ์—์„œ ํ„ฐ๋ฏธ๋„ ์ƒ์˜ ์ปค์„œ ์œ„์น˜๋Š” \033[6n์ด๋ผ๋Š” Escape Sequence๋ฅผ ํ†ตํ•ด์„œ [row;colR ํ˜•ํƒœ์˜ ๊ฐ’์„ ์–ป์€ ํ›„์— ํŒŒ์‹ฑํ•˜์—ฌ ์•Œ์•„๋‚ธ๋‹ค. ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด, ์‹ค์ œ ์‰˜๊ณผ๋Š” ์‚ฌ๋ญ‡ ๋‹ค๋ฅธ ์ ์„ ๋Š๋‚„ ์ˆ˜ ์žˆ๋‹ค. ํ„ฐ๋ฏธ๋„ ์‚ฌ์ด์ฆˆ๋ฅผ ๋„˜์–ด๊ฐ„ ํ‚ค ์กฐ์ž‘์— ๋Œ€ํ•ด์„  ์›ํ•˜๋Š” ๋Œ€๋กœ ์กฐ์ž‘์ด ์•ˆ๋˜๊ธฐ๋„ ํ•˜๊ณ , ์ž…๋ ฅ๋œ ์œ„์— ์ปค์„œ๋ฅผ ๋‘๊ณ  ์ž…๋ ฅ์„ ๋ฐ›์œผ๋ฉด ๊ทธ ๊ฐ’์ด ๋ฎ์–ด์”Œ์›Œ์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์ž์— ๋Œ€ํ•ด์„œ๋Š” ์ด์–ด์„œ ์†Œ๊ฐœ๋˜๋Š” ioctl์„ ํ†ตํ•ด ์žฅ์น˜์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ด์–ด ํ„ฐ๋ฏธ๋„ ์‚ฌ์ด์ฆˆ ๋“ฑ์„ ์‰ฝ๊ฒŒ ์•Œ์•„๋‚ด์–ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ , ํ›„์ž์˜ ๊ฒฝ์šฐ์—๋Š” TermCap์˜ ์ฟผ๋ฆฌ๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

4. on <sys/ioctl.h>, <sys.wait.h>

1) ioctl

1. ์˜์กด์„ฑ

#include <sys/ioctl.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int ioctl(int fd, unsigned long request, ...);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

ioctl ํ•จ์ˆ˜๋Š” ์žฅ์น˜์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๋ฉฐ, ์‹œ์Šคํ…œ ์ฝœ์ด๋‹ค. <dirent.h>์—์„œ ์ŠคํŠธ๋ฆผ์„ ์„ค๋ช…ํ•˜๋ฉด์„œ Unix์˜ ๋ชจ๋“  ์žฅ์น˜๋Š” ์ถ”์ƒํ™”๋˜์–ด ํŒŒ์ผ๋กœ์จ ์กฐ์ž‘๋œ๋‹ค๊ณ  ํ–ˆ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ioctl ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์žฅ์น˜์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋„ ํŒŒ์ผ ์กฐ์ž‘์„ ํ†ตํ•ด์„œ ์ด๋ค„์ง€๋ฏ€๋กœ, fd๋Š” ์žฅ์น˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ๋œ๋‹ค.
ioctl์„ ํ†ตํ•ด ์กฐ์ž‘ํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ์žฅ์น˜๋กœ๋Š” ํ„ฐ๋ฏธ๋„์ด ์žˆ๋‹ค. ์ด ๋•Œ ioctl์˜ ์ธ์ž๋กœ ๋„ฃ๋Š” fd๋Š” open์„ ํ†ตํ•ด์„œ ์–ป์€ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ๋˜๋Š”๋ฐ, ๊ฐ„ํ˜น ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋ถ€์ž‘์šฉ์œผ๋กœ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์— ๋”ฐ๋ผ open์„ ์ˆ˜ํ–‰ํ•  ๋•Œ O_NONBLOCK ํ”Œ๋ž˜๊ทธ๋„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.
request๋ผ๋Š” ์ธ์ž๋Š” fd์— ํ•ด๋‹นํ•˜๋Š” ์žฅ์น˜์—๊ฒŒ ๋ณด๋‚ผ ์žฅ์น˜์—์„œ ์ œ๊ณต๋˜๋Š” ์ฝ”๋“œ์ด๊ณ , ๋งˆ์ง€๋ง‰ ์ธ์ž๋Š” ํŠน์ • ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ฐธ์กฐํ•˜๋Š” ํฌ์ธํ„ฐ์ด๋‹ค. ๋งˆ์ง€๋ง‰ ์ธ์ž๊ฐ€ ํฌ์ธํ„ฐ ํƒ€์ž… ์ž„์—๋„ ๊ฐ€๋ณ€ ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” ํ•จ์ˆ˜ ์›ํ˜•์—์„œ ํ•ด๋‹น ํฌ์ธํ„ฐ์˜ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•จ์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ๋งˆ์ง€๋ง‰ ์ธ์ž์˜ ๊ฐ€๋ณ€ ์ธ์ž์—๋Š” char * ํƒ€์ž…์œผ๋กœ ์ด์šฉํ•œ๋‹ค.
ํ•จ์ˆ˜ ์›ํ˜•์—์„œ ํฌ์ธํ„ฐ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š” ํ–‰์œ„๋Š” ํ•ด๋‹น ์ธ์ž๊ฐ€ ๋‹ค์–‘ํ•œ ํฌ์ธํ„ฐ ํƒ€์ž…์œผ๋กœ ์ด์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ธ๋ฐ, ์ด์™€ ์ผ๋งฅ์ƒํ†ตํ•œ ํฌ์ธํ„ฐ ํƒ€์ž…์€ void *์ด๋‹ค. ioctl ํ•จ์ˆ˜์—์„œ void *๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š์€ ์ด์œ ๋Š” ๋‹จ์ˆœํžˆ ioctl ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋‹น์‹œ์— void *๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ํƒ€์ž…์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ตœ๊ทผ ๋ช‡ ์‹œ์Šคํ…œ์—์„œ๋Š” ioctl์˜ ์›ํ˜•์„ void *๋กœ ์ด์šฉํ•˜๋Š” ๊ณณ๋„ ์žˆ๋‹ค.
ioctl ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. request๋ผ๋Š” ์ธ์ž๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ •์˜ ํ•˜์— ์ด์šฉ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” request์— ๋”ฐ๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰ ์ค‘์— ioctl ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๊ฒฝ์šฐ์—๋Š” ioctl์˜ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†์„ ๋•Œ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์–‘์ˆ˜๋ฅผ ์ด์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.
ioctl ํ•จ์ˆ˜๋Š” ์žฅ์น˜ ๋“œ๋ผ์ด๋ฒ„์— ๋”ฐ๋ผ ์ธ์ž ๋ฐ ๋ฐ˜ํ™˜ ๊ฐ’ ๋“ฑ Semantic์ด ๋‹ค์–‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Unix์˜ I/O์— ํ•ด๋‹นํ•˜๋Š” ์ŠคํŠธ๋ฆผ์—๋Š” ์ •๊ตํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.
๋ฐ˜ํ™˜ ๊ฐ’์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ request์— ๋Œ€ํ•œ ์ž‘์—…์„ ์ง์ ‘ ์ •์˜๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ๋ฐ, ์ด๋Š” <sys/ioctl.h>์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋งคํฌ๋กœ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. <sys/ioctl> ๋‚ด์—๋Š” <sys/ioccom.h>๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋Š”๋ฐ, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด _IO, _IOR, _IOW, _IOWR ํ•จ์ˆ˜๋“ค์„ ํ†ตํ•ด ์žฅ์น˜๊ฐ€ request๋ฅผ ๋ฐ›์•˜์„ ๋•Œ์˜ ํ–‰์œ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
ioctl์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด๋Š” 32 Bit๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ณ , ์ด๋“ค์€ ํŠน์ • ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋Š”๋‹ค. 2 Bit๋Š” R/W ๋“ฑ์˜ ์ž‘์—… ๊ตฌ๋ถ„, 14 Bit๋Š” size, 8 Bit๋Š” number, 8 Bit๋Š” type์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋“ค์ด ๊ณง ์ œ์‹œ๋œ ๊ทธ๋ฆผ์—์„œ _IO(type, number), {_IOR, _IOW, _IOWR}(type, number, size)์— ํ•ด๋‹น๋œ๋‹ค.
2 Bit์—์„œ ์‚ฌ์šฉ๋˜๋Š” R/W ๋“ฑ์˜ ์ž‘์—…์€ 00: None, 01: Write, 10: Read, 11: Read/Write๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋˜ํ•œ size๋Š” ๋งค๋‰ด์–ผ์—์„œ ์ •์˜๋œ ์ด๋ฆ„์ธ ๋งŒํผ ํŠน์ • ์‹œ์Šคํ…œ์—์„œ๋„ ํ•ด๋‹น ์ด๋ฆ„์„ ์ด์šฉํ•˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ, ์ด๋Š” ์ž˜๋ชป๋œ ๋ช…์นญ์ด๋‹ค. size์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์€ sizeof(size)์ด๋ฏ€๋กœ ์ „์ฒด์ ์œผ๋กœ ๊ฐ ์ธ์ž๋ฅผ ๋‹ค์‹œ ๋ช…๋ช…ํ•  ํ•„์š”์„ฑ์ด ์ œ์‹œ๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ์„œ ๊ฐ ์ธ์ž๋ฅผ ์ง€์นญํ•˜๋Š” ์ด๋ฆ„์ด ๋”ฐ๋กœ ์ •ํ•ด์กŒ์œผ๋ฉฐ, Mac OS X์—์„œ๋Š” ์œ„ ๊ทธ๋ฆผ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด size โ†’ type (t), number โ†’ number (n), type โ†’ group (g)๋กœ ๋‚˜ํƒ€๋‚œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. size๊ฐ€ sizeof(size)๋กœ ์ด์šฉ๋œ๋‹ค๋Š” ์‚ฌ์‹ค์— ๋”ฐ๋ผ, ๊ตฌ์กฐ์ฒด ํ˜น์€ Legacy ๊ฐ’์„ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํ˜ธํ™˜์„ฑ์ด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
ioctl ํ•จ์ˆ˜์˜ ๋งคํฌ๋กœ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ ์˜ˆ์‹œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•˜๋„๋กํ•˜๊ณ , ์—ฌ๊ธฐ์„œ์˜ ์ œ์‹œ๋  ์˜ˆ์‹œ๋Š” ioctl ํ•จ์ˆ˜์™€ winsize ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•œ ํ„ฐ๋ฏธ๋„ ์‚ฌ์ด์ฆˆ ํ™•์ธ์ด๋‹ค.
์˜ค๋ž˜ ์ „์˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ttysize๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ–ˆ๋Š”๋ฐ, winsize๋ผ๋Š” ๊ตฌ์กฐ์ฒด๊ฐ€ ์ƒ๊ธฐ๋ฉด์„œ ttysize๋Š” Obsolete๋˜์—ˆ๋‹ค. ํ•ด๋‹น ๊ตฌ์กฐ์ฒด ์—ญ์‹œ <sys/ioctl.h> ๋‚ด์— ์กด์žฌํ•œ๋‹ค. ์ด ๋•Œ winsize์˜ ws_xpixel๊ณผ ws_ypixel์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์ด๋‹ค.

4. ์˜ˆ์‹œ

#include <stdio.h> #include <sys/ioctl.h> #include <unistd.h> int main(void) { struct winsize size; if (ioctl(STDIN_FILENO, TIOCGWINSZ, &size) == -1) return (1); printf("Terminal Row Size:\t%d\n",size.ws_row); printf("Terminal Col Size:\t%d\n",size.ws_col); return (0); }
C

2) wait3

1. ์˜์กด์„ฑ

#include <sys/wait.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

pid_t wait3(int *status, int options, struct rusage *rusage);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

wait3 ํ•จ์ˆ˜๋Š” waitpid ํ˜น์€ waitid ํ•จ์ˆ˜๊ฐ€ ๋‚˜์˜ค๋ฉด์„œ Obsolete ๋œ ํ•จ์ˆ˜์ด๋‹ค. ํ•จ์ˆ˜์˜ ๊ธฐ๋Šฅ ์ž์ฒด๋Š” waitpid ํ•จ์ˆ˜์™€ ๋™์ผํ•œ๋ฐ, ๊ทธ๋Ÿผ์—๋„ wait3 ํ•จ์ˆ˜๋ฅผ ์ดํ•ดํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ํ†ตํ•ด pipex์—์„œ์˜ wait๊ณผ waitpid์— ๊ธฐ์ˆ ๋œ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ status์™€ options๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์„ ๊ถŒํ•œ๋‹ค.
wait3(status, options, rusage)์˜ ํ˜ธ์ถœ์€ waitpid(-1, status, options)์™€ ๋™์ผํ•˜๋‹ค.
pipex ๋งํฌ๋ฅผ ํ†ตํ•ด wait ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ๊ธฐ์กด์˜ wait ํ•จ์ˆ˜๋Š” waitpid์—์„œ์˜ options๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— option์— ํ•ด๋‹นํ•˜๋Š” ํŠน์ • ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ wait3 ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ–ˆ์—ˆ๋‹ค. wait ํ•จ์ˆ˜ ๋Œ€์‹ ์— wait3 ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ–ˆ๋˜ ๋˜ ๋‹ค๋ฅธ ์ด์œ ๋กœ๋Š” rusage๋ผ๋Š” ๊ตฌ์กฐ์ฒด ๋•Œ๋ฌธ์ธ๋ฐ, rusage๋ผ๋Š” ์ธ์ž๋Š” Resource Usage์˜ ์•ฝ์ž์ด๋ฉฐ ์ž์›์˜ ์‚ฌ์šฉ๋Ÿ‰์„ ์˜๋ฏธํ•˜๋Š” ๊ตฌ์กฐ์ฒด์ด๋‹ค. wait3์˜ rsuage๋ผ๋Š” ๊ตฌ์กฐ์ฒด์˜ ๊ฐ’์ด NULL์ด ์•„๋‹ˆ๋ผ๋ฉด, wait3์˜ ํ•จ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ ์ž์›์— ๋Œ€ํ•ด์„œ ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ rusage์— ๊ธฐ๋กํ•˜๊ฒŒ ๋œ๋‹ค. rusage์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์€ ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์œ ์ง€๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
wait3์˜ ํ•จ์ˆ˜๊ฐ€ Obsolete๋œ ์ด์œ ๋Š” ํ‘œ์ค€ํ™” ๋•Œ๋ฌธ์ธ๋ฐ, wait3 ํ•จ์ˆ˜๋Š” BSD ๊ณ„์—ด ์‹œ์Šคํ…œ์˜ ์‹œ์Šคํ…œ ์ฝœ์— ํ•ด๋‹นํ•˜๋Š”๋ฐ POSIX์— ์˜ํ•ด ํ‘œ์ค€ํ™” ๋˜๋ฉด์„œ waitpid๋ฅผ ์ด์šฉํ•˜๋„๋ก ๊ถŒ์žฅ๋˜์—ˆ๋‹ค. ์ด ๋•Œ waitpid ํ•จ์ˆ˜๋ฅผ ์ž˜ ์‚ดํŽด๋ณด๋ฉด, wait3๊ฐ€ waitpid๋กœ ๋Œ€์ฒด๋˜๋ฉด์„œ option์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ rusage๋ฅผ ์–ป๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํ•จ์ˆ˜์˜ ๋ชฉ์ ์„ ๊ตฌ๋ถ„ ์ง“๊ธฐ ์œ„ํ•ด์„œ waitpid์—์„œ๋Š” rusage๋ฅผ ๋” ์ด์ƒ ์ด์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋œ ๊ฒƒ์ธ๋ฐ, ์ด ๋•Œ๋ฌธ์— rusage๋Š” getrusage๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. minishell์˜ ๊ฒฝ์šฐ์—๋Š” getrusage๊ฐ€ ํ—ˆ์šฉ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ์ผ ์ž์›์˜ ์‚ฌ์šฉ๋Ÿ‰์„ ์–ป์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ์žˆ๋‹ค๋ฉด, ์ด ๋•Œ๋งŒํผ์€ wait3 ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
getrusage์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ๋ณด๋‹ค ์ž์„ธํžˆ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.
wait3 ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋Š” wait ๋ฐ waitpid์™€ ๋™์ผํ•˜๋‹ค. pid_t ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ pid๋ฅผ ์˜๋ฏธํ•˜๊ณ , ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ๊ทธ๋„์— ์˜ํ•ด์„œ ์ข…๋ฃŒ๋˜๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
์ฃผ์–ด์ง„ ์˜ˆ์‹œ์—์„œ๋Š” ๋ณ„๋„์˜ options๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ณ , status๋ฅผ ์ทจ๋“ํ•˜์ง€๋„ ์•Š์„ ๊ฒƒ์ด๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์€ pipex์—์„œ waitpid๋ฅผ ํ†ตํ•ด ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ์ž„์˜์˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด์„œ ์ž์› ์‚ฌ์šฉ๋Ÿ‰์— ๋Œ€ํ•ด์„œ ํŒŒ์•…ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

4. ์˜ˆ์‹œ

#include <stdio.h> #include <sys/wait.h> #include <unistd.h> #include <sys/time.h> int main(void) { struct rusage ru; pid_t pid; pid = fork(); if (pid == -1) return (1); else if (!pid) { printf("Child Process\n"); return (0); } else { wait3(NULL, 0, &ru); printf("Parent Process\n"); printf("=========Resource Usage of Child========\n"); printf("Number of Context Switch (Voluntary)\t%ld\n", ru.ru_nvcsw); printf("Number of Context Switch (Involuntary)\t%ld\n", ru.ru_nivcsw); printf("Number of Page Swap\t%ld\n", ru.ru_nswap); printf("Number of Page Fault\t%ld\n", ru.ru_majflt); printf("Signal Received\t%ld\n", ru.ru_nsignals); } return (0); }
C

3) wait4

1. ์˜์กด์„ฑ

#include <sys/wait.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

wait4 ํ•จ์ˆ˜๋Š” wait3 ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ waitpid ํ˜น์€ waitid ํ•จ์ˆ˜๊ฐ€ ๋‚˜์˜ค๋ฉด์„œ Obsolete ๋œ ํ•จ์ˆ˜์ด๋‹ค. ํ•จ์ˆ˜์˜ ๊ธฐ๋Šฅ ์ž์ฒด๋Š” waitpid ํ•จ์ˆ˜์™€ ๋™์ผํ•˜๋ฉฐ, wait3 ํ•จ์ˆ˜์™€์˜ ์ฐจ์ด์ ์€ ํ•จ์ˆ˜์˜ ์ž‘์—…์„ ์–ด๋–ค ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ํŠน์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.
wait4(pid, status, options, rusage)์˜ ํ˜ธ์ถœ์€ waitpid(pid, status, options)์™€ ๋™์ผํ•˜๋‹ค.
wait4 ํ•จ์ˆ˜๋Š” ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ํŠน์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ชจ๋‘ wait3 ํ•จ์ˆ˜์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์—์„œ wait3 ํ•จ์ˆ˜๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ ๊ถŒํ•œ๋‹ค.
wait4 ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋Š” wait3 ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ wait ๋ฐ waitpid์™€ ๋™์ผํ•˜๋‹ค. pid_t ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ pid๋ฅผ ์˜๋ฏธํ•˜๊ณ , ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ๊ทธ๋„์— ์˜ํ•ด์„œ ์ข…๋ฃŒ๋˜๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
์ฃผ์–ด์ง„ ์˜ˆ์‹œ์—์„œ๋Š” ๋ณ„๋„์˜ options๋ฅผ ์ด์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ณ , status๋ฅผ ์ทจ๋“ํ•˜์ง€๋„ ์•Š์„ ๊ฒƒ์ด๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์€ pipex์—์„œ waitpid๋ฅผ ํ†ตํ•ด ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ์ž„์˜์˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด์„œ ์ž์› ์‚ฌ์šฉ๋Ÿ‰์— ๋Œ€ํ•ด์„œ ํŒŒ์•…ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

4. ์˜ˆ์‹œ

#include <stdio.h> #include <sys/wait.h> #include <unistd.h> #include <sys/time.h> int main(void) { struct rusage ru; pid_t pid; pid = fork(); if (pid == -1) return (1); else if (!pid) { printf("Child Process\n"); return (0); } else { wait4(pid, NULL, 0, &ru); printf("Parent Process\n"); printf("=========Resource Usage of %d========\n", pid); printf("Number of Context Switch (Voluntary)\t%ld\n", ru.ru_nvcsw); printf("Number of Context Switch (Involuntary)\t%ld\n", ru.ru_nivcsw); printf("Number of Page Swap\t%ld\n", ru.ru_nswap); printf("Number of Page Fault\t%ld\n", ru.ru_majflt); printf("Signal Received\t%ld\n", ru.ru_nsignals); } return (0); }
C

5. on <unistd.h>, <stdlib.h>, <signal.h>

1) getcwd

1. ์˜์กด์„ฑ

#include <unistd.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *getcwd(char *buf, size_t size);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

getcwd๋Š” getcwd๋ฅผ ํ˜ธ์ถœํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๋ฌธ์ž์—ด๋กœ ์–ป๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋Š” buf๋ผ๋Š” char * ํƒ€์ž…์˜ ์ธ์ž์— ๊ธฐ๋ก์„ ํ•˜๊ฒŒ ๋˜๊ณ , size๋Š” buf์˜ ํฌ๊ธฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. buf์— ๊ธฐ๋ก๋˜๋Š” ๋ฌธ์ž์—ด์€ '\0'์ด๋ผ๋Š” ๋„ ๋ฌธ์ž๋กœ ๋๋‚˜๊ธฐ ๋•Œ๋ฌธ์—, size๋Š” ๋„ ๋ฌธ์ž๊นŒ์ง€ ํฌํ•จํ•œ ํฌ๊ธฐ์ž„์„ ๋ช…์‹ฌํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์ผ ๋„ ๋ฌธ์ž๊นŒ์ง€ ๊ณ ๋ คํ•œ ์ฑ„๋กœ buf์— ๊ธฐ๋กํ•˜๋ ค๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ์˜ ๋ฌธ์ž์—ด ๊ธธ์ด๊ฐ€ size๋ฅผ ๋„˜๊ฒŒ ๋˜๋ฉด, NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ ์ ˆ๋Œ€ ๊ฒฝ๋กœ์˜ ๊ธฐ๋ก์ด ์„ฑ๊ณต์ ์ด๋ผ๋ฉด buf์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค,
getcwd์˜ ํŠน์ดํ•œ ์ ์œผ๋กœ๋Š” buf์˜ ์ธ์ž๋กœ NULL์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด, ๋‚ด๋ถ€์ ์œผ๋กœ size๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ๋™์  ํ• ๋‹น์„ ๋ฐ›์•„ ํ•ด๋‹น ๊ณต๊ฐ„์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋œ๋‹ค. ๋งŒ์ผ size ๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ๋™์  ํ• ๋‹น์„ ๋ฐ›์•„์„œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ๋™์  ํ• ๋‹น์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ๋™์  ํ• ๋‹น ๋ฐ›์€ ๊ณต๊ฐ„์— ๋Œ€ํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ free๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์ผ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด, NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

4. ์˜ˆ์‹œ

#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(void) { char *path; path = getcwd(NULL, 0); if (!path) return (1); printf("%s\n", path); free(path); path = NULL; return (0); }
C

2) chdir

1. ์˜์กด์„ฑ

#include <unistd.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int chdir(const char *path);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

chdir ํ•จ์ˆ˜๋Š” ํ˜„์žฌ ๊ตฌ๋™๋˜๊ณ  ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฒฝ๋กœ๋ฅผ path๋กœ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ๊ฒฝ๋กœ์˜ ๋ณ€๊ฒฝ์ด ์„ฑ๊ณต์ ์ด๋ผ๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

4. ์˜ˆ์‹œ

#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(void) { char *path; path = getcwd(NULL, 0); if (!path) return (1); printf("Before:\t%s\n", path); free(path); path = NULL; if (chdir("../") == -1) return (1); path = getcwd(NULL, 0); if (!path) return (1); printf("After:\t%s\n", path); free(path); path = NULL; return (0); }
C

3) isatty

1. ์˜์กด์„ฑ

#include <unistd.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int isatty(int fd);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ธ์ž๋กœ ๋ฐ›์€ fd๋ผ๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š”์ง€์˜ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋œ๋‹ค. ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๋ฉด 1์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
isatty์˜ ํ˜ธ์ถœ๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜๋Š” EBADF, ENOTTY 2๊ฐ€์ง€์ธ๋ฐ, ๊ฐ๊ฐ์— ๋Œ€ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” fd๋ฅผ ์ด์šฉํ•˜๊ฑฐ๋‚˜ fd๊ฐ€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์ง€ ์•Š์•„์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฐ’๋“ค์ด๋‹ค. 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ƒํ™ฉ์— ๋Œ€ํ•ด์„œ๋Š” ์ œ์‹œ๋œ 2๊ฐ€์ง€ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด์„œ๋„ ๋ชจ๋‘ ํฌํ•จ๋˜๋Š”๋ฐ, ์ด ๋•Œ๋ฌธ์— isatty ํ˜ธ์ถœ ์ „๊ณผ ํ›„๋กœ errno๋ฅผ ๋น„๊ตํ•˜์—ฌ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด์„œ ๊ฒ€์ถœํ•  ํ•„์š”๋Š” ์—†๋‹ค. ์ œ์‹œ๋œ 2๊ฐ€์ง€ ์˜ค๋ฅ˜๋“ค์€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ํ•จ์ˆ˜ ์ž์ฒด์˜ ๋ชฉ์ ์„ ํ๋ฆฌ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด, 2๊ฐ€์ง€ ์˜ค๋ฅ˜ ์ค‘ ์–ด๋–ค ์ƒํ™ฉ์ด ๋˜๋”๋ผ๋„ ์ธ์ž๋กœ ๋ฐ›์€ fd๊ฐ€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๋ช…ํ™•ํ•œ ์‚ฌ์‹ค์ด๋‹ค.
์•„๋ž˜ ๋งํฌ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” IBM์˜ isatty ํ•จ์ˆ˜์˜ ์˜ˆ์‹œ์—์„œ๋„ ๋ณ„๋„์˜ ์˜ค๋ฅ˜ ๊ฒ€์‚ฌ๋ฅผ ํ•˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

4. ์˜ˆ์‹œ

#include <fcntl.h> #include <stdio.h> #include <unistd.h> void censor(int fd, const char *s) { if (isatty(fd)) { if (s) printf("%s is referring to a terminal\n", s); else printf("File Descriptor %d is referring to a terminal\n", fd); } else { if (s) printf("%s is not referring to a terminal\n", s); else printf("File Descriptor %d is not referring to a terminal\n", fd); } } int main(void) { int fd; fd = open("test", O_RDONLY); if (fd < 0) return (1); censor(STDIN_FILENO, "STDIN"); censor(STDOUT_FILENO, "STDOUT"); censor(STDERR_FILENO, "STDERR"); censor(fd, NULL); censor(42, NULL); close(fd); return (0); }
C

4) ttyname

1. ์˜์กด์„ฑ

#include <unistd.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *ttyname(int fd);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์ธ์ž๋กœ ๋ฐ›์€ fd๋ผ๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ํ„ฐ๋ฏธ๋„์˜ ๊ฒฝ๋กœ๋ฅผ '\0'๋ผ๋Š” ๋„ ๋ฌธ์ž๋กœ ์ข…๋ฃŒ๋˜๋Š” ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ fd๊ฐ€ ํ„ฐ๋ฏธ๋„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด, NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜ ๋ฐ›์€ ๋ฌธ์ž์—ด์€ ๋‚ด๋ถ€์ ์œผ๋กœ static ํ˜•ํƒœ๋กœ ํ• ๋‹น๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ttyname์˜ ์—ฐ์ด์€ ํ˜ธ์ถœ์— ์˜ํ•ด ๊ทธ ๊ฐ’์ด ๋ฎ์–ด์“ฐ์ผ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ static ํ˜•ํƒœ๋กœ ํ• ๋‹น๋˜์—ˆ์œผ๋ฏ€๋กœ ๋ณ„๋„์˜ free ํ˜ธ์ถœ์€ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

4. ์˜ˆ์‹œ

#include <fcntl.h> #include <stdio.h> #include <unistd.h> void censor(int fd, const char *s) { if (isatty(fd)) { if (s) printf("%s is referring to a terminal\n", s); else printf("File Descriptor %d is referring to a terminal\n", fd); } else { if (s) printf("%s is not referring to a terminal\n", s); else printf("File Descriptor %d is not referring to a terminal\n", fd); } printf("TTYNAME:\t%s\n", ttyname(fd)); } int main(void) { int fd; fd = open("test", O_RDONLY); if (fd < 0) return (1); censor(STDIN_FILENO, "STDIN"); censor(STDOUT_FILENO, "STDOUT"); censor(STDERR_FILENO, "STDERR"); censor(fd, NULL); censor(42, NULL); close(fd); return (0); }
C

5) ttyslot

1. ์˜์กด์„ฑ

#include <unistd.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int ttyslot(void);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

ttyslot์„ ํ˜ธ์ถœํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ํ„ฐ๋ฏธ๋„์˜ index๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ๊ฒฝ์šฐ ์ด์šฉํ•˜๊ณ  ์žˆ๋Š” ์‹œ์Šคํ…œ์— ๋”ฐ๋ผ 0 ํ˜น์€ -1์ด ๋ฐ˜ํ™˜๋œ๋‹ค. ๋ฐ˜ํ™˜ ๋ฐ›์€ ๊ฐ’์€ ํ„ฐ๋ฏธ๋„์— ๋Œ€ํ•œ DB์˜ ์—”ํŠธ๋ฆฌ index๋กœ ์ด์šฉ๋˜๋Š”๋ฐ, ttyslot ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ Legacy ํ•จ์ˆ˜๋ผ๋Š” ์ ์„ ์ฐธ๊ณ ํ•˜์ž.

4. ์˜ˆ์‹œ

#include <fcntl.h> #include <stdio.h> #include <unistd.h> void censor(int fd, const char *s) { if (isatty(fd)) { if (s) printf("%s is referring to a terminal\n", s); else printf("File Descriptor %d is referring to a terminal\n", fd); } else { if (s) printf("%s is not referring to a terminal\n", s); else printf("File Descriptor %d is not referring to a terminal\n", fd); } printf("TTYNAME:\t%s\n", ttyname(fd)); } int main(void) { int fd; printf("TTYSLOT:\t%d\n", ttyslot()); fd = open("test", O_RDONLY); if (fd < 0) return (1); censor(STDIN_FILENO, "STDIN"); censor(STDOUT_FILENO, "STDOUT"); censor(STDERR_FILENO, "STDERR"); censor(fd, NULL); censor(42, NULL); close(fd); return (0); }
C

6) getenv

1. ์˜์กด์„ฑ

#include <stdlib.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *getenv(const char *name);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

name์— ํ•ด๋‹นํ•˜๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ๊ฐ’์— ๋Œ€ํ•œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์„ ์ฐพ์ง€ ๋ชปํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๊ฒฝ์šฐ์—๋Š” NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. getenv์— ์˜ํ•ด ์ฐธ์กฐ๋˜๊ณ  ์žˆ๋Š” ๊ฐ’๋“ค์€ ๋‚ด๋ถ€์ ์œผ๋กœ static ํ˜•ํƒœ๋กœ ํ• ๋‹น๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— free ํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ์ ์„ ๋ช…์‹ฌํ•ด์•ผ ํ•œ๋‹ค.

4. ์˜ˆ์‹œ

#include <stdlib.h> #include <stdio.h> int main(void) { char *term; term = getenv("TERM"); if (!term) return (1); printf("Term Type is %s\n", term); return (0); }
C

7) signal

1. ์˜์กด์„ฑ

#include <signal.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

์‹œ๊ทธ๋„์€ ์ผ์ข…์˜ IPC์ด๋ฉด์„œ ๋™์‹œ์— Interrupt์ด๋‹ค. ์‹œ๊ทธ๋„์€ ์†Œํ”„ํŠธ์›จ์–ด ์ธก๋ฉด์—์„œ ๋ฐœ์ƒ๋˜๋Š” Interrupt๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, Philosophers์—์„œ Interrupt์— ๋Œ€ํ•œ ๊ฐœ๋…์„ ๋‹ค๋ค˜์„ ๋•Œ๋Š” Interrupt์˜ ๋ฐœ์ƒ ์ฃผ์ฒด๊ฐ€ ํ•˜๋“œ์›จ์–ด๋ผ๊ณ  ํ–ˆ์—ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ์‹œ๊ทธ๋„์ด Interrupt์˜ ์ •์˜์— ์œ„๋ฐ˜๋˜๋Š” ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์†Œํ”„ํŠธ์›จ์–ด ์ƒ์—์„œ ctrl ์กฐํ•ฉ ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜์—ฌ Interrupt๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ํ„ฐ๋ฏธ๋„์˜ ์ œ์–ด๋ฅผ ์ด์šฉํ•˜๋ฏ€๋กœ ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•˜๋“œ์›จ์–ด๋ฅผ ์ด์šฉํ•˜๋Š” Interrupt๊ฐ€ ๋œ๋‹ค. ์ฆ‰, ์‹œ๊ทธ๋„์ด๋ผ๋Š” ์†Œํ”„ํŠธ์›จ์–ด ์ธก๋ฉด์˜ Interrupt ๋ฐœ์ƒ์€ ์ผ์ข…์˜ Interrupt Delegation์ด๋ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
signal ํ•จ์ˆ˜๋Š” ํŠน์ • ์‹œ๊ทธ๋„์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•  ๋™์ž‘์„ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์ผ์ „์— pipex ๊ธ€์—์„œ ์‹œ๊ทธ๋„์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•ด์„œ ์–ธ๊ธ‰ํ•œ ์ ์ด ์žˆ๋‹ค. ์‹œ๊ทธ๋„์˜ ์ฒ˜๋ฆฌ ๋™์ž‘์€ SIG_IGN (๋ฌด์‹œ), SIG_DFL (๊ธฐ๋ณธ ์ •์˜), ํ•ธ๋“ค๋Ÿฌ (์‚ฌ์šฉ์ž ์ •์˜)๋กœ ๋‚˜๋‰˜๋Š”๋ฐ, ์œ„ ๊ทธ๋ฆผ์—์„œ ์ œ์‹œ๋œ ๊ฐ ๋™์ž‘๋“ค์˜ ํƒ€์ž…๋“ค์ด ๋™์ผํ•œ ๊ฒƒ์„ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด signal ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํŠน์ • ์‹œ๊ทธ๋„์˜ ์ฒ˜๋ฆฌ ๋™์ž‘์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ฐ ์‹œ๊ทธ๋„๋“ค์˜ SIG_DFL์˜ ๋™์ž‘์€ ์•„๋ž˜ ๋งํฌ์˜ Default Action์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. signal ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋™์ž‘์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ทธ๋„๋“ค์€ SIGKILL, SIGSTOP, SIGCONT ๋“ฑ์„ ์ œ์™ธํ•œ ์‹œ๊ทธ๋„๋“ค์ด๋‹ค.
signal ํ•จ์ˆ˜์˜ signum์€ ์ •์˜ํ•˜๊ณ ์ž ํ•˜๋Š” ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ๋ฅผ ์˜๋ฏธํ•˜๊ณ , handler๋Š” sighandler_t ํƒ€์ž…์˜ ์ •์˜ํ•˜๊ณ ์ž ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. handler๊ฐ€ ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•จ์—๋„ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํƒ€์ž…์ด ์•„๋‹Œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” sighandler_t ํƒ€์ž…์˜ ์ •์˜๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ณด๋ฉด ์˜๋ฌธ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. sighandler_t๋Š” void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  signum์„ ๋ฐ›๊ธฐ ์œ„ํ•œ int ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
signal ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๋ณด๋ฉด sighandler_t ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ฐ˜ํ™˜ ํƒ€์ž…์— ๋ช…์‹œ๋œ ๊ฒƒ์ฒ˜๋Ÿผ signal ํ•จ์ˆ˜๋Š” ํŠน์ • ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด ๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ํ•ธ๋“ค๋Ÿฌ๋Š” signal ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ์ด์šฉ๋œ handler๊ฐ€ ์•„๋‹ˆ๋ผ, ์‹œ๊ทธ๋„์˜ ์ฒ˜๋ฆฌ ๋™์ž‘์ด handler๋กœ ์ •์˜๋˜๊ธฐ ์ด์ „์— ์ •์˜๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, signal ํ•จ์ˆ˜์˜ ๋™์ž‘ ์ž์ฒด๋Š” ํŠน์ • ์‹œ๊ทธ๋„์˜ ๋™์ž‘์— ๋Œ€ํ•œ ์ •์˜์ด์ง€๋งŒ, ์กฐ๊ธˆ ๋” ์ •ํ™•ํ•˜๊ฒŒ๋Š” ํŠน์ • ์‹œ๊ทธ๋„์˜ ๋™์ž‘์— ๋Œ€ํ•œ ์ •์˜๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋งŒ์ผ signal ํ•จ์ˆ˜ ์ˆ˜ํ–‰ ๋„์ค‘์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด, signal ํ•จ์ˆ˜๋Š” ์ด์ „์— ๋“ฑ๋ก๋œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ SIG_ERR๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์ด์— ๋Œ€ํ•œ ๊ฒ€์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
sighandler_t๋Š” GNU Extension์—์„œ ์ •์˜๋œ ํƒ€์ž…์ธ๋ฐ, glibc์—๋Š” GNU Extension ์ด์™ธ์—๋„ sig_t์™€ ๊ฐ™์€ BSD Extension์œผ๋กœ ์ •์˜๋œ ํƒ€์ž…์œผ๋กœ๋„ signal ํ•จ์ˆ˜๊ฐ€ ๋ช…์‹œ๋˜์–ด ์žˆ๋‹ค. ๋งŒ์ผ ์ด๋Ÿฌํ•œ ํƒ€์ž… ์—†์ด signal ํ•จ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•˜๋ฉด void ( *signal(int signum, void (*handler)(int)) ) (int); ์™€ ๊ฐ™์ด ์ฝ๊ธฐ ํž˜๋“  ๊ตฌ๋ฌธ์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
signal ํ•จ์ˆ˜ ์ž์ฒด์˜ ๋ฌธ์ œ์ ๋„ ์žˆ๋Š”๋ฐ, ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ์˜ signal ํ•จ์ˆ˜์˜ ์ด์šฉ์€ Unspecified Behavior๋ผ๋Š” ์ ๊ณผ signal ํ•จ์ˆ˜์˜ ์ด์šฉ์€ ์ด์‹์„ฑ ์ธก๋ฉด์—์„œ ๊ทธ๋ฆฌ ์ข‹์€ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ์ ์ด๋‹ค. ํ›„์ž์— ๋Œ€ํ•ด์„œ ์กฐ๊ธˆ ๋” ๋‹ค๋ค„๋ณด์ž๋ฉด, SIG_IGN, SIG_DFL์„ ์ œ์™ธํ•˜๊ณ  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์€ ์‹œ์Šคํ…œ๋งˆ๋‹ค ์ด๋ฅผ ์ •์˜ํ•œ Semantic์ด ๊ต‰์žฅํžˆ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํฐ ์ด์œ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ณผ๊ฑฐ์˜ Unix ๊ณ„์—ด์˜ ์‹œ์Šคํ…œ์—์„œ๋Š” signal ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋“ฑ๋กํ•œ ํ•ธ๋“ค๋Ÿฌ๋กœ ์‹œ๊ทธ๋„์ด ์ฒ˜๋ฆฌ๋˜๊ณ  ๋‚˜๋ฉด, ์‹œ๊ทธ๋„์˜ ์ฒ˜๋ฆฌ ๋™์ž‘์€ SIG_DFL๋กœ ์žฌ์„ค์ •๋˜๋„๋ก ๋˜์–ด ์žˆ์—ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์— ๋‹ค์‹œ ์‹œ๊ทธ๋„์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ •์˜ํ•˜๋Š” ํ–‰์œ„๊ฐ€ ์š”๊ตฌ๊ฐ€ ๋˜์—ˆ๊ณ , ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ signal ํ•จ์ˆ˜์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ๋ฐœ์ƒ๋˜๋Š” ์‹œ๊ทธ๋„์— ๋Œ€ํ•ด์„œ๋Š” ์‹œ์Šคํ…œ ์ƒ์—์„œ ๋ง‰์ง€ ์•Š์•„ SIG_DFL๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉด์„œ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค. ๋ฌผ๋ก  ์ผ๋ถ€ Unix ์‹œ์Šคํ…œ์—์„œ๋งŒ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ด๊ธด ํ•˜๋‚˜ ๋ถ„๋ช… ์ด์‹์„ฑ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋œ ๊ฒƒ์ด๋‹ค.
POSIX์—์„œ๋Š” ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ signal ํ•จ์ˆ˜ ๋Œ€์‹ ์— sigaction์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋„๋ก ๋งŒ๋“ค๋ฉด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. sigaction์€ sigaction์ด๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ํ†ตํ•ด signal ํ•จ์ˆ˜์˜ ๊ธฐ๋Šฅ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๊ฒŒ ๋˜๋ฉด์„œ, ๊ฒฐ๊ณผ์ ์œผ๋กœ signal ์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ”ผํ•˜๊ณ  sigaction ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. minishell์—์„œ๋Š” signal์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ ์— ํฌ๊ฒŒ ํ•ด๋‹น๋˜์ง€ ์•Š์„ ๋ฟ๋”๋Ÿฌ sigaction ๋ฐ ์ด์™€ ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ํ•จ์ˆ˜๋“ค์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— signal ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ, signal ํ•จ์ˆ˜ ๋Œ€์‹ ์— ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹ฌํ•ด์•ผ ํ•œ๋‹ค.
signal ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค๋„ ์žˆ๋‹ค. ์ฒซ ์งธ๋Š” signal ํ•จ์ˆ˜ ๋‚ด์—์„œ๋Š” ๋ฐ˜๋“œ์‹œ Async-Signal-Safe ํ•จ์ˆ˜๋“ค๋งŒ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค. Async-Signal-Safeํ•œ ํ•จ์ˆ˜๋“ค์€ ๋Œ€์ฒด์ ์œผ๋กœ Reentrant๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜๋“ค์ด๋‹ค. Reentrant๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋Œ€ํ‘œ์ ์ธ ํ•จ์ˆ˜๋กœ๋Š” printf๊ฐ€ ์žˆ๋Š”๋ฐ, printf๋Š” Async-Signal-Safeํ•˜์ง€ ์•Š๋‹ค. ๋งŒ์ผ printf์˜ ํ˜ธ์ถœ๋กœ ์ถœ๋ ฅ ์ค‘์ธ ์ƒํƒœ์—์„œ ์‹œ๊ทธ๋„์„ ๋ฐ›์•„์„œ ์‹œ๊ทธ๋„ ์ฒ˜๋ฆฌ ๋™์ž‘์—์„œ๋„ printf๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด, ์›ํ•˜๋Š” ์ถœ๋ ฅ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค. printf์˜ ์ถœ๋ ฅ ์ž์ฒด๋Š” Buffer Management๋ฅผ ํ†ตํ•ด ์ถœ๋ ฅ์„ ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ๋‚ด๋ถ€์— ๋ณ„๋„๋กœ ๋‘” Buffer๋ฅผ ํ† ๋Œ€๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์“ฐ๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ œ์‹œ๋œ ์ƒํ™ฉ์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์“ฐ๋Š” ์ž‘์—…์— ์ด์šฉ๋˜๋Š” ๊ธฐ์กด์˜ Buffer์˜ ๋‚ด์šฉ์ด ์†์‹ค๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ๋™์ž‘๋“ค์ด ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด์„  ๋ฐ˜๋“œ์‹œ Async-Signal-Safe ํ•จ์ˆ˜๋“ค๋งŒ ์ด์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค. ์ด์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋“ค์€ Reentrant๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ์Šคํ…œ ์ฝœ๋“ค์— ํ•ด๋‹นํ•˜๋Š”๋ฐ, signal ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์€ ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
๋‘˜ ์งธ๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ kill์ด๋‚˜ raise ๋“ฑ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜์— ์˜ํ•œ ์‹œ๊ทธ๋„์ด ์•„๋‹Œ SIGFPE, SIGILL, SIGSEGV ๋“ฑ์˜ ์‹œ๊ทธ๋„์— ๋Œ€ํ•ด์„œ๋Š” signal ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ ๋™์ž‘์„ ์ •์˜ํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด์™€ ๊ฐ™์€ ์‹œ๊ทธ๋„๋“ค์˜ ๋ฌด์‹œ ํ˜น์€ ์‚ฌ์šฉ์ž ์ •์˜๋Š” ์˜ค๋ฅ˜ ์ƒํ™ฉ์—์„œ๋„ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜์ง€ ์•Š์•„ ๋ฌธ์ œ ์ƒํ™ฉ ์†์—์„œ ๋ฌดํ•œํžˆ ์ง€์†๋˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

4. ์˜ˆ์‹œ

#include <signal.h> #include <stdbool.h> #include <unistd.h> void handler(int signum) { (void)signum; write(STDOUT_FILENO, "write From Signal\n", 18); } int main(void) { signal(SIGINT, handler); while(true) ; return (0); }
C

6. on <readline/readline.h>, <readline/history.h>

<readline/readline.h>์™€ <readline/history.h>์˜ ์ด๋ฆ„์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ, ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋ชจ๋‘ readline ๋””๋ ‰ํ† ๋ฆฌ์— ์†ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Mac OS X์—์„œ๋Š” ํ•ด๋‹น readline์ด๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋ฏ€๋กœ ์ด๋ฅผ ์ด์šฉํ•ด๋„ ๋œ๋‹ค.
Unix ๊ณ„์—ด์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” readline ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•œ ๋’ค ์ปดํŒŒ์ผ ํ•ด๋ณด๋ฉด, rl_replace_line๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์ปดํŒŒ์ผ์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” Unix ๊ณ„์—ด์˜ readline์€ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ๋งŒ ์ œ๊ณตํ•˜๊ณ , rl_replace_line๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  GNU Library๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. GNU Library์˜ readline์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๋“ค์€ ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
Mac OS X ๋ฒ„์ „์— ๋”ฐ๋ผ์„œ ์œ„ ํ•จ์ˆ˜ ๋ง๊ณ ๋„ ์—†๋Š” ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ปดํŒŒ์ผ ์‹œ์— -l, -L, -I ์˜ต์…˜์œผ๋กœ GNU Library์˜ readline์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ช…์‹œํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์ •ํ™•ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•œ ํ›„์—์•ผ ๋น„๋กœ์†Œ ๋ฌธ์ œ ์—†์ด ์ปดํŒŒ์ผ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์ผ GNU Library์—์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” readline์˜ ๊ธฐ๋Šฅ๋“ค์„ ์ด์šฉํ•  ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด, ์‹œ์Šคํ…œ์— ๋‚ด์žฅ๋œ readline์„ ์ด์šฉํ•˜๋ฉด์„œ ๋ณ„๋„์˜ ์ปดํŒŒ์ผ ์˜ต์…˜์„ ์ฃผ์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
Mac OS X์—์„œ๋Š” Xcode๋ฅผ ์„ค์น˜ํ•˜๋ฉด์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ GCC๊ฐ€ ํ•จ๊ป˜ ์„ค์น˜๋˜๊ธฐ ๋•Œ๋ฌธ์— GNU Library๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๊ณ  ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์ง€๋งŒ, ๋งŒ์ผ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๋ช…์‹œํ•œ GNU Library์˜ ์œ„์น˜๋ฅผ ์•„์˜ˆ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋ฉด ๋ณ„๋„๋กœ GNU Library์˜ readline์„ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Š” ์•„๋ž˜์— ๋ช…์‹œ๋œ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ ์‰ฝ๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
brew install readline
์œ„์™€ ๊ฐ™์ด GNU Library์˜ readline์„ ์ด์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผํ•  ์ ์ด ์žˆ๋‹ค. GNU Library์˜ readline์—์„œ๋Š” FILE์ด๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜๋Š”๋ฐ, ํ•ด๋‹น ๊ตฌ์กฐ์ฒด๋Š” <stdio.h>๋‚ด์— ์กด์žฌํ•œ๋‹ค. GNU Library์˜ <readline/readline.h>์— <stdio.h>๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ข‹๊ฒ ์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ GNU Library์˜ <readline/readline.h>๋ฅผ ํฌํ•จํ•˜๊ธฐ ์ „์— <stdio.h>์˜ ํฌํ•จ์ด ์„ ํ–‰๋˜์–ด์•ผ ํ˜ธ์ถœํ•˜๋ ค๋Š” ํ•จ์ˆ˜๋“ค์ด FILE ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ ˆํžˆ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1) readline

1. ์˜์กด์„ฑ

#include <readline/readline.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

char *readline (const char *prompt);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

readline ํ•จ์ˆ˜ ์ž์ฒด๋Š” get_next_line์œผ๋กœ ๊ตฌํ˜„ํ•œ ํ•จ์ˆ˜๋ฅผ ํ‘œ์ค€ ์ž…๋ ฅ์„ ๋Œ€์ƒ์œผ๋กœ ํ•œ ๊ธฐ๋Šฅ๊ณผ ๋น„์Šทํ•˜๋‹ค. ์ธ์ž๋กœ ๋ฐ›๋Š” prompt๋Š” ํ‘œ์ค€ ์ž…๋ ฅ์„ ๋ฐ›๊ธฐ ์ด์ „์— ๋ณด์—ฌ์ค„ ๋ฌธ๊ตฌ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. prompt์˜ ์ธ์ž๊ฐ€ ๋„ ๋ฌธ์ž์—ด์ด๊ฑฐ๋‚˜ NULL์ด๋ผ๋ฉด ๋ณ„๋„๋กœ ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. prompt๋กœ ์ด์šฉ๋˜๋Š” ๋ฌธ์ž์—ด์€ ๋‚ด๋ถ€์ ์œผ๋กœ ํ”„๋กฌํ”„ํŠธ ๊ฐ’์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์ด์šฉ๋œ๋‹ค.
get_next_line๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ˜ํ™˜๋˜๋Š” char * ํƒ€์ž…์˜ ๋ฌธ์ž์—ด์€ ๋™์  ํ• ๋‹น์„ ๋ฐ›์•„์„œ ์ƒ์„ฑ๋œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, readline์„ ํ˜ธ์ถœํ•œ ์‚ฌ์šฉ์ž์˜ ์ง์ ‘์ ์ธ free๊ฐ€ ๋’ท๋ฐ›์นจ ๋˜์–ด์•ผ ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ž…๋ ฅ์—์„œ ๊ฐœํ–‰ ๋ฌธ์ž๊นŒ์ง€์˜ ๋ฌธ์ž์—ด์„ readline์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด ๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ๋ฌธ์ž์—ด์—์„œ๋Š” ๊ฐœํ–‰ ๋ฌธ์ž๋Š” ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋งŒ์ผ ๊ณต๋ฐฑ ๋ฌธ์ž๋งŒ ์ž…๋ ฅ์„ ํ•œ ํ›„ ๊ฐœํ–‰ ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ์—๋Š” ๋„ ๋ฌธ์ž์—ด๋งŒ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
readline์˜ ๋ฐ˜ํ™˜ ๊ฐ’์—์„œ EOF์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” 2๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋‚˜๋‰œ๋‹ค. EOF๋ฅผ ๋งŒ๋‚ฌ์ง€๋งŒ ๊ทธ ์ „์— ์ฒ˜๋ฆฌํ•  ๋ฌธ์ž์—ด์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” NULL์ด ๋ฐ˜ํ™˜๋˜๊ณ , EOF๋ฅผ ๋งŒ๋‚ฌ์ง€๋งŒ ๊ทธ ์ „์— ์ฒ˜๋ฆฌํ•  ๋ฌธ์ž์—ด์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” EOF๋ฅผ ๊ฐœํ–‰ ๋ฌธ์ž์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ ์ ˆํžˆ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋™์ž‘ํ•œ๋‹ค.
readline ํ•จ์ˆ˜๊ฐ€ get_next_line ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋น„์Šทํ•˜๋‹ค๊ณ  ํ•œ ์ด์œ ๋Š”, readline์˜ ๊ธฐ๋Šฅ ์ค‘์—๋Š” vi ํ˜น์€ emacs์˜ Editing์„ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ EOF๋ฅผ ๋งŒ๋‚ฌ์„ ๋•Œ ์ฒ˜๋ฆฌํ•  ๋ฌธ์ž์—ด์ด ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„  ๋ฌธ์ž์—ด ์ž…๋ ฅ ํ›„ Ctrl + D๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•˜๋Š”๋ฐ, ํ•ด๋‹น ๊ฒฝ์šฐ์—๋Š” Ctrl + D๋ฅผ ์ž…๋ ฅํ•˜์—ฌ๋„ EOF๋กœ์จ ์ธ์‹์ด ์•ˆ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” readline์ด Editing ๋ฐฉ์‹์— ๋”ฐ๋ฅธ Key Binding์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
ํ•ด๋‹น ํ˜„์ƒ์„ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ๋งค๋‰ด์–ผ์„ ํ™•์ธํ•ด๋ณด๋ฉด, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์ œ์‹œ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. readline์—์„œ EOF๋ฅผ ์ž…๋ ฅํ•˜๊ธฐ ์œ„ํ•ด์„  ์•„๋ฌด๋Ÿฐ ๋ฌธ์ž๊ฐ€ ์—†์„ ๋•Œ Ctrl + D๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•˜๋ฉฐ, ๋ฌธ์ž๊ฐ€ ์กด์žฌํ•  ๋•Œ์˜ Ctrl + D๋Š” ๋ฌธ์ž ํ•˜๋‚˜๋ฅผ ์ง€์šฐ๋Š” Key Binding์œผ๋กœ์จ ๋™์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฌธ์ž์—ด์ด ์กด์žฌํ•  ๋•Œ EOF๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„  ๊ธฐ๋ณธ์ ์œผ๋กœ ์ •ํ•ด์ง„ ์„ค์ • ๊ฐ’์„ ๋”ฐ๋กœ ๋ฐ”๊ฟ”์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์„ค์ • ๊ฐ’์€ ~/.inputrc์—์„œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งŒ์ผ ํ•ด๋‹น ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด /etc/inputrc์—์„œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
๋‘ ํŒŒ์ผ ๋ชจ๋‘ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋ณ„๋„๋กœ ๋งŒ๋“ค์–ด์„œ ์šด์šฉํ•ด๋„ ๋œ๋‹ค. inputrc๋ผ๋Š” ํŒŒ์ผ์€ readline์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š”๋ฐ ์ด์šฉ๋˜๋Š” ํŒŒ์ผ์ด๋ฉฐ, ํ•ด๋‹น ํŒŒ์ผ์€ vimrc๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ต‰์žฅํžˆ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
readline์—์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” Key Binding์ด๋ผ๋“ ๊ฐ€, ์–ธ๊ธ‰๋œ ์„ค์ • ํŒŒ์ผ ๋‚ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Directive๋“ค์€ ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•˜์—ฌ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ์„œ ์ด๋“ค์„ ์ ์ ˆํžˆ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.
readline ํ•จ์ˆ˜์—์„œ๋Š” ํŠน์ • Editing์„ ์ง€์›ํ•œ๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ, Tab์„ ์ด์šฉํ•œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ํ•ด๋‹น ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์€ Oh-My-Zsh์™€ ๊ฐ™์€ ์ž๋™ ์™„์„ฑ ๋งŒํผ ๋›ฐ์–ด๋‚œ ์™„์„ฑ๋„๋ฅผ ๋ณด์—ฌ์ฃผ์ง€๋Š” ์•Š์ง€๋งŒ, ๊ธฐ๋ณธ ์‰˜์˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ๋งŒํผ์€ ๋ณด์žฅํ•ด์ค€๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ Customizing ํ•œ๋‹ค๋ฉด ์™„์„ฑ๋„ ๋†’์€ minishell์„ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•  ๊ฒƒ์ด๋‹ค.

2) rl_on_new_line

1. ์˜์กด์„ฑ

#include <readline/readline.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int rl_on_new_line(void)
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

rl_on_new_line ํ•จ์ˆ˜๋Š” readline ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ Update ๊ด€๋ จ ํ•จ์ˆ˜๋“ค์—๊ฒŒ ์ปค์„œ๊ฐ€ ๊ฐœํ–‰ ๋ฌธ์ž๋ฅผ ํ†ตํ•ด ๋‹ค์Œ ์ค„๋กœ ์ด๋™ํ–ˆ์Œ์„ ์•Œ๋ ค์ค„ ๋•Œ ์ด์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์•Œ๋ฆผ ์šฉ๋„์˜ ํ•จ์ˆ˜์ด๋ฏ€๋กœ ์ง์ ‘์ ์œผ๋กœ rl_on_new_line ํ•จ์ˆ˜๊ฐ€ ๊ฐœํ–‰ ๋ฌธ์ž๋ฅผ ์ˆ˜ํ–‰ํ•ด์ฃผ์ง€๋Š” ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ, rl_on_new_line ํ•จ์ˆ˜๋Š” ๊ฐœํ–‰ ๋ฌธ์ž ์ถœ๋ ฅ ์ดํ›„์— ์ด์šฉ๋œ๋‹ค.
Update ๊ด€๋ จ ํ•จ์ˆ˜๋กœ๋Š” rl_redisplay๋„ ํฌํ•จ๋œ๋‹ค.
rl_on_new_line์˜ ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

3) rl_replace_line

1. ์˜์กด์„ฑ

#include <readline/readline.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

void rl_replace_line(const char *text, int clear_undo)
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

rl_replace_line ํ•จ์ˆ˜๋Š” rl_line_buffer๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค. readline ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ ํ•จ์ˆ˜๋“ค์€ readline ๋””๋ ‰ํ† ๋ฆฌ๋กœ๋ถ€ํ„ฐ ์ „์—ญ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ๋ณ€์ˆ˜๋“ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด rl_line_buffer๋„ ์ด๋“ค ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ด ๋•Œ rl_line_buffer๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด์„ ๋ณ„๋„๋กœ ์œ ์ง€ํ•œ๋‹ค.
readline ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ ํ•จ์ˆ˜๋“ค์ด ์ด์šฉํ•˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
rl_replace_line ํ•จ์ˆ˜์˜ ์—ญํ• ์€ rl_line_buffer์— ์ž…๋ ฅ ๋ฐ›์€ ๋‚ด์šฉ์„ text๋ผ๋Š” ๋ฌธ์ž์—ด๋กœ ๋Œ€์น˜ํ•˜๋Š”๋ฐ ์žˆ๋‹ค. ์ด ๋•Œ clear_undo๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์œ ์ง€ ์ค‘์ธ undo_list๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ง€์˜ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ • ์ง“๋Š” ๊ฐ’์ด๋‹ค. clear_undo์˜ ๊ฐ’์ด 0์ด๋ผ๋ฉด ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š๊ณ , 0 ์ด์™ธ์˜ ๊ฐ’์ด๋ผ๋ฉด undo_list๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. rl_replace_line์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๋”ฐ๋กœ ์—†๋‹ค.
undo_list๋Š” readline ํ•จ์ˆ˜์—์„œ ์ง€์›ํ•˜๋Š” Editing ๊ธฐ๋Šฅ ์ค‘ Undo ์ž‘์—…์— ์ด์šฉ๋œ๋‹ค.
rl_replace_line์˜ ์‚ฌ์šฉ์€ ๋‹ค๋ฐฉ๋ฉด์—์„œ ์ด๋ค„์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, rl_line_buffer๋ฅผ Flushํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ•˜๋Š”๋ฐ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ํŠนํžˆ ํ•ด๋‹น ๊ฒฝ์šฐ์—๋Š” ์‹œ๊ทธ๋„์„ ๋ฐ›์•˜์„ ๋•Œ์˜ ์ƒํ™ฉ์—์„œ ์ด์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์˜ˆ์‹œ์—์„œ ๊ทธ ์‚ฌ์šฉ๋ฒ•์„ ์ •ํ™•ํžˆ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

4) rl_redisplay

1. ์˜์กด์„ฑ

#include <readline/readline.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

void rl_redisplay(void);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

rl_redisplay ํ•จ์ˆ˜ ์—ญ์‹œ rl_replace_line ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ rl_line_buffer๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค. rl_redisplay ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜์—ฌ ์œ ์ง€ ์ค‘์ธ rl_line_buffer์˜ ๊ฐ’์„ ํ”„๋กฌํ”„ํŠธ์™€ ํ•จ๊ป˜ ์ถœ๋ ฅํ•ด์ค€๋‹ค. ์ด ๋•Œ ํ”„๋กฌํ”„ํŠธ ๊ฐ’์€ readline ํ•จ์ˆ˜์— prompt๋กœ ์ค€ ๋ฌธ์ž์—ด๋กœ ์ด์šฉ๋œ๋‹ค.
ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด readline ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์— ์กด์žฌํ•˜๋Š” ํŠน์ • ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ minishell์—์„œ๋Š” ํ”„๋กฌํ”„ํŠธ ์„ค์ • ๊ด€๋ จํ•œ ํ•จ์ˆ˜๋“ค์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹ฌํ•˜์ž.
rl_redisplay ํ•จ์ˆ˜์—์„œ๋Š” ๋ณ„๋„๋กœ ๋ฐ›๋Š” ์ธ์ž๋„ ์—†๊ณ  ๋ณ„๋„์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์žˆ๋Š” ๊ฒƒ๋„ ์•„๋‹Œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์— ๋”ฐ๋ผ readline ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์—์„œ๋Š” rl_redisplay๋ฅผ ์™œ ์ด์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ ๋  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ์ฃผ๋กœ ์‹œ๊ทธ๋„์„ ๋ฐ›์•˜์„ ๋•Œ์˜ ์ƒํ™ฉ์—์„œ rl_redisplay๋ฅผ ์ด์šฉํ•œ๋‹ค. ์ด์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์˜ˆ์‹œ์—์„œ ๊ทธ ์‚ฌ์šฉ๋ฒ•์„ ์ •ํ™•ํžˆ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

5) add_history

1. ์˜์กด์„ฑ

#include <readline/history.h>
C

2. ํ•จ์ˆ˜ ์›ํ˜•

int add_history(const char *line); void add_history(const char *line);
C

3. ํ•จ์ˆ˜ ์„ค๋ช…

add_history๋Š” readline ํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ ๋™์ž‘ ์ค‘์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ–ˆ๋˜ ๋ฌธ์ž์—ด์„ ๋‹ค์‹œ ์–ป๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค. add_history์˜ ์ธ์ž์ธ line์œผ๋กœ ๊ธฐ์žฌํ•œ ๋ฌธ์ž์—ด์€ ์œ„์™€ ์•„๋ž˜ ๋ฐฉํ–ฅํ‚ค๋ฅผ ํ†ตํ•ด์„œ readline ํ•จ์ˆ˜ ์‹คํ–‰ ๋„์ค‘์— ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
Unix ๊ณ„์—ด์—์„œ ๋‚ด์žฅ๋œ readline ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” int ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋งŒ๋“œ๋Š”๋ฐ, ํ•จ์ˆ˜ ์ˆ˜ํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์ผ Unix ๊ณ„์—ด์— ๋‚ด์žฅ๋œ readline ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ GNU Library์˜ readline ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ด์šฉํ•œ๋‹ค๋ฉด, ์ด์ „๊ณผ ๋‹ฌ๋ฆฌ void ํƒ€์ž…์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” readline์˜ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์–ด๋–ค ๊ฒƒ์ธ์ง€ ์ •ํ™•ํžˆ ํ™•์ธ ํ›„์— ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

6) ์˜ˆ์‹œ

readline ๋””๋ ‰ํ† ๋ฆฌ์˜ ์˜ˆ์‹œ๋Š” ๊ฐ ํ•จ์ˆ˜ ๋ณ„๋กœ ๋“œ๋Š” ๊ฒƒ๋„ ์ข‹๊ฒ ์ง€๋งŒ, readline ํ•จ์ˆ˜์™€ add_history ํ•จ์ˆ˜๋งŒ ์ด์šฉํ•˜์—ฌ ์˜ˆ์‹œ๋ฅผ ์ž‘์„ฑํ•ด๋ณผ ๊ฒƒ์ด๋‹ค. ์˜ˆ์‹œ์—์„œ๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋ฐ›์€ ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•˜๊ณ , ์œ„์™€ ์•„๋ž˜ ๋ฐฉํ–ฅํ‚ค๋ฅผ ํ†ตํ•ด ์ด์ „์— ์ž…๋ ฅ ๋ฐ›์•˜๋˜ ๋ฌธ์ž์—ด์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์‹ค์ œ ์‰˜์—์„œ Ctrl + C๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์˜ˆ์‹œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋„ ์ด์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก rl_on_new_line๊ณผ rl_replace_line, rl_redisplay ํ•จ์ˆ˜๋“ค์„ ์ ์ ˆํžˆ ์ด์šฉํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.
#include <signal.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <readline/readline.h> #include <readline/history.h> #include <unistd.h> void handler(int signum) { if (signum != SIGINT) return ; write(STDOUT_FILENO, "\n", 1); if (rl_on_new_line() == -1) exit(1); rl_replace_line("", 1); rl_redisplay(); } int main(void) { int ret; char *line; signal(SIGINT, handler); while (true) { line = readline("input> "); if (line) { ret = strcmp(line, "bye"); if (ret) printf("output> %s\n", line); add_history(line); free(line); line = NULL; if (!ret) break ; } else return (1); } return (0); }
C

7. Approach

์•„์‰ฝ๊ฒŒ๋„ ๊ฝค๋‚˜ ๊ท€์ฐฎ์€ ๊ณผ์ œ์˜€๊ณ , ์–ด์„œ ๋งˆ์น˜๊ณ  ์‹ถ์€ ๋งˆ์Œ์ด ์ปค์„œ ใ…Žใ…Žใ…Ž... ๊ฐ„๋‹จํ•˜๊ฒŒ๋งŒ ๊ธฐ๋กํ•˜๊ฒ ๋‹ค.

1) Cooperation

๋ฉ”์ธ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” bigpel66/42-cursus ๋ฅผ ์ด์šฉํ•˜์˜€๊ณ , ํŒ€์›์€ GitHub์˜ Issue์™€ Pull Request ํ˜•์‹์œผ๋กœ ์ฝ”๋“œ์— ๊ธฐ์—ฌํ–ˆ๋‹ค. Pull Request๋ฅผ ๋จธ์ง€ํ•˜๊ธฐ ์ด์ „์—๋Š” ๋ฐ˜๋“œ์‹œ GitHub ๊ธฐ๋Šฅ์œผ๋กœ ์ง€์›ํ•˜๋Š” ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์›์น™์œผ๋กœ ํ•˜์˜€๋‹ค.
ํ˜‘์—… ๊ธฐ๊ฐ„์ด ๊ธธ์ง€๋Š” ์•Š์•˜์ง€๋งŒ ํŒ€์›์ด ์ง„๋„๋ฅผ ์ซ’์•„์˜ค๋Š” ๊ณต๋ฐฑ๊ธฐ ๋™์•ˆ ๊ตฌ์กฐ๋ฅผ ์˜ค๋ž˜ ๊ณ ๋ฏผํ•œ ๋•์ธ์ง€, ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ ๋ฐ ์ž๋ฃŒ ํ˜•ํƒœ์˜ ๊ฒฐ์ •๊ณผ ๋ถ„ํ• ์€ ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š์•˜๋‹ค.
ํŠนํžˆ Makefile์˜ ๊ฒฝ์šฐ GNU์˜ readline์„ ์ด์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๊ฒƒ์ด ํŒ€์›๊ณผ์˜ ๊ฒฝ๋กœ์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ํ™˜๊ฒฝ ์—ญ์‹œ ๊ฒฝ๋กœ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ด๋Š” ํ˜„์žฌ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ๋Š” ์ง€์›Œ์กŒ์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•˜์—ฌ make MODE=$(NAME) ๋ช…๋ น์–ด๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.
MODE = EVAL LIB_NAME = readline ifeq ($(MODE), EVAL) LIB_HEADER = /Users/jseo/.brew/Cellar/readline/8.1.1/include/ else ifeq ($(MODE), HYSON) LIB_HEADER = /Users/hyson/.brew/Cellar/readline/8.1.1/include/ else ifeq ($(MODE), JSEO) LIB_HEADER = /usr/local/opt/readline/include/ endif ifeq ($(MODE), EVAL) LIB_FOLDER = /Users/jseo/.brew/Cellar/readline/8.1.1/lib/ else ifeq ($(MODE), HYSON) LIB_FOLDER = /Users/hyson/.brew/Cellar/readline/8.1.1/lib/ else ifeq ($(MODE), JSEO) LIB_FOLDER = /usr/local/opt/readline/lib/ endif %.o : %.c @echo $(YELLOW) "Compiling...\t" $< $(EOC) $(LINE_CLEAR) @$(CC) $(CFLAGS) -I $(HEADER) -o $@ -c $< -I $(LIB_HEADER) $(NAME) : $(OBJ) @echo $(GREEN) "Source files are compiled!\n" $(EOC) @echo $(WHITE) "Building $(NAME) for" $(YELLOW) "Mandatory" $(WHITE) "..." $(EOC) @$(CC) $(CFALGS) -I $(HEADER) -o $(NAME) $(OBJ) -I $(LIB_HEADER) -l $(LIB_NAME) -L $(LIB_FOLDER) @echo $(GREEN) "$(NAME) is created!\n" $(EOC)
Plain Text
์œ„ Makefile์€ ์ผ๋ถ€ ๋ฐœ์ทŒํ•œ ๊ฒƒ์ด๊ณ , ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ํ‰๊ฐ€๋ฅผ ๋ฐ›์„ ๋•Œ๋Š” brew๋ฅผ ์ด์šฉํ•˜์—ฌ readline์„ ์„ค์น˜ ํ›„์— install_name_tool์„ ์ด์šฉํ•˜์—ฌ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์žก์•„์ฃผ๋Š” ์‹์œผ๋กœ ๋™์ž‘์‹œ์ผฐ๋‹ค.
install_name_tool ๋“ฑ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด์šฉ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด, ์•„๋ž˜ ๋งํฌ์—์„œ install_name_tool์„ ๊ฒ€์ƒ‰ํ•ด๋ณด์ž.

2) Implementation

์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ ํฌ๊ฒŒ 2๊ฐœ ์ •๋„ ์ผ๋‹ค. ์ฒซ ์งธ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ €์žฅ์„ ์œ„ํ•œ RB Tree, ๋‘˜ ์งธ๋Š” ๋ช…๋ น์–ด ์‹คํ–‰์„ ์œ„ํ•œ AS Tree์ด๋‹ค.
์ผ์ „์— push_swap ๊ณผ์ œ์—์„œ๋„ RB Tree๋ฅผ ์ด์šฉํ•˜์—ฌ Set์„ ๊ตฌํ˜„ํ•œ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ, ๊ฐœ์ธ์ ์œผ๋กœ ๋งŽ์ด ์•„์‰ฌ์› ๋˜ ์ ์ด ๋‚จ์•„ ์žˆ์—ˆ๋‹ค. Delete ๋กœ์ง์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜๋˜ ์ ์ด๋ผ๋“ ๊ฐ€, โ†’ ๊ฐ€ ๋‚œ๋ฌดํ•ด์„œ ๊ฒฐ๊ตญ์— ๋‚˜์ค‘์—๋Š” ์Šค์Šค๋กœ๋„ ์•Œ์•„๋ณด๊ธฐ ํž˜๋“ค์–ด์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์•ˆ ๋œ๋‹ค๋Š” ์ ์ด๋ผ๋“ ๊ฐ€ ๋ง์ด๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ์ธ์ ์ธ ์š•์‹ฌ์œผ๋กœ RB Tree๋ฅผ ์ด์šฉํ•œ ์ ๋„ ์žˆ์—ˆ๊ณ , ์‚ฌ์‹ค ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์ „์ฒด ๋ชฉ๋ก์„ ์ถœ๋ ฅํ•˜๋Š” ํšŸ์ˆ˜๋ณด๋‹ค ํŠน์ • ๊ฐ’์„ ์ฐพ์•„๋‚ด๋Š” ํ–‰์œ„๊ฐ€ ๋” ๋งŽ์„ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜์—ฌ ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ๋„ ์žˆ์—ˆ๋‹ค. ์ „์ฒด ๋ชฉ๋ก์„ ์ถœ๋ ฅํ•˜๋Š” ๋ฐ์—๋Š” ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ ์‹œ O(n)O(n)์ด๋ฉด ๋˜์ง€๋งŒ, RB Tree๋Š” ์ค‘๋ณต ๋…ธ๋“œ ํƒ์ƒ‰ ๋•Œ๋ฌธ์— O(nlogn)O(nlogn)์„ ์š”๊ตฌํ•œ๋‹ค. ๋ฐ˜๋ฉด์— ํŠน์ • ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ O(n)O(n)์„ ์š”๊ตฌํ•˜์ง€๋งŒ, RB Tree์—์„œ๋Š” O(logn)O(logn)์ด๋ฉด ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ „์ฒด ํƒ์ƒ‰์—์„œ ์กฐ๊ธˆ ์†ํ•ด๋ฅผ ๋ณด๋”๋ผ๋„ ๋นˆ๋„๊ฐ€ ๋” ๋†’์€ ๋ช…๋ น์–ด์—์„œ ๋“์„ ๋ณด๊ธฐ ์œ„ํ•ด์„œ RB Tree๋ฅผ ์ด์šฉํ•˜๊ธฐ๋ก ํ–ˆ๋‹ค.
์ง€๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋ฆฌ์ŠคํŠธ๋กœ๋„ RB Tree๋กœ๋„ ์œ ์ง€ํ•ด์„œ ์ „์ฒด ํƒ์ƒ‰์—๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ, ํŠน์ • ๋…ธ๋“œ ํƒ์ƒ‰์—๋Š” RB Tree๋ฅผ ์“ฐ๋„๋ก ๋‘๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.
์ „์ฒด์ ์ธ ์ง„ํ–‰์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ ๋Œ€์น˜ (Expand) โ†’ ๋ฉ์–ด๋ฆฌ ๋‚˜๋ˆ„๊ธฐ (Tokenize) โ†’ AS Tree ํ˜•ํƒœ๋ฃจ ์ง„ํ–‰์ด ๋˜๋Š”๋ฐ, ๋งจ๋ฐํ† ๋ฆฌ ์ƒ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ ๋ณด๋„ˆ์Šค์˜ &&, || ๋“ฑ์„ ๊ณ ๋ คํ•˜๋ฉด Tokenize โ†’ AS Tree โ†’ Expand ์ˆœ์ด ์—ฃ์ง€ ์ผ€์ด์Šค์— ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜์ค‘์—์„œ์•ผ ์•Œ๊ฒŒ ๋œ ์ ์€ ์ •๋ง ์•„์‰ฌ์› ๋‹ค.
AS Tree๋ฅผ ๋„์ž…ํ•œ ์ด์œ ๋Š” ๋‹ค๋ฅธ ์‰˜๋“ค์ด ์ด๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์ด์–ด์„œ ๊ฒฝํ—˜์„ ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๊ณ , ํŠน์ด Syntax Parsing์— ๊ต‰์žฅํžˆ ์šฉ์ดํ•˜๋‹ค๊ณ  ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„๋ช… ์ถ”ํ›„์— ๊ฒช์„ ์—ฌ๋Ÿฌ ๋‚œํ•ดํ•œ ์—ฃ์ง€ ์ผ€์ด์Šค๋“ค๋กœ๋ถ€ํ„ฐ ๋Œ€์ฒ˜๊ฐ€ ๊ทธ๋‚˜๋งˆ ์‰ฝ์ง€ ์•Š์„๊นŒ ํ•˜๋Š” ์ƒ๊ฐ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์—ฌ๋Ÿฌ ์ผ€์ด์Šค๋“ค ์ค‘ Redirection๊ณผ Pipe์˜ ์กฐํ•ฉ์—์„œ ๊ฒฐ๊ตญ์— ๋“์„ ๋ณด์•˜๋‹ค.
์ฝ”๋“œ๋“ค ๋Œ€๋ถ€๋ถ„์€ ์žฌ๊ท€ ๊ตฌ์กฐ๋ฅผ ๋„๊ณ  ์žˆ์–ด์„œ ์ฒ˜์Œ์—๋Š” ๊ตฌํ˜„์ด ๊ฝค๋‚˜ ๊นŒ๋‹ค๋กœ์› ์ง€๋งŒ, ์‹œ๊ฐ„ ์ง€๋‚˜๊ณ  ๋ณด๋‹ˆ ๊ฝค๋‚˜ ๊ดœ์ฐฎ์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๋‚จ๋“ค ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๋ฆฌ๋ทฐ, ๋””๋ฒ„๊น… ๋“ฑ์—์„œ๋„ ํฌ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๋Š”๋ฐ, ์ด๋Š” ์ฃผ์„, ๋‹จ์–ธ, ๊ตฌ์กฐ์—์„œ ๋“์„ ๋ดค๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.
์ด๋ฒˆ๋งŒํผ์€ ํŒ€์›๊ณผ ์ง„ํ–‰์„ ํ•˜๋Š” ๊ณผ์ œ์˜€๊ธฐ ๋•Œ๋ฌธ์—, ์ฃผ์„ ์Šคํƒ€์ผ์„ ์ •ํ•˜์—ฌ ๊ผผ๊ผผํžˆ ๊ธฐ๋กํ•˜๋„๋ก ๊ทœ์น™์„ ์ •ํ–ˆ๋‹ค. ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ๋“ค์–ด๊ฐ€๋ณด๋ฉด ๋งค ํ•จ์ˆ˜๋งˆ๋‹ค ์ฃผ์„์„ ๋‹ฌ์•„๋‘์—ˆ๊ณ , ์–ด๋–ค ๋ชฉ์ ์˜ ํ•จ์ˆ˜์ธ์ง€, ๋ฐ˜ํ™˜ ๊ฐ’์€ ๋ฌด์—‡์ธ์ง€, ์ธ์ž๋“ค์€ ๋ฌด์—‡์ธ์ง€ ๋“ฑ์„ ๋นผ๋†“์ง€ ์•Š๊ณ  ๊ธฐ๋กํ•˜๋„๋ก ์ •ํ–ˆ๋‹ค.
๋‹จ์–ธ์— ๋Œ€ํ•ด์„œ๋Š” assert๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ด์šฉํ•˜์˜€๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์ธ ์ฝ”๋”ฉ์—์„œ ์ด์šฉํ•˜๋Š” assert์™€ ์ตœ๋Œ€ํ•œ ๋™์ผํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜์—ฌ ์ด์šฉํ–ˆ๋‹ค. assert๋ฅผ ์ด์šฉํ•˜๋ฉด์„œ ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹์œผ๋กœ ๋กœ์ง์„ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.
1.
๊ตฌํ˜„ ์ƒ ๋™์ ํ• ๋‹น ํšŸ์ˆ˜๊ฐ€ ๊ฝค ๋˜๋Š” ํŽธ์ธ๋ฐ, ๋งค ์ˆœ๊ฐ„๋งˆ๋‹ค ์ด๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  bool๋กœ ๋ฐ˜ํ™˜ ๋ฐ›๊ณ  fallback์„ ํ•˜๋Š” ๊ณผ์ •์ด ๋ฐ”๋žŒ์งํ•˜์ง€๋Š” ์•Š๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋˜์—ˆ๋‹ค.
2.
์ „๋ฐ˜์ ์ธ ๋กœ์ง๋“ค์€ NULL Safety๋ฅผ ๋ณด์žฅํ•˜๋„๋ก (NULL์— ์•ˆ์ „ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก) ๋งŒ๋“ค์—ˆ๋‹ค.
3.
๋‹ค์Œ ๋กœ์ง์— ์š”๊ตฌ๋˜๋Š” ๊ฐ’๋“ค์˜ ๊ฒฝ์šฐ, ์ด์ „ ๋กœ์ง์—์„œ NULL์ด ๋‚˜์™”์„ ๋•Œ ์ด๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ์‹์œผ๋กœ assert๋ฅผ ์ด์šฉํ•˜์˜€๋‹ค.
๋”ฐ๋ผ์„œ ์•„๋ž˜์€ ์ฝ”๋“œ์—์„œ ๊ตฌํ˜„ ํ˜น์€ ๋””๋ฒ„๊น…์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด mini_assert ํ•จ์ˆ˜์—์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ ์‹œํ‚ค๊ณ  ์–ด๋–ค ํŒŒ์ผ, ์–ด๋–ค ๋ผ์ธ, ์–ด๋–ค ํ•จ์ˆ˜์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์–ด ๊ฝค๋‚˜ ๋งŽ์€ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ–ˆ๋‹ค.
/* ** loop () - Main Runtime Function of Minishell ** ** return - void ** input - Variable for a User Input ** chunks - Variable for Tokens of User Input ** syntax - Variable for a Syntax Tree from Chunks ** envmap - Variable for Maps the Environment Variables */ void loop(char *input, t_lst *chunks, t_as *syntax, t_rb *envmap) { while (true) { jfree((void **)(&input)); input = readline(get_value(envmap, "PS1")); if (input == NULL) { jputendl("exit", STDOUT_FILENO); exit(VALID); } if (!jstrlen(input) || empty(input)) continue ; add_history(input); if (!quotes(input) && set_rl(input, QUOTES, STDERR_FILENO, false)) continue ; input = expand(input, envmap, false); mini_assert(input != NULL, \ MASSERT "(input != NULL), " LOOP MLOOP_FILE "line 60."); tokenize(input, &chunks); mini_assert(chunks != NULL, \ MASSERT "(chunks != NULL), " LOOP MLOOP_FILE "line 64."); execute(chunks, syntax, envmap); jlstclear(&chunks, jfree); } }
C
assert๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ ๋˜์—ˆ๋‹ค.
/* ** mini_assert () - Assert Whether Condition True or False ** ** return - void ** condition - Condition to Check ** context - Context Information in Runtime */ void mini_assert(bool condition, char *context) { if (condition) return ; jputendl(context, STDERR_FILENO); exit(GENERAL); }
C
ํŠนํžˆ ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ๋Š” ์ตœ๋Œ€ํ•œ ์˜์กด๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ๊ฐ๊ฐ์˜ ๊ธฐ๋Šฅ๋“ค์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ–ˆ๋‹ค. ์ด ๋•๋ถ„์— ํ˜‘์—… ์‹œ ์„œ๋กœ์˜ ์˜์กด๋„๋ฅผ ๋งŽ์ด ๋‚ฎ์ถ”๋Š”๋ฐ ๋„์›€์ด ๋˜์—ˆ๋‹ค. ์ด๋Š” ๊ตฌํ˜„์— ํ•„์š”ํ•œ ๊ฒƒ๋“ค์„ ์‚ฌ์ „์— ์ •์˜ํ•ด๋ณด๊ณ  ์˜์‚ฌ ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ์ž‘์„ฑํ•ด๋ดค๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ์ด์— ๋”ฐ๋ผ ์šฐ๋ฆฌ ํŒ€์€ ์•„๋ž˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด 5๊ฐœ์˜ include ๋“ค์„ ์ด์šฉํ•˜์˜€๋‹ค.
์ถ”๊ฐ€์ ์œผ๋กœ๋Š” ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ๋“ค์„ ์ง์ ‘ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํฐ ๋„์›€์ด ๋  ๊ฒƒ ๊ฐ™์•„์„œ, ์œ„์˜ ๊ฐ ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋””๋ฒ„๊น… ํ•จ์ˆ˜๋“ค์„ ์—ฌ๋Ÿฟ ๋งŒ๋“ค์–ด๋‘์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ช…๋ น์–ด๋ฅผ ํ•˜๋‚˜ ์น˜๋”๋ผ๋„, ๋ˆˆ์œผ๋กœ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ํŒ€์—์„œ ๋งŒ๋“ค์–ด๋‚ธ ๊ตฌ์กฐ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ ์ง€์†์ ์œผ๋กœ ํ™•์ธํ•˜๋ฉฐ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค. ๋•๋ถ„์— ์—ฃ์ง€ ์ผ€์ด์Šค์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋”๋ผ๋„ ํ™•์ธ์ด ๋นจ๋ž์œผ๋ฉฐ, AS Tree ๋•๋ถ„์— ์ด๋ฅผ ๊ณ ์น˜๋Š” ๊ฒƒ๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
๋น„๋ก ์•„์‰ฌ์šด ์ ๋„ ๋ช‡ ์žˆ์—ˆ๊ณ , ๊ตฌํ˜„ํ•˜๋ฉด์„œ ์–ด๋ ค์› ๋˜ ์ ๋“ค๋„ ๋งŽ์•˜์ง€๋งŒ ์ถฉ๋ถ„ํžˆ ์ข‹์€ ํ˜‘์—…์ด์—ˆ๊ณ  Inner Circle์˜ ๋งˆ์ง€๋ง‰ C ์–ธ์–ด ์ฝ”๋”ฉ์œผ๋กœ๋Š” ์ฉ ๋‚˜์˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค. GitHub Issue + Pull Request + Code Review๋Š” ์ •๋ง ์žฌ๋ฐŒ๋Š” ๊ธฐ๋Šฅ์ด์—ˆ๋‹ค.
์ •๋ฆฌํ•˜๋ฉด์„œ stat, lstat, fstat ์–˜๊ธฐ๋“ค์ด ๋น ์ง„ ๊ฒƒ์„ ๋’ค๋Šฆ๊ฒŒ ํ™•์ธํ–ˆ๋Š”๋ฐ, ์ด๋“ค์€ ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ต์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง์ ‘ ์ฐพ์•„๋ณด๊ธธ ๊ถŒํ•œ๋‹ค ใ…Žใ…Ž...

8. Reference

ncurses๋ฅผ ๊ฐ„๋‹จํžˆ ์•Œ์•„๋ณด๊ธฐ
์˜ค๋Š˜์€ ํ„ฐ๋ฏธ๋„ ๊ทธ๋ž˜ํ”ฝ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ NCURSES๋ฅผ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์œ„ํ‚ค๋ฐฑ๊ณผ์— ๋”ฐ๋ฅด๋ฉด ncurses๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ TUI๋ฅผ ํ„ฐ๋ฏธ๋„ ๋…๋ฆฝ ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ๋„๋ก API๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ปค์„œ๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ‚ค๋ณด๋“œ, ๋งˆ์šฐ์Šค๋กœ ์‰ฝ๊ฒŒ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ ํŽธ๋ฆฌํ•˜๋„๋ก ์ฐฝ์˜ ํฌ๊ธฐ๋‚˜ ์ƒ‰์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณธ๋ž˜ ncurses๋Š” Cursor optimization์—์„œ ์œ ๋ž˜ํ•˜๋ฉฐ ์œ ๋‹‰์Šค ๊ณ„์—ด ์šด์˜์ฒด์ œ๋ฅผ ์œ„ํ•œ ์ œ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ํ•˜๋‚˜์˜€์œผ๋‚˜ 1990๋…„๋Œ€ ์ค‘๋ฐ˜์— curses๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐœ๋ฐœ์ด ์ค‘๋‹จ๋œ ํ›„ GNU์—์„œ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค.
[C-๋„คํŠธ์›Œํฌ] ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์Šค fork() - 2 (์‹œ๊ทธ๋„ ํ•ธ๋“ค๋ง)
์•ˆ๋…•ํ•˜์„ธ์š”, ์ญ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—” c์–ธ์–ด๋กœ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š”๋ฐ, ์‹œ๊ทธ๋„์„ ์ด์šฉํ•œ ๊น”๋”ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด๋ด…์‹œ๋‹ค. ์‹œ๊ทธ๋„(Signal)์ด ๋ญ์ฃ ? ์‹œ๊ทธ๋„์€ ํŠน์ • ์ƒํ™ฉ์ด ๋˜์—ˆ์„๋•Œ, ์šด์˜์ฒด์ œ(OS)๊ฐ€ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ํ•ด๋‹น ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ์ผ์ข…์˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค์€ ์šฐ๋ฆฌ์˜ ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰๋˜๋Š” ๋„์ค‘, OS๋กœ ๋ถ€ํ„ฐ ๊ฐ์ข… ์‹œ๊ทธ๋„์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๊ทธ ์‹œ๊ทธ๋„๋“ค ์ค‘์—์„œ๋Š” ๋„์ฐฉํ•ด๋„ ๋ฌด์‹œ๊ฐ€๋˜๋Š”(ํ”„๋กœ์„ธ์Šค๋Š” ์•„๋ฌด๋Ÿฐ ๋ฐฉํ•ด์—†์ด ํ•˜๋˜์ž‘์—…์„ ๊ณ„์†) ์‹œ๊ทธ๋„๋„ ์žˆ๊ณ , ํ”„๋กœ์„ธ์Šค์˜ ์ข…๋ฃŒ๋ฅผ ๋™์ž‘์‹œํ‚ค๋Š” ์‹œ๊ทธ๋„๋“ค(๋Œ€ํ‘œ์ ์œผ๋กœ ctrl+c ๋กœ ๊ฐ•์ œ์ข…๋ฃŒ) ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

9. Code of Jseo