【Unix/Linux程式設計實踐】檔案系統:編寫pwd
知識點
目錄是一個包含檔名與i-節點對的列表的檔案。
”檔案在目錄中“的含義:目錄中存放的只是檔案在i-節點表的入口,而檔案的內容則儲存在資料區中。例如,“檔案x在目錄a中”意味著在目錄a中有一個指向檔案x的i-節點的連結,這個連結所附加的檔名為x。
pwd:用來顯示到達當前目錄的路徑。
pwd的工作過程
- 得到“.”(當前目錄)的i-節點號,稱其為n(使用stat);
- chdir .. (使用chdir,進入父目錄);
- 找到i-節點號n連結的名字(存放在父目錄的資料區中,使用opendir, readdir, closedir);
- 回到1,直到到達樹的頂端(當“.”和”..”的i-節點號相同時)。
此外,為以正確的順序列印目錄名字,且方便簡單,我們可以遞迴地列印。
pwd的一種版本
/* spwd.c: a simplified version of pwd
*
* starts in current directory and recursively
* climbs up to root of filesystem, prints top part
* then prints current part
*
* uses readdir() to get info about each thing
*
* bug: prints an empty string if run from "/"
**/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
ino_t get_inode(char *);
void printpathto(ino_t);
void inum_to_name(ino_t , char *, int );
int main()
{
printpathto( get_inode( "." ) ); /* print path to here */
putchar ('\n'); /* then add newline */
return 0;
}
void printpathto( ino_t this_inode )
/*
* prints path leading down to an object with this inode
* kindof recursive
*/
{
ino_t my_inode ;
char its_name[BUFSIZ];
if ( get_inode("..") != this_inode )
{
chdir( ".." ); /* up one dir */
inum_to_name(this_inode,its_name,BUFSIZ);/* get its name*/
my_inode = get_inode( "." ); /* print head */
printpathto( my_inode ); /* recursively */
printf("/%s", its_name ); /* now print */
/* name of this */
}
}
void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen)
/*
* looks through current directory for a file with this inode
* number and copies its name into namebuf
*/
{
DIR *dir_ptr; /* the directory */
struct dirent *direntp; /* each entry */
dir_ptr = opendir( "." );
if ( dir_ptr == NULL ){
perror( "." );
exit(1);
}
/*
* search directory for a file with specified inum
*/
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
if ( direntp->d_ino == inode_to_find )
{
strncpy( namebuf, direntp->d_name, buflen);
namebuf[buflen-1] = '\0'; /* just in case */
closedir( dir_ptr );
return;
}
fprintf(stderr, "error looking for inum %d\n", inode_to_find);
exit(1);
}
ino_t get_inode( char *fname )
/*
* returns inode number of the file
*/
{
struct stat info;
if ( stat( fname , &info ) == -1 ){
fprintf(stderr, "Cannot stat ");
perror(fname);
exit(1);
}
return info.st_ino;
}
下面我們進行測試,分別使用pwd和我們自己寫的spwd列印當前目錄路徑:
jiange@jiange-Inspiron:~/linux/unix程式設計實踐教程程式碼/CH04$ pwd
/home/jiange/linux/unix程式設計實踐教程程式碼/CH04
jiange@jiange-Inspiron:~/linux/unix程式設計實踐教程程式碼/CH04$ ./spwd
/jiange/linux/unix程式設計實踐教程程式碼/CH04
咦,為什麼不一樣呢?
因為命令pwd顯示達到這個計算機上整棵檔案樹的根,而我們寫的程式只是到達所在檔案系統的根而已!
我的電腦在分割槽的時候,/ 以及 /home 是分在不同的區中,即兩者是在不同的檔案系統當中的。在unix中,每個分割槽都有自己的檔案系統樹,當計算機上存在多個檔案系統時,unix將這些數整合成一顆更大的樹。比如我們的 / 和 /home, / 所在檔案系統為根檔案系統,/home所在檔案系統被附件到根檔案系統的/home子目錄上,根檔案系統中的目錄/home作為指標,指向/home檔案系統的根,這樣子兩個檔案系統就聯絡起來了。
使用命令mount可以檢視當前所裝載的檔案系統以及它們的裝載點。
×硬連結不可以跨越檔案系統,符號連結則可以。
相關推薦
【Unix/Linux程式設計實踐】檔案系統:編寫pwd
知識點 目錄是一個包含檔名與i-節點對的列表的檔案。 ”檔案在目錄中“的含義:目錄中存放的只是檔案在i-節點表的入口,而檔案的內容則儲存在資料區中。例如,“檔案x在目錄a中”意味著在目錄a中有一個指向檔案x的i-節點的連結,這個連結所附加的檔名為x。 pw
【Unix/Linux程式設計實踐】 動手實現簡單的more
最近都在看一些理論方面的書,缺乏實踐真的是雲裡霧裡的,於是今天開始看《Unix/Linux程式設計實踐教程》,理論實踐相結合! 自己動手來實現linux的一些功能,確實挺有趣的,而且還能加深對系統的理解~ 版本一 /*more01.c *read a
學習《Unix/Linux程式設計實踐教程》(2):實現 more
0.目錄 1.more 能做什麼? 2.more 是如何實現的? 3.實現 more 3.1 more01.c 3.2 more02.c 3.3 more03.c 1.more 能做什麼? more 可以分頁顯示檔案的內容。正常執行後 more 會顯示檔案第一屏的內容,在螢幕的底
【Linux學習二】檔案系統
環境 虛擬機器:VMware 10 Linux版本:CentOS-6.5-x86_64 客戶端:Xshell4 FTP:Xftp4 一、檔案系統 一切皆檔案Filesystem Hierarchy Standard(檔案系統層次化標準)/boot: 系統啟動相關的檔案,如核心、initrd,以及
Unix-Linux 程式設計實踐教程 第十章 小結
檔案描述符是一個資源陣列的索引,每次取最小的用,0、1、2分別代表stdin,stdout,stderr三個標準IO的描述符。重定向只需close其中其中一個,然後再開啟一個檔案描述符,系統自動將關閉掉的索引重新使用。比如close(0),open(x-file,"r"),此時就是將stdi
Unix-Linux 程式設計實踐教程 第八章 小結
執行程式的函式---execvp() &n
Unix-Linux 程式設計實踐教程 第七章 小結
設定傳送訊號的計時器---alarm()alarm()設定當前程序的計時器到seconds秒後收到由核心發來的SIGALARM訊號 pause()掛起呼叫程序知道一個訊號到達,如果呼叫程序被整個訊號終止,pause()則不會返回。 三種計時器: ITIMER_
Unix-Linux 程式設計實踐教程 第五章 小結
裝置檔案中用逗號連線起來的兩個數字為主裝置號和從裝置號。主裝置號確定實際的裝置驅動程式,從裝置號作為引數。 如下圖中的,主裝置號-4,從裝置號-2 裝置檔案中的i-node儲存的是指向核心子程式指標 fcntl()針對當前fd描述的連線,執行操作,並不會改變檔案本身的屬性。
Unix-Linux 程式設計實踐教程 第四章 小結
建立目錄的函式---mkdir(const char *pathname, mode_t mode); #include <sys/stat.h> #include <sys/types.h> //pathname中可接受,“/home/tmp”和“/home/t
Unix-Linux 程式設計實踐教程 第三章 小結
Linux下一切皆檔案,所以目錄也只是一種特殊的檔案,可以同文件一樣open,read,close,只是函式換成了opendir(),readdir(),closedir() 用於讀取目錄檔案的資料結構---struct dirent #include <dirent.h>
Unix-Linux 程式設計實踐教程 第二章 小結
utmp檔案記錄當前正在本系統中的使用者的登入資訊 wtmp檔案記錄登入過本系統的使用者的登入資訊 PS:man who命令即可查詢到utmp和wtmp檔案在當前系統的位置 who命令相關: who顯示當前已登入使用
unix/linux程式設計實踐教程C語言補充(2)
1 getchar()和putchar()函式 getchar()函式的功能是從終端接受一個字元。可以將其置於程式中實現暫停功能。 getchar()函式接受的字元可以賦給一個字元型或整型變數,也可以賦給任何變數,直接輸出。 putchar(引數) 引數可以是一個字元
Unix/Linux程式設計實踐教程–ac在Ubuntu 14.04的實現
環境:Ubuntu 14.04 32位 為什麼這回不寫在OS x上的實現了?因為OS X使用的是utmpx,然後我用getutxent_wtmp()這個函式也沒有辦法正確獲取wtmp的日誌資訊,所以先在Ubuntu上實現好了。 預設沒有帶ac這個程式,需要自
【windows核心驅動開發】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽)
【我的】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽) 作者:zcr214 時間:2016/4/21 在編寫檔案系統微過濾驅動minifilter的時候,很有可能我們只對某一個特定的磁碟分割槽感興趣,而其他的如系統盤的很多IRP對於我們要編寫的驅動可
Unix/Linux程式設計實踐教程–od在OS X的實現
環境:OS X 10.12.4 抱歉,本文章並不是關於Ollydbg的實現(笑)。 照舊man 1 od。 od 是一個能把指定的檔案或者標準輸入按照使用者定義的格式列印。( The od utility is a filter which displa
【windows核心驅動開發】檔案系統微過濾驅動Minifilter——獲取程序資訊
【我的】檔案系統微過濾驅動Minifilter——獲取程序資訊 作者:zcr214 時間:2016/4/22 在編寫檔案系統微過濾驅動minifilter的時候,除了繫結指定的磁碟分卷,對於指定的檔案很可能還會有指定的應用程式,例如txt檔案可以有很多編輯器可以使用,如w
Unix/Linux程式設計實踐教程–chmod在Centos7.3的實現
環境:centos 7.3 x86_64 如果搜一下man就會發現,裡面有兩個chmod,一個是chmod(1),一個是chmod(2)。根據牛頓-萊布尼茲公式,立即推,第一個是使用者命令,第二個是系統呼叫。系統呼叫裡,函式的原型是這樣的: int chmo
Unix/Linux程式設計實踐教程–書評
花了兩個月的時間把這本書讀完了,完成了一部分的課後習題。 總的來說,這是一本挺好的Unix\Linux程式設計的入門書(雖然書中的小錯誤一大堆),書的開始部分簡要介紹了Unix系統程式設計,講述瞭如何使用男人(man page),這也是我比較看好的,授人以漁,
Unix/Linux程式設計實踐教程–cat在OS X的實現
環境:OS X 10.12.4 cat 這玩意兒在哪個Unix平臺實現都一樣吧- - cat這個程式是把引數中的檔名的檔案內容輸出到標準輸出,如果引數中沒有檔名,預設是把標準輸入的內容輸出到標準輸出。 這裡使用了utmplib類似的程式碼用於快取資料,減少
unix/linux程式設計實踐教程:who命令
1. who命令的編寫 1) 通過man命令的幫助,找到who命令的儲存檔案 man who2) 在man who的幫助下,找到utmp這個資訊 man -k utmp 3) 看man -k utmp的輸出,找到以下這條資訊: utmp (5)