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 ๋ฑ ํฐ๋ฏธ๋๊ณผ ๊ด๋ จ๋ ์ถ๊ฐ์ ์ธ ์ ๋ณด๋ ์๋ ๋งํฌ์์ ์ป์ ์ ์๋ค.
์ ๋ฆฌํด๋ณด๋ฉด, ์ฌ์ฉ์ ์ดํ๋ฆฌ์ผ์ด์
์ด ์ํ๋ ์์
์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋ด์ ์ด์์ฒด์ ๊ฐ 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์ ๊ฐ์ ์๊ฒฉ ํต์ ์ ์ํฉ์ ํตํด ์กฐ๊ธ ๋ ์ฝ๊ฒ ์ดํดํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ์ด๋ค ํ๋ก๊ทธ๋จ์ด ์คํ๋๊ณ ์๋ ํ๊ฒฝ์ ๋ผ๊ณ ํ๊ณ , ์ด๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ๊ฒฝ์ ๋ผ๊ณ ํด๋ณด์. ์ฆ, ํ๊ฒฝ์์ ssh๋ฅผ ํตํด ํ๊ฒฝ์์ ํ๋ก๊ทธ๋จ์ ์คํํ๊ณ ์๋ ๊ฒ์ด๋ค. ์ฌ์ฉ์ ์ดํ๋ฆฌ์ผ์ด์
์ด ํฐ๋ฏธ๋๊ณผ ์ํธ์์ฉ์ ํ๊ณ ์๋ ํ๊ฒฝ์ ์ด๋ฏ๋ก, ํ๊ฒฝ์์ ์ ์ด๋ฅผ ํ๊ณ ์๋ ์ํฉ์์ ์ ์ ํ TermCap์ ์ด์ฉํ๊ณ ์ ํ๋ค๋ฉด ํ๊ฒฝ์ ์ํธ๋ฆฌ ์ญ์ ๊ฐ๊ณ ์์ด์ผ ํ๋ค. ๋ฐ๋ผ์ ์๊ฒฉ ํต์ ์์์๋ ๋ ํฐ๋ฏธ๋์ ํ์
์ ๋์ผํ๊ฒ ๋ง์ถ ํ์๊ฐ ์๋๋ฐ, 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๋ฅผ ์ด์ฉํ ์ ๋ ์์๊ณ , ์ฌ์ค ํ๊ฒฝ ๋ณ์ ์ ์ฒด ๋ชฉ๋ก์ ์ถ๋ ฅํ๋ ํ์๋ณด๋ค ํน์ ๊ฐ์ ์ฐพ์๋ด๋ ํ์๊ฐ ๋ ๋ง์ ๊ฒ์ผ๋ก ์๊ฐํ์ฌ ์ด๋ฅผ ๊ตฌํํ ๊ฒ๋ ์์๋ค. ์ ์ฒด ๋ชฉ๋ก์ ์ถ๋ ฅํ๋ ๋ฐ์๋ ๋ฆฌ์คํธ๋ก ๊ตฌํ ์ ์ด๋ฉด ๋์ง๋ง, RB Tree๋ ์ค๋ณต ๋
ธ๋ ํ์ ๋๋ฌธ์ ์ ์๊ตฌํ๋ค. ๋ฐ๋ฉด์ ํน์ ๋
ธ๋๋ฅผ ์ฐพ์ ๋๋ ๋ฆฌ์คํธ์์ ์ ์๊ตฌํ์ง๋ง, RB Tree์์๋ ์ด๋ฉด ์ถฉ๋ถํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ์ ์ฒด ํ์์์ ์กฐ๊ธ ์ํด๋ฅผ ๋ณด๋๋ผ๋ ๋น๋๊ฐ ๋ ๋์ ๋ช
๋ น์ด์์ ๋์ ๋ณด๊ธฐ ์ํด์ 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 ์๊ธฐ๋ค์ด ๋น ์ง ๊ฒ์ ๋ค๋ฆ๊ฒ ํ์ธํ๋๋ฐ, ์ด๋ค์ ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์ผ๋ฏ๋ก ์ง์ ์ฐพ์๋ณด๊ธธ ๊ถํ๋ค ใ
ใ
...