如果要實現pwd命令,必需對linux的文件系統非常了解。下面我們先從文件系統說起,然后過度到編寫pwd的知識。
1、linux的文件系統
從用戶的角度來看,linux的文件系統就是一個目錄樹,從系統的角度看,是對磁盤劃分的抽象。磁盤的第一級抽象:從磁盤到分區;第二級:從磁盤到塊序
列,盤片被劃分為磁道,磁道被劃分為扇區;第三級:從塊序列到三個區域的劃分。在linux下,磁盤被劃分為三個區域:超級塊,i-結點和書局區。超級塊
是文件系統的第一個塊,存放文件系統本身的信息,i-結點存放每個文件的屬性『大小,文件所有者,權限等』。數據區存放文件的內容。
2、創建一個文件的過程
??? 四個步驟:
— 存儲屬性,分配i-結點;
??? — 存儲數據,維護一個存放文件的塊列表;
??? — 記錄分配情況,在i-結點的磁盤分布區記錄了存放文件的塊序列;
??? — 添加文件名到目錄,在目錄文件中增加一條記錄。
3、目錄的工作過程
??? 目錄是包含了文件名子列表的特殊文件,可以使用命令ls -1ia
director來查看對應的i-node號。理解目錄和目錄的工作過程是理解文件系統的關鍵。在每個目錄文件的列表中有兩個特殊的項:.代表本級目
錄,..代表上級目錄,并且都有對應的i-node號,所以我們可以通過這兩個i-node號逐級向上就可以找到當前工作目錄的絕對路徑。但是什么時間算
到了根目錄呢?先執行ls -i /看看結果,可以發現,根目錄下的.和..對應的i-node號相同,這可以作為搜索結束的條件。
4、pwd命令的實現
代碼如下:
?1?/*
?2??*?starts?in?current?directory?and?recursively?climbs?up?to?root
?3??*?of?filesystem,?prints?top?part?then?prints?current?part
?4??*?use?readdir()?to?get?info?about?each?thing
?5??*/
?6??
?7??#include?<stdio.h>
?8??#include?<sys/types.h>
?9??#include?<sys/stat.h>
10??#include?<dirent.h>
11??#include?<stdlib.h>
12??#include?<string.h>
13??#include?<unistd.h>
14??
15??ino_t?get_inode(char?*);
16??void?printpathto(ino_t);
17??void?inum_to_name(ino_t,?char?*,?int);
18??
19??int?main()
20??{
21????printpathto(get_inode("."));
22????printf("\n");
23????return?0;
24??}
25??
26??void?printpathto(ino_t?this_inode)
27??/*
28???*?prints?path?leading?down?to?an?object?with?this?inode
29???*?kind?of?recursive
30???*/
31??{
32????ino_t?my_inode;
33????char?its_name[BUFSIZ];
34????if(get_inode("..")?!=?this_inode)??????//not?lead?to?root
35????{
36??????chdir("..");????????????????????????????????//up?one?dir
37??????inum_to_name(this_inode,?its_name,?BUFSIZ);?//get?its?name
38??????my_inode?=?get_inode(".");
39??????printpathto(my_inode);
40??????printf("/%s",?its_name);
41????}
42??}
43??
44??void?inum_to_name(ino_t?inode_to_find,?char?*namebuf,?int?buflen)
45??/*
46???*looks?through?current?directory?for?a?file?with?this?node
47???*number?and?copies?its?name?into?namebuf
48???*/
49??{
50????DIR?*dir_ptr;
51????struct?dirent?*direntp;
52????dir_ptr?=?opendir(".");
53????if(dir_ptr?==?NULL)
54????{
55??????perror(".");
56??????exit(1);
57????}
58????while((direntp?=?readdir(dir_ptr))?!=?NULL)
59????{
60??????if?(direntp->d_ino?==?inode_to_find)
61??????{
62????????strncpy(namebuf,?direntp->d_name,?buflen);
63????????namebuf[buflen?-?1]?=?'\0';
64????????closedir(dir_ptr);
65????????return?;
66??????}
67????}
68????fprintf(stderr,?"error?looking?for?inum?%d\n",?inode_to_find);
69????exit(1);
70??}
71??
72??
73??ino_t?get_inode(char?*fname)
74??{
75????/*
76?????*?return?inode?number?of?the?file
77?????*/
78?????struct?stat?info;
79?????if((stat(fname,?&info))?==?-1)
80?????{
81???????fprintf(stderr,?"Cannot?stat");
82???????perror(fname);
83???????exit(1);
84?????}
85?????
86?????return?info.st_ino;
87??}
88??
89?
結論:
對于理解系統編程,理解操作系統,學習相關的命令,并探究命令的實現過程,最后自給編寫一個同樣功能的命令,不失為一種很好的學習方法。