这个例子需要一些 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_namelen 为 d_reclen
。再重新 make all aga 。成功。 它构建没有错误。我们现在从好运气中得到我们的"cheap thrills"
。