次のページ 前のページ 目次へ

11. 3 番目の例: Fortune

この例は 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/includedirent.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 を使って 「ちょっとどきどき」できますね。


次のページ 前のページ 目次へ