此文著重介紹系統是如何表示目錄的以及pwd命令的編寫。
我們都知道unix將磁碟分為三部分:超級塊(superblock),節點表(inode table)以及資料區。超級塊中記錄檔案系統本身的結構資訊。節點表中記錄檔案的屬性,檔案系統中每個檔案在表中都至少有乙個i-節點,表中每個節點的大小相同。資料區就是檔案資料真實的儲存位置。
簡要介紹磁碟知識後,我們來談談目錄。在unix中,目錄是包含了檔案名字列表的特殊檔案,其抽象模型是乙個包含i-節點號和檔名的表。所以乙個目錄的內容有兩個部分:乙個i-節點表和檔名表,其相互對應。對於檔案來說,目錄是找到該檔案的乙個索引(鏈結),本質上就是負責記錄檔案i-節點表與檔名的對應關係(乙個檔案可能對應好多個i-節點)。對於open、cat、cp等命令,都是通過在目錄中尋找目的檔名,然後根據對應關係獲取i-節點號以獲取檔案屬性,最終獲取檔案內容來實現的。
假設目錄demodir中有乙個檔案y,y檔案對應的i-節點號是491。從系統角度來看,目錄中有乙個包含檔名y和i-節點號為491的入口,也可以說目錄demodir中有乙個指向i-節點號為491的鏈結,這個鏈結所附加的檔名為y。
說來說去這麼繞,書上有一句結論概括地很好:目錄包含的是檔案的引用,每個引用被成為鏈結。檔案的內容儲存在資料塊,檔案的屬性被記錄在乙個被稱為i-節點的結構中,i-節點的編號和檔名儲存在目錄中。就像我前面說的,目錄本質上是記錄對應關係。
了解了pwd的核心屬性後,我們來實現一下pwd。
此程式中使用遞迴語句實現,從當前目錄不斷迴圈深入直到」.」與」..」的i-節點號相同,即代表到達根目錄,再由內向外列印出資料夾名。
邏輯不難理解,有一點需要注意,通過stat結構體我們可以獲得」.」與」..」目錄的i-節點號,我們需要通過節點號獲取資料夾名。有點類似於乙個trick,通過獲得父目錄的dir結構體,取出父目錄中包含當前目錄在內的檔案及資料夾的dirent結構體,通過比對結構體中d_ino欄位與當前目錄的inode,找到此inode所對應的的d_name即可。因此,程式中chdir必須在num_to_name之前。
/*pwd.c -print the directory where you in*/
#include "stdio.h"
#include "string.h"
#include "dirent.h"
#include "sys/stat.h"
#include "unistd.h"
#include "stdlib.h"
#define size 100
ino_t get_inode(char *path);
void print_path(ino_t cur_inode);
void num_to_name(ino_t inode, char *name);
int main(int argc, char const *argv)
ino_t get_inode(char *path)
return info.st_ino;
}void print_path(ino_t cur_inode)
}void num_to_name(ino_t inode, char *name)
while((direntp = readdir(dir_ptr)) != null)
}perror("can not fine with the innode");
exit(1);
}
檔案系統(一)
又是檔案系統。前面已經提到過一次檔案系統的實現了,為什麼這裡還要再介紹一邊檔案系統呢?原因是前面介紹的檔案系統訪問比較簡單,僅僅是讀取固定的幾個檔案。而這裡,為了保證裝載器的靈活性,這裡的檔案系統設計複雜多了。而且由於是c 實現,可讀性也提高了。以後在核心中,我們還需要處理一次檔案系統,那是作業系統...
檔案系統(一)
檔案系統占得 比較多,我們將從提供給使用者的api開始逐步進入核心,順藤摸瓜!最終獲取檔案系統的抽象 裝置的組織。裝置號 系統所含的裝置如下 與minix 系統的一樣,所以我們可以使用minix 的 檔案系統。以下這些是主裝置號。0 沒有用到 nodev 1 dev mem 記憶體裝置。2 dev ...
檔案系統(一)
檔案系統 檔案系統是某些作業系統必然包含的模組,對系統中儲存介質的訪問以統一的系統介面進行管理,完成read write ioctl等操作 1 分類 按實現分類 傳統的單機版的檔案系統和網路分布式的檔案系統。分布式檔案系統通常應用網路技術和協議,將分散的各個資料資源進行統一管理的系統形式。嵌入式作業...