다음 이전 차례

11. 세번째 예: Fortune

이 예는 C 프로그래밍에 대한 지식이 조금 필요하다. 유닉스나 리눅스용 소프트웨어의 많은 부분이 C로 쓰여져 있으므로, 소프트웨어 설치에 대해서 진지한 사람이라면 최소한 조금은 C를 배워두는 것이 좋다.

악명높은 fortune 프로그램은 리눅스가 뜰 때마다 "fortune cookie"라고 불리는 재미있는 격언을 보여준다. 불행하게도(unfortunately, 발음갖고 농담하는 거다), 2.0.30 커널을 사용하는 레드 햇 배포판에서 fortune을 컴파일하려고 하면 심각한 에러가 생긴다.

~/fortune# make all


gcc -O2 -Wall -fomit-frame-pointer -pipe   -c fortune.c -o
fortune.o
fortune.c: In function `add_dir':
fortune.c:551: structure has no member named `d_namlen'
fortune.c:553: structure has no member named `d_namlen'
make[1]: *** [fortune.o] Error 1
make[1]: Leaving directory `/home/thegrendel/for/fortune/fortune'
make: *** [fortune-bin] Error 2

fortune.c를 살펴보면, 해당되는 줄은 다음과 같다.

   if (dirent->d_namlen == 0)
            continue;
        name = copy(dirent->d_name, dirent->d_namlen);

우리는 dirent라는 구조체를 찾아야 하지만, 이 구조체는 fortune.c 안에 선언되어 있지 않으며, grep dirent를 해봐도 다른 소스 파일들에서도 찾을 수 없다. 하지만, fortune.c의 제일 위에 다음과 같은 줄이 있다.

#include <dirent.h>

이것은 시스템 라이브러리의 include 파일로 보이므로, dirent.h를 찾을 논리적인 위치는 /usr/include 다. 실제로 /usr/include에는 dirent.h 파일이 있지만, 그 파일은 dirent 구조체의 정의를 포함하고 있지 않다. 이 파일은 그 대신 또다른 dirent.h 파일을 참조하고 있다.

#include <linux/dirent.h>

마침내, /usr/include/linux/dirent.h에서, 바라던 구조체 선언을 찾았다.

struct dirent {
        long            d_ino;
        __kernel_off_t  d_off;
        unsigned short  d_reclen;
        char            d_name[256]; /* We must not include limits.h! */
};

물론 이 구조체 선언은 d_namelen 을 포함하고 있지 않지만, 그에 해당될 만한 "후보"는 두 개 있다. 가장 그럴 듯 한 것은 d_reclen인데, 이 구조체 멤버는 무엇인가의 길이를 나타내는 것 같고 또 short integer 형이기 때문이다. 또 하나의 가능성은, d_ino인데 그 이름과 자료형으로 보아 inode의 번호일 것 같다. 우리는 아마도 "directory entry" 구조체를 다루고 있는 듯 하다. 그 원소들은 파일의 속성, 그 이름, inode, 길이(블럭 수)를 나타낼 것이다. 이것도 (d_reclen 과 d_ino 에 대한) 우리의 추측을 확인해 주는 것으로 보인다.

fortune.c 파일을 편집해서, 551째줄과 553째줄의 d_namelen에 대한 참조를 d_reclen에 대한 참조로 고치도록 하자. 다시 make all 을 해 보자. 성공이다. 에러 없이 컴파일되었다. 우리는 이제 fortune으로부터 싼 값에 스릴을 느낄 수 있다.


다음 이전 차례