この例は C 言語のプログラミングの知識をある程度必要とします。UNIX や Linux のソフトウェアのほとんどは C 言語で書かれているので、ソフトウェ アのインストールをまじめにやろうとするなら多少でも C 言語を覚えておけ ばきっと役に立つでしょう。
有名な fortune プログラムはユーモアのあることわざ、いわゆる "fortune cookie" を Linux がブートするたびに表示します。 不運なことに(ここは unfortune にかけたシャレのつもり)、 カーネルのバージョンが 2.0.30 の RedHat ディストリビューションでは致命 的なエラーが発生します。
~/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>
これはシステムライブラリのインクルードファイルのようです。したがって、
必然的に dirent.h を探しに行く場所は /usr/include と
なります。実を言うと、/usr/include に dirent.h はあ
るのですが、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 が入っていませんでした。し かし、それに相当しそうな「候補」が 2 つあります。そのうちもっともそれ らしいのは d_reclen です。というのも、この構造体メンバは 何かの長さを表しているようですし、short 型の整数だからです。もう一つの 方は d_ino ですが、これは名前と型から考えると inode 番号のよ うです。実をいうと、ここでは「ディレクトリエントリ」構造体を扱っていて、 各要素はファイルの属性、ファイル名、inode 番号、(ブロック単位での)長さ を表しています。この事実と突き合わせると推測が確実になるでしょう。
fortune.c
を編集して、551 行目と 553 行目にある d_namelen
への参照を d_reclen に書き換えてみましょう。それから
make all をもう一度試しましょう。成功しました。
エラーもなしに構築できました。これで fortune を使って
「ちょっとどきどき」できますね。