Next Previous Contents

8. 第三个例子: Fortune

最後例子需要某些 C 程式设计知识. 大部分的 Linux 软体是用 C 写的, 而且至少学点 C 明显的对任何想软体安装的人会有助益.

恶名昭彰的(notorious) fortune 程式在每次 Linux 开机起来时秀出幽默的谚语 "fortune cookie". 不幸地 (有双关意思的), 设法在 Red Hat 发行套件 2.0.30 的核心下建立,出现了 一堆严重的错误.


~/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 的 structure, 但它没有宣告(declared)在 fortune.c 档案中, 想用 grep dirent 来秀出是否在其它原始码的档案中, 但也没有. 然而, 在 fortune.c 档的最上方有下列这行.


#include <dirent.h>

这似乎是系统函式库的 include 档案, 所以要找 dirent.h 的合理位置是在 /usr/include. 事实上, dirent.h 的确有在 /usr/include 中, 但该档没有包含 dirent 的 structure. 然而, 参考另一个 dirent.h 档.


#include <linux/dirent.h>

最後, 去 /usr/include/linux/dirent.h, 我们可找到我们所需要宣告的 structure.


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

足够地确定, 这个 structure 宣告没有包含 d_namelen, 但有一对与其相当的选择. 其中最可能的是 d_reclen, 因为 这个 structure member 表示某样东西的 length 而且它是 short integer. 其他大略, d_ino, 可能是 inode number, 判断它的 name 和 type. 事实上, 我们大概是处理 "directory entry" structure, 而元素表示档案属性, 它的名称, inode, 和 length (以 blocks 作单位). 这似乎对我们的猜想很合理.

我们编辑档案 fortune.c, 而且改变在551行和553行的 d_namelen 变成 d_reclen. 再试试 make all. Success. 这次建立没有错误. 我们现在能够从 fortune 获得 "cheap thrills"


Next Previous Contents