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

11. 第3の例:Fortune

最後の例は C のプログラミングの知識をいくらか必要とします。UNIX や Linux の ソフトウェアのほとんどは C で書かれており、少しでも C について知っていれば ソフトウェアのインストールにおいて間違い無く強みとなるでしょう。

悪名高い fortune プログラムはユーモアのあることわざ、いわゆる "fortune cookie" を Linux がブートするたびにディスプレイに 表示します。不運にも、カーネルのバージョンが2.0.30の Red Hat の ディストリビューションで、致命的なエラーが発生します。


~/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 や、他のソース ファイルでは宣言されていません。しかし、 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 です。もう一つの可能性のあるのが、名前とデータのタイプから 判断すると、 d_ino は inode の数を表しているようです。実際のところ、 この構造体は多分"ディレクトリエントリ"を扱っているのでしょう。 そして、これらのメンバはファイルの属性やファイルの名前、 inode 、 (ブロックの)長さを意味しているようです。このことが推測が当たっているという ことを示唆しているように思えます。

fortune.c を編集して、551行目と553行目の d_namelen への参照をを d_reclen に書き換えてみましょう。もう一度 make all を試してみましょう。 成功しました。エラーがでることなく構築できました。今や、 fortune のおかげで"ちょっとしたどきどき"を感じることが 出来ます。


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