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