Next Previous Contents

11. 第三个例子:Fortune

这个例子需要一些 C 语言知识。大部分 UNIX/Linux 软件是用 C 写的。而且任何人学习少量的 C 知识对于软件安装是非常有好处的。

非常有名的 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 结构里寻找,但是它没有所说的 fortune.c 文件,在其它所有源码文件里用 grep dirent 命令也没看到。可是在 fortune.c 最上面有下面的行:

#include <dirent.h>

这看起来似乎是一个系统函数 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 。因为这个结构成员出现的特征或许和它的大概长度是一个短整数。另一个可能性,d_ino ,凭它的名字和类型判断可能是一个节点数字。事实上,我们正在处理一个 "directory entry"; 结构,而且这些元素表现一个文件的属性,它的名字,节点,和长度 (在区段中) 。这些似乎证实了我们的猜测。

让我们编辑 fortune.c 文件,并在 551 和 553 行修改两个 d_namelend_reclen 。再重新 make all aga 。成功。 它构建没有错误。我们现在从好运气中得到我们的"cheap thrills" 。


Next Previous Contents