linux操作系統(tǒng)課程設(shè)計(jì)ls的編寫(xiě)含源碼
《linux操作系統(tǒng)課程設(shè)計(jì)ls的編寫(xiě)含源碼》由會(huì)員分享,可在線閱讀,更多相關(guān)《linux操作系統(tǒng)課程設(shè)計(jì)ls的編寫(xiě)含源碼(35頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、 西安郵電大學(xué) 操作系統(tǒng)課程設(shè)計(jì) 報(bào) 告 書(shū) 院系名稱 : 計(jì)算機(jī)學(xué)院 學(xué)生姓名 : 專業(yè)名稱 : 軟件工程 班 級(jí) : 班 學(xué)號(hào) : 時(shí)間 : 2015 年4月 13 日 至 2015 年 4月 24 日 1 實(shí)驗(yàn)?zāi)康? 操作系統(tǒng)是控制和管理計(jì)算機(jī)硬件和軟件資源的虛擬機(jī),其中的文件系統(tǒng)是對(duì)軟件和設(shè)備進(jìn)行管理的系統(tǒng),文件系統(tǒng)是操作系統(tǒng)中非常重要的一個(gè)模塊,它的實(shí)現(xiàn)占用了操作系統(tǒng)源碼的最大編碼量,其好壞也直接影響著用戶對(duì)操作系統(tǒng)的感受程度。通過(guò)對(duì)操作系統(tǒng)課程設(shè)計(jì)的實(shí)踐,進(jìn)一步加深對(duì)文件系統(tǒng)的認(rèn)識(shí)和理
2、解,并在此基礎(chǔ)上培養(yǎng)學(xué)生的工程應(yīng)用能力。實(shí)驗(yàn)分別從用戶態(tài)和內(nèi)核態(tài)兩個(gè)層次實(shí)踐文件系統(tǒng)的部分功能。 2 實(shí)驗(yàn)任務(wù) 2.1 ls實(shí)現(xiàn) 在linux下編程實(shí)現(xiàn)帶參數(shù)的shell命令 ls,ls命令必須支持如下功能。 1.基本要求 (1) 支持 -l 參數(shù); (2) 輸出結(jié)果按字典排序; (3) 列出“.”文件,支持-a參數(shù),在沒(méi)有-a時(shí)候不顯示隱藏文件; (4) 顯示記錄總數(shù)。 2.高級(jí)要求 (1) 支持對(duì)給定的目錄進(jìn)行操作,如 ls /tmp; (2) 輸出結(jié)果分欄排序,每欄的寬度由這一欄最長(zhǎng)的文件名決定,顯示的欄數(shù)還受終端顯示器的寬度影響,每一列盡可能的等寬; (3) 正
3、確顯示文件特殊屬性suid、sgid和sticky,參見(jiàn)聯(lián)機(jī)幫助確保程序能處理各種情況; (4) 支持標(biāo)準(zhǔn)的ls支持選項(xiàng)-R,它的功能是遞歸地列出目錄中所有的文件包含子目錄中的文件; (5) 支持標(biāo)準(zhǔn)的ls支持選項(xiàng)-u,它會(huì)顯示出文件的最后訪問(wèn)時(shí)間,如果用了-u而不用-l,會(huì)有什么結(jié)果?; (6) 當(dāng)關(guān)掉一個(gè)文件的讀權(quán)限,就不能打開(kāi)這個(gè)文件來(lái)讀。如果從一個(gè)終端登錄,打開(kāi)一個(gè)文件,保持文件的打開(kāi)狀態(tài),然后從另外的終端登錄,去掉文件的讀權(quán)限,這時(shí)有什么事情會(huì)發(fā)生?編寫(xiě)一個(gè)程序,先用open()打開(kāi)一個(gè)文件,用read()讀一些內(nèi)容,調(diào)用sleep()等待20s以后,再讀一些內(nèi)容,從另外的終端
4、,再等待的20s內(nèi)去掉文件的讀權(quán)限,這樣會(huì)有什么結(jié)果?。 2.2編寫(xiě)內(nèi)核模塊顯示目錄或文件的信息。 (1) 使用內(nèi)核模塊編程; (2) 調(diào)試《Linux操作系統(tǒng)原理與應(yīng)用》第8章文件系統(tǒng)P215 的例子; (3) 練習(xí)給內(nèi)核模塊傳入?yún)?shù),參考關(guān)于帶參數(shù)的模塊編程 (4) 給內(nèi)核模塊傳入?yún)?shù)path,其中path為絕對(duì)路徑; 1) 當(dāng)path為目錄時(shí),顯示目錄對(duì)應(yīng)的dentrey結(jié)構(gòu)中的相關(guān)信息(可打印的信息); 2) 當(dāng)path為文件時(shí),顯示文件對(duì)應(yīng)的indoe結(jié)構(gòu)中的相關(guān)信息(可打印的信息); 3) 當(dāng)路徑錯(cuò)誤時(shí),有錯(cuò)誤提示信息。 3 開(kāi)發(fā)環(huán)境 設(shè)備名稱 設(shè)
5、備類型 配置類型 參數(shù) Lenovo G480 PC機(jī) 硬件配置 RAM 4G 軟件配置 Ubuntu 32位 4 測(cè)試環(huán)境 設(shè)備名稱 設(shè)備類型 配置類型 參數(shù) Lenovo G480 PC機(jī) 硬件配置 RAM 4G 軟件配置 Ubuntu 32位 5 總體設(shè)計(jì) 5.1功能組織圖 ls 功能圖: 運(yùn)行命令 Ls -a Ls Ls -l Ls -la 添加 /temp(指定目錄) 輸出所有文件屬性 輸出隱藏文件 輸出文件屬性 按字典順
6、序排序 文件權(quán)限: 運(yùn)行命令 chmod修改權(quán)限 讀文件,ls顯示權(quán)限信息 內(nèi)核模塊: super_blocks: 運(yùn)行命令 加載模塊 加鎖 遍歷系統(tǒng)中的超級(jí)塊 打印文件設(shè)備號(hào) 打印文件系統(tǒng)名 打印索引結(jié)點(diǎn)號(hào)統(tǒng)計(jì)索引結(jié)點(diǎn)計(jì)數(shù) 卸載模塊 path: 運(yùn)行命令 路徑錯(cuò)誤 Path=文件 Path=目錄 顯示目錄信息 顯示錯(cuò)誤信息 顯示文件信息 5.2原
7、理 linux文件系統(tǒng): linux下有普通文件、目錄文件、鏈接文件、設(shè)備文件、管道文件這幾種類型。但鏈接文件、設(shè)備文件、管道文件都可以當(dāng)做普通文件看待,那實(shí)際也就只要區(qū)分普通文件和目錄文件這兩種了。而目錄文件的內(nèi)容就是它所包含所有文件和子目錄的一個(gè)列表,所以只要打開(kāi)目錄文件并讀取對(duì)應(yīng)目錄塊里的那個(gè)列表數(shù)據(jù),就可以得到些目錄下所有文件和子目錄的名稱了。其實(shí)這個(gè)流程簡(jiǎn)單,就是:打開(kāi)目錄->讀取內(nèi)容->顯示文件名稱->關(guān)閉打開(kāi)的目錄。 Linux系統(tǒng)中會(huì)有很多目錄。每個(gè)目錄中又會(huì)有很多文件。如果要列出一個(gè)非當(dāng)前目錄的內(nèi)容或者是一個(gè)特定文件的信息,則需要在參數(shù)中給出目錄名或文件名。如: l
8、s/tmp//列出/tmp目錄中各文件的文件名 ls–docs//列出docs目錄中各文件的屬性 ls*.c//列出當(dāng)前目錄下與*.c匹配的文件,即當(dāng)前目錄下所有以.c為后綴的經(jīng)常用到的命令行選項(xiàng) ls-l在前面已經(jīng)提到過(guò),-l就是輸出文件詳細(xì)的信息 ls-a列出的內(nèi)容包含以“.“開(kāi)頭的文件,即所謂有隱藏文件 Linux的文件訪問(wèn)權(quán)限: Linux是一個(gè)安全的操作系統(tǒng),說(shuō)他安全,最重要的一個(gè)原因是對(duì)用戶訪問(wèn)權(quán)限的控制。在shell下我們可以通過(guò)命令ls-l filename 來(lái)查看一文件的屬性。其中第一項(xiàng)文件屬性總共由10位構(gòu)成,第一位是文件類型,剩下9位都是表示文件的訪問(wèn)權(quán)限
9、,每3個(gè)一組,第一組:文件所有者對(duì)該文件的操作權(quán)限,第二組表示與文件所有者同組的用戶對(duì)該文件的操作權(quán)限,第三組表示其他用戶對(duì)該文件的操作權(quán)限,權(quán)限由三種字母組成:r:可讀w:可寫(xiě)x:可執(zhí)行。 編寫(xiě)內(nèi)核模塊 ① 寫(xiě)內(nèi)核模塊,打印super_block結(jié)構(gòu)中一些域的值。(課本上的例子) 遍歷系統(tǒng)中的超級(jí)塊:list_head結(jié)構(gòu)類型的字段名稱為s_list。list_entry宏通過(guò)指向list_head節(jié)點(diǎn)的地址來(lái)得到外部超級(jí)塊的首地址。獲取系統(tǒng)中個(gè)超級(jí)塊的地址,獲得某個(gè)子進(jìn)程的地址,打印文件系統(tǒng)所在的主設(shè)備號(hào)和次設(shè)備號(hào)和文件系統(tǒng)名。遍歷打印每個(gè)超級(jí)塊中的所有索引節(jié)點(diǎn)號(hào),打印索引結(jié)點(diǎn)。
10、 ② 內(nèi)核模塊傳入?yún)?shù)path,其中path為絕對(duì)路徑 path=路徑時(shí),顯示如下信息: 目錄項(xiàng)標(biāo)志、哈希表、短目錄名、目錄項(xiàng)長(zhǎng)度、目錄項(xiàng)名、目錄項(xiàng)計(jì)數(shù)器的引用 path=文件時(shí),顯示如下信息: 文件索引節(jié)點(diǎn)的數(shù)量、文件類型和權(quán)限、用戶ID、用戶組ID、指定文件系統(tǒng)的讀寫(xiě)訪問(wèn)標(biāo)志、文件大小、索引節(jié)點(diǎn)的狀態(tài)、硬鏈接數(shù)、引用記數(shù)、文件的塊、版本號(hào)、以位為單位的塊大小 6 詳細(xì)設(shè)計(jì) 6.1 模塊一ls 1.功能 (1)ls支持 -l 參數(shù); (2)輸出結(jié)果按字典排序; (3)列出“.”文件,支持-a參數(shù),在沒(méi)有-a時(shí)候不顯示隱藏文件; (4)顯示記錄總數(shù)。 (5
11、)支持對(duì)給定的目錄進(jìn)行操作,如 ls /tmp; (6)輸出結(jié)果分欄排序,每欄的寬度由這一欄最長(zhǎng)的文件名決定,顯示的欄數(shù)還受終端顯示器的寬度影響,每一列盡可能的等寬; (7)修改文件權(quán)限 2.算法/流程圖 ls算法描述: 用parameter[20]保存命令行參數(shù)的值,用path[PATH_MAX+1]保存文件的路徑名;程序運(yùn)行時(shí),先將命令參數(shù)保存下來(lái),并給flag_parameter賦相應(yīng)的值,再判斷文件路徑是否存在,不存在則代表當(dāng)前目錄,將./賦值給path,若存在,則根據(jù)文件路徑判斷是文件還是目錄,若是文件,就根據(jù)flag_parameter和path調(diào)用Output
12、_parameter()函數(shù),輸出該文件的屬性;若是目錄,就將正確的目錄名保存到path;最后根據(jù)flag_parameter和path調(diào)用Output_dir()函數(shù),列出目錄下所有文件的屬性。 流程圖: main()函數(shù): 開(kāi)始 parameter[20]保存命令行參數(shù)的值 給flag_parameter賦相應(yīng)的值 判斷是否有文件路徑 否 給path賦值為./ 是 文件路徑名保存在path中 判斷文件路徑是否存在 否 是 判
13、斷文件路徑是目錄 否 是 調(diào)用Output_dir(flag_parameter,path); 判斷文件路徑是文件 否 是 調(diào)用Output_parameter(flag_parameter, path); 結(jié) 束 Output_file_attribute(): 開(kāi)始 給str賦值”---------” 判斷文件的類型,給str[0]賦值對(duì)應(yīng)的字母 判斷用戶的權(quán)限,給str[1]~[3]賦值
14、 判斷組的權(quán)限,給str[4]~[6]賦值 判斷其他用戶的權(quán)限,給str[7]~[9]賦值 輸出str [10]的內(nèi)容 輸出文件的各種屬性 文件個(gè)數(shù)加一 結(jié)束 Output_parameter(): 開(kāi)始 文件個(gè)數(shù)加一 從路徑中解析出文件名 Lstat解析鏈接文件 否 是 flag_parameter== PARAMETER_N 調(diào)用Output() Name[0]==’.’ 是 是
15、 否 否 flag_parameter== PARAMETER_A 調(diào)用Output() 是 否 flag_parameter== PARAMETER_L 調(diào)用Output_file_attribute() Name[0]==’.’ 是 是 否 否 flag_parameter== PARAMETER_A_L 調(diào)用Output_file_attribute() 是 否 結(jié)束 Output():開(kāi)始 本行剩余長(zhǎng)度<文件名
16、長(zhǎng)度 否 是 換行,給剩余長(zhǎng)度賦最大值 打印文件名 文件個(gè)數(shù)加一 結(jié)束 3.運(yùn)行結(jié)果 4.模塊使用的主要函數(shù)、數(shù)據(jù)類型和宏 (1)主要函數(shù)說(shuō)明 1)函數(shù)一Output_file_attribute 原型:Output_file_attribute(struct stat buf, char * name) 功能:根據(jù)文件名輸出文件的各種屬性 參數(shù):buf,name 返回值:void 2)函數(shù)二Output 原型:Output(char * name) 功能:將文件名分欄排序 參數(shù)
17、: name 返回值:void 3)函數(shù)三Output_parameter 原型: Output_parameter(int flag, char * pathname) 功能:根據(jù)命令行參數(shù)和完整路徑名按要求顯示目標(biāo)文件 參數(shù):flag,pathname 返回值:void 4)函數(shù)四Output_dir 原型: Output_dir(int flag_parameter, char * path) 功能:根據(jù)命令行參數(shù)和目錄路徑名將目錄下的文件按要求顯示出來(lái) 參數(shù):flag_parameter,path 返回值:void (2)數(shù)據(jù)類型 1)數(shù)據(jù)類型1
18、 名稱:num 類型:int 含義:保存命令參數(shù)行-的個(gè)數(shù) 2)數(shù)據(jù)類型2 名稱:path[PATH_MAX+1] 類型:char 含義:保存文件路徑名 3)數(shù)據(jù)類型3 名稱:parameter[20] 類型:char 含義:保存命令行參數(shù) 4)數(shù)據(jù)類型4 名稱:flag_parameter 類型:int 含義:記錄命令行參數(shù)的種類 5)數(shù)據(jù)類型5 名稱:buf 類型:struct stat 含義:保存文件信息 (3)宏1 名稱:#define PARAMETER_N 0 含義:命令行無(wú)參數(shù) 宏2 名稱:#define PARAMETER_
19、A 1 含義:命令行參數(shù)只有-a 宏3 名稱:#define PARAMETER_L 2 含義:命令行參數(shù)只有-l 宏4 名稱:#define PARAMETER_A_L 3 含義:命令行參數(shù)有-a和-l 宏5 名稱:#define MAXROWLEN 80 含義:一行顯示的最多字符數(shù),用于分欄排序 6.2 模塊二read 1.功能 打開(kāi)文件,修改文件權(quán)限后讀取文件內(nèi)容 2.算法/流程圖 算法:定義一個(gè)空指針buf用來(lái)存放動(dòng)態(tài)申請(qǐng)內(nèi)存空間的地址,定義一個(gè)整型變量file用來(lái)存放文件描述符;用open()函數(shù)已只讀的方式打開(kāi)指定的文件,返回的文件描述符賦給fil
20、e;若文件打開(kāi)成功,就休眠20秒,在這20秒期間,通過(guò)chmod 命令改變文件的讀寫(xiě)權(quán)限;然后根據(jù)file的值來(lái)讀取文件中的字符,存放在buf,再輸出buf,若讀取失敗就退出。 流程圖: 開(kāi)始 定義buf,file變量 buf = malloc(30); file=open ("read.txt",O_RDONLY); file==-1 是 否 休眠20s,chmod修改文件權(quán)限 (read(file,buf,30)) == -1 是 否 輸出b
21、uf的內(nèi)容 結(jié)束 3.運(yùn)行結(jié)果 4.模塊使用的主要函數(shù)、數(shù)據(jù)類型和宏 (1)主要函數(shù)說(shuō)明 1)函數(shù)一main 原型:void main() 功能:打開(kāi)文件 參數(shù):無(wú) 返回值:無(wú) (2)數(shù)據(jù)類型 1)數(shù)據(jù)類型1 名稱:buf 類型:void * 含義:定義一個(gè)空指針,用來(lái)指向動(dòng)態(tài)申請(qǐng)的內(nèi)存地址 2)數(shù)據(jù)類型2 名稱:file 類型:int 含義:用來(lái)存放打開(kāi)文件的文件描述符 (3)宏:無(wú) 6.3 模塊三super_block 1.功能 通過(guò)加載內(nèi)核的方式,打印出超級(jí)塊super_blocks數(shù)
22、據(jù)結(jié)構(gòu)中文件系統(tǒng)所在的主設(shè)備號(hào)和次設(shè)備號(hào)以及文件系統(tǒng)名 2.算法/流程圖 開(kāi)始 加載模塊 加鎖 遍歷系統(tǒng)中的超級(jí)塊 打印文件設(shè)備號(hào) 打印文件系統(tǒng)名 打印索引結(jié)點(diǎn)號(hào) 索引結(jié)點(diǎn)計(jì)數(shù) 卸載模塊 結(jié)束 3.運(yùn)行結(jié)果 4.模塊使用的主要函數(shù)、數(shù)據(jù)類型和宏 (1)主要函數(shù)說(shuō)明 1)函數(shù)一 原型: static int __init my_init(void) 功能:模塊加載 參數(shù):無(wú) 返回值:int 2)函數(shù)二 原型:static void __exit m
23、y_exit(void) 功能:模塊卸載 參數(shù):void 返回值:void (2)數(shù)據(jù)類型 1)數(shù)據(jù)類型1 名稱:sb 類型:struct super_block * 含義:定義一個(gè)超級(jí)塊 2)數(shù)據(jù)類型2 名稱:pos 類型:struct list_head * 含義:定義一個(gè)鏈表 3)數(shù)據(jù)類型3 名稱:linode 類型:struct list_head * 含義:定義一個(gè)鏈表 4)數(shù)據(jù)類型4 名稱:pinode 類型:struct inode * 含義:定義一個(gè)索引結(jié)點(diǎn) 5)數(shù)據(jù)類型5 名稱:count 類型:int 含義:存儲(chǔ)總數(shù)
24、 (3)宏一 名稱:#define SUPER_BLOCKS_ADDRESS 0xc1778bc0 含義:超級(jí)塊的變量地址 宏二 名稱:#define SB_LOCK_ADDRESS 0xc1932aa0 含義: sb_lock超級(jí)塊對(duì)應(yīng)的自旋鎖 6.4 模塊四path 1.功能 給內(nèi)核模塊傳入?yún)?shù)path,其中path為絕對(duì)路徑; 1) 當(dāng)path為目錄時(shí),顯示目錄對(duì)應(yīng)的dentrey結(jié)構(gòu)中的相關(guān)信息(可打印的信息); 2) 當(dāng)path為文件時(shí),顯示文件對(duì)應(yīng)的indoe結(jié)構(gòu)中的相關(guān)信息(可打印的信息); 3) 當(dāng)路徑錯(cuò)誤時(shí),有錯(cuò)誤提示信息。 2.算法/流程圖
25、 開(kāi)始 加載模塊 調(diào)用open() 卸載模塊 結(jié)束 開(kāi)始 open()函數(shù): 打開(kāi)文件 是文件 否 調(diào)用file_put()打印文件信息 是 調(diào)用dir()打印目錄信息 關(guān) 閉 文 件 結(jié)束 3.運(yùn)行結(jié)果 4.模塊使用的主要函數(shù)、數(shù)據(jù)類型和宏 (1)主要函數(shù)說(shuō)明 1)函數(shù)一 原型:static int file_put(void) 功能:打印文件信息 參數(shù):void 返回值:int
26、 2)函數(shù)二 原型:static int dir(void) 功能:打印目錄信息 參數(shù):void 返回值:int 3)函數(shù)三 原型:static int open(char *path) 功能:打開(kāi)文件 參數(shù):char *path 返回值:int 4)函數(shù)四 原型:static int param_init(void) 功能:加載模塊 參數(shù):void 返回值:int 5)函數(shù)五 原型:static void param_exit(void) 功能:模塊卸載 參數(shù):void 返回值:void (2)數(shù)據(jù)類型 1)數(shù)據(jù)類型1 名稱:file 類型
27、:struct file * 含義:定義一個(gè)文件 2)數(shù)據(jù)類型2 名稱:inode 類型:struct inode * 含義:定義一個(gè)索引結(jié)點(diǎn) 3)數(shù)據(jù)類型3 名稱:dent 類型:struct dentry * 含義: 4)數(shù)據(jù)類型4 名稱:path_file 類型:static char * 含義:定義一個(gè)字符串存放輸入文件名 (3)宏:無(wú) 7 測(cè)試方法與測(cè)試結(jié)果 7.1測(cè)試方法 編號(hào) 輸入用例 期望結(jié)果 1 ./ls 按字典排序,輸出當(dāng)前目錄下的所有文件名(不含隱藏文件)
28、 2 ./ls -l ls.c 顯示 ls.c文件的詳細(xì)信息 3 ./ls -a ../python 顯示上級(jí)目錄下python目錄的所有文件名,含有隱藏文件。 4 ./ls -l . 顯示當(dāng)前目錄下的非隱藏文件詳細(xì)信息按字典排序 5 ./ls -al ../shell 顯示上層文件夾下所有文件文件的詳細(xì)信息 6 ./ls abc 顯示ERROR:當(dāng)前文件夾下沒(méi)有該文件 7.2測(cè)試結(jié)果 1. ./ls 2. ./ls –l l
29、s.c 3. ./ls –a ../python 4. ./ls –l ../pyhon 5. ./ls –al ../shell 6. ./ls abc 8 調(diào)試情況,設(shè)計(jì)技巧及體會(huì) 在設(shè)計(jì)過(guò)程中,在編寫(xiě)多個(gè)命令參數(shù)時(shí)遇到了困難,由于在程序整個(gè)過(guò)程中都需要根據(jù)命令參數(shù)打印記錄文件,因此設(shè)定了一個(gè)數(shù)組用來(lái)存儲(chǔ)命令行參數(shù),考慮到全局參數(shù)不安全,因此選擇使用函數(shù)的形參來(lái)傳遞。,通過(guò)這次課程設(shè)計(jì),不僅使我對(duì)ls命令有了更深一層的認(rèn)識(shí),還認(rèn)識(shí)到了系統(tǒng)提供的命令實(shí)現(xiàn)的途徑和方法。之前總是使用系統(tǒng)命令,如今自己編程實(shí)現(xiàn)了一些命令,每次使用系統(tǒng)提供的命令和調(diào)
30、用自己編寫(xiě)的命令感覺(jué)大不相同。對(duì)同時(shí)對(duì)內(nèi)核模塊的編程也更加熟悉了。 在做設(shè)計(jì)時(shí)先要理清思路,設(shè)計(jì)好功能模塊之間的關(guān)系,再一步一步編碼實(shí)現(xiàn)。 9 參考資料 [1] DANIEL P.BOVET&MARCO CESATI. 深入理解LINUX內(nèi)核[M]. 陳莉君,張瓊聲,張宏偉,譯.第三版. 北京:中國(guó)電力出版社,2007:825-831. [2]Documentation/x86/boot.txt [4] Richard Blum. 匯編語(yǔ)言程序設(shè)計(jì)[M]. 馬朝暉 譯. 北京:機(jī)械工業(yè)出版社,2006. [5] http://elinux.org/images/d/d2/To
31、ols-and-technique-for-reducing-bootup-time.pdf
10 源程序清單
Ls.c
#include
32、 #define PARAMETER_N 0 // 無(wú)參數(shù) #define PARAMETER_A 1 // -a: 顯示所有文件 #define PARAMETER_L 2 // -l:一行顯示一個(gè)文件的詳細(xì)信息 #define PARAMETER_A_L 3 //-a-l或-la或-al顯示所有文件的詳細(xì)信息 #define MAXROWLEN 80 // 一行顯示的最多字符數(shù) int cnt = 0;//顯示文件的總個(gè)數(shù) int leave_len = MAXROWLEN; // 一行剩余長(zhǎng)度,用于輸出對(duì)齊 int maxlen; // 存放某目錄下最長(zhǎng)文件名的長(zhǎng)度
33、 void Output_file_attribute(struct stat buf, char * name); //打印文件屬性 void Output(char * name);//只輸出文件名,命令沒(méi)有-l選項(xiàng),文件名時(shí)要保持上下文對(duì)齊 void Output_parameter(int flag, char * pathname); //根據(jù)命令行參數(shù)和文件路徑名顯示目標(biāo)文件 void Output_dir(int flag_parameter, char * path); //顯示目錄下的文件 int main(int argc, char ** argv) {
34、 int i, j, k, num; char path[PATH_MAX+1]; //文件路徑名 char parameter[20]; // 保存命令行參數(shù)-a-l int flag_parameter = PARAMETER_N; // 用來(lái)記錄參數(shù)種類 struct stat buf; j = 0; num = 0; for (i = 1 ; i < argc; i++) { if (argv[i][0] == -) { for(k = 1; k < strlen(argv[i]); k++) { parame
35、ter[j] = argv[i][k]; // 獲取-后面的參數(shù)保存到數(shù)組parameter中 j++; } num++; // 保存"-"的個(gè)數(shù) } } //記錄參數(shù),最后為選項(xiàng)數(shù)組的末尾元素賦‘\0’。 for(i = 0; i < j; i++) { if(parameter[i] == a) { flag_parameter = PARAMETER_A; i++; if(parameter[i] == l)//記錄-al情況 flag_parameter = PARAMETER_A_L;
36、 else i--; continue; } else if (parameter[i] == l) { flag_parameter = PARAMETER_L; i++; if(parameter[i] == a)//記錄-la情況 flag_parameter = PARAMETER_A_L; continue; } else { printf("ls:參數(shù)輸入錯(cuò)誤-%c\n", parameter[i]); exit(1); } } parameter[j]
37、= \0; //判斷是否是當(dāng)前目錄,若是,則給path賦值為./ if ((num + 1) == argc) { strcpy(path, "./");// "./"當(dāng)前目錄 path[2] = \0; Output_dir(flag_parameter, path); printf("\nTotal:%d\n",cnt); return 0; } i=1; do{ //如果不是目標(biāo)文件名或目錄,解析下一個(gè)命令行參數(shù) if (argv[i][0] == -)//跳過(guò)-a-l參數(shù) { i++; continue;
38、 } else { strcpy(path, argv[i]); //如果目標(biāo)文件或目錄不存在,報(bào)錯(cuò)并退出程序 if ( stat(path, &buf) == -1 ) { printf("目標(biāo)文件不存在"); } if ( S_ISDIR(buf.st_mode) ) // argv[i]是一個(gè)目錄 // 如果目錄的最后一個(gè)字符不是/,就加上/ { if ( path[ strlen(argv[i])-1 ] != /) { path[ strlen(argv[i]) ] = /
39、; path[ strlen(argv[i])+1 ] = \0; } else { path[ strlen(argv[i]) ] = \0; } Output_dir(flag_parameter,path); i++; } else //argv[i]是一個(gè)文件 { Output_parameter(flag_parameter, path); i++; } } } while (i < argc); printf("\nTotal:%d\
40、n",cnt); return 0; } //獲取文件屬性并打印 void Output_file_attribute(struct stat buf, char * name) { char buf_time[32]; //存放時(shí)間 char str[11]; struct passwd *psd; //從該結(jié)構(gòu)體中獲取文件所有者的用戶名 struct group *grp; //從該結(jié)構(gòu)體中獲取文件所有者所屬組的組名 strcpy(str,"----------"); if(S_ISDIR(buf.st_mode)) str[0] = d;
41、if(S_ISCHR(buf.st_mode)) str[0] = c; if(S_ISBLK(buf.st_mode)) str[0] = b; if(S_ISLNK(buf.st_mode)) str[0] = l; if(S_ISREG(buf.st_mode)) str[0] = -; if(S_ISFIFO(buf.st_mode)) str[0] = f; if(S_ISSOCK(buf.st_mode)) str[0] = s; if(buf.st_mode & S_IRUSR) str[1] = r; if(buf.st_mode & S_IWU
42、SR) str[2] = w; if(buf.st_mode & S_IXUSR) str[3] = x; if(buf.st_mode & S_IRGRP) str[4] = r; if(buf.st_mode & S_IWGRP) str[5] = w; if(buf.st_mode & S_IXGRP) str[6] = x; if(buf.st_mode & S_IROTH) str[7] = r; if(buf.st_mode & S_IWOTH) str[8] = w; if(buf.st_mode & S_IXOTH) str[9] = x
43、; printf("%s ",str); psd = getpwuid(buf.st_uid); grp = getgrgid(buf.st_gid); printf("%4d ",buf.st_nlink); //打印文件的鏈接數(shù)(該文件硬鏈接數(shù)目) printf(" %-8s", psd->pw_name); //打印文件擁有者 printf(" %-8s", grp->gr_name); //打印文件所屬用戶組 printf("%6ld",(long)buf.st_size); // 打印文件的大小 strcpy(buf_time,ctime(&bu
44、f.st_mtime)); buf_time[strlen(buf_time) - 1] = \0; // 去掉換行符 printf(" %s",buf_time);// 打印文件的時(shí)間信息 cnt++; } //在沒(méi)有使用-l選項(xiàng)時(shí),打印一個(gè)文件名,打印時(shí)上下行之間進(jìn)行對(duì)齊 void Output(char *name) { int i, len; //如果本行不足以打印一個(gè)文件名則換行 if (leave_len < maxlen) { printf("\n"); leave_len = MAXROWLEN; } len = str
45、len(name); len = maxlen - len; printf("%-s", name); for (i = 0; i < len; i++) { printf(" "); } cnt++; printf(" "); leave_len -= (maxlen + 2); } // 根據(jù)命令行參數(shù)和完整路徑名顯示目標(biāo)文件 void Output_parameter(int flag_parameter, char * pathname) { int i, j; struct stat buf; char name[NAME
46、_MAX + 1]; //從路徑中解析出文件名 for (i = 0, j = 0; i < strlen(pathname); i++) { if (pathname[i] == /) { j = 0; continue; } name[j++] = pathname[i]; } name[j] = \0; //用lstat解析鏈接文件 if ( lstat(pathname, &buf) == -1 ) //lstat返回的是符號(hào)鏈接文件文件本身的狀態(tài)信息 { printf("error\n"); } swi
47、tch (flag_parameter) { case PARAMETER_N: // 沒(méi)有-l和-a選項(xiàng) if (name[0] != .)//不輸出隱藏文件 { Output(name); } break; case PARAMETER_A: // -a:顯示包括隱藏文件在內(nèi)的所有文件 Output(name); break; case PARAMETER_L: // -l:每個(gè)文件單獨(dú)占一行,顯示文件的詳細(xì)屬性信息 if (name[0] != .) { Outp
48、ut_file_attribute(buf, name); printf(" %-s\n", name); } break; case PARAMETER_A_L: // 同時(shí)有-a和-l選項(xiàng)的情況,輸出所有文件詳細(xì)信息 Output_file_attribute(buf, name); printf(" %-s\n", name); break; default:break; } } /*為顯示目錄下的文件做準(zhǔn)備*/ void Output_dir(int flag_parameter, char *path
49、) { DIR *dir; struct dirent *ptr; int count = 0; char filenames[256][PATH_MAX + 1],temp[PATH_MAX + 1]; // 獲取該目錄下文件總數(shù)和最長(zhǎng)的文件名 dir = opendir(path); if (dir == NULL) { printf("目錄打開(kāi)失敗\n"); } while ((ptr = readdir(dir)) != NULL) { if (maxlen < strlen(ptr->d_name)) maxlen = s
50、trlen(ptr->d_name); count++; } closedir(dir); if(count > 256) printf("error\n"); int i, j, len = strlen(path); // 獲取該目錄下所有的文件名 dir = opendir(path); for(i = 0; i < count; i++) { ptr = readdir(dir); if( ptr == NULL) { printf("error\n"); } strncpy(filenames[i],pat
51、h,len); //filenames存放目錄下的所有文件名 filenames[i][len] = \0; strcat(filenames[i],ptr->d_name); filenames[i][len + strlen(ptr->d_name)] = \0; } // 使用冒泡法對(duì)文件名進(jìn)行排序,排序后文件名按字母順序存儲(chǔ)于filenames for(i = 0; i < count-1; i++) for(j = 0; j < count - 1 - i; j++) { if( strcmp(filenames[j],filename
52、s[j + 1]) > 0 ) { strcpy(temp,filenames[j + 1]); temp[strlen(filenames[j + 1])] = \0; strcpy(filenames[j + 1],filenames[j]); filenames[j + 1][strlen(filenames[j])] = \0; strcpy(filenames[j], temp); filenames[j][strlen(temp)] = \0; } } for(i = 0; i < count;
53、i++)
Output_parameter(flag_parameter, filenames[i]);
closedir(dir);
}
Read.c
#include
54、)
{
printf("OpenFail\n");
exit(1);
}
sleep(20);
if((read(file,buf,30)) == -1)
{
printf("ReadFail\n");
exit(1);
}
else
{
printf("%s ",buf);
}
printf("\n");
close(file);
}
Path.c
#include
55、
56、; MODULE_AUTHOR("LXD"); static char *path_file; module_param(path_file,charp,0644); MODULE_PARM_DESC(path_file,"char *param!\n"); //打印文件信息 static int file_put(void) { inode=file->f_dentry->d_inode; printk("\nOutput the file inode:\n"); printk("1.inode number:%ld\n",inode->i_in
57、o); printk("2.mode:%d\n",inode->i_mode); printk("3.uid is:%d\n",(int)inode->i_uid); printk("4.gid is:%d\n",(int)inode->i_gid); printk("5.mount flag is:%u\n",inode->i_flags); printk("6.size is:%d\n",(int)inode->i_size); printk("7.node is:%ld\n",inode->i_state); return 0; } //打印目錄
58、信息 static int dir(void) { dent=file->f_dentry; printk("\nOuput dentry information:\n"); printk("1.dentry flags is:%u\n",dent->d_flags); printk("2.hash is:%u\n",dent->d_name.hash); printk("3.short name:%s\n",dent->d_iname); printk("4.lenghth is:%u\n",dent->d_name.len); printk("5.nam
59、e is:%s\n",dent->d_name.name); return 0; } //打開(kāi)文件 static int open(char *path) { file=filp_open(path,O_DIRECTORY,0); if(IS_ERR(file)) { file=filp_open(path,O_RDWR|O_CREAT,0777); if(IS_ERR(file)){ printk("open file %s failed..\n",path); return 0; } print
60、k("open success!\n"); file_put(); filp_close(file,NULL); return 1; }else { printk("is a direntry!\n"); dir(); filp_close(file,NULL); return 0; } } static int param_init(void) { open(path_file); return 0; } static void param_exit(void) { return; } modu
61、le_init(param_init);
module_exit(param_exit);
super_block.c
#include
62、 static int __init my_init(void) { struct super_block *sb; struct list_head *pos; struct list_head *linode; struct inode *pinode; unsigned long long count=0; printk("\nPrint some fields of super_blocks:\n"); spin_lock((spinlock_t *)SB_LOCK_ADDRESS);//加鎖 list_for_each(pos,(struct
63、list_head *)SUPER_BLOCKS_ADDRESS) { sb=list_entry(pos,struct super_block,s_list); //打印文件系統(tǒng)所在設(shè)備的主設(shè)備號(hào)和次設(shè)備號(hào) printk("\ndev_t:%d: %d",MAJOR(sb->s_dev),MINOR(sb->s_dev)); // 打印文件系統(tǒng)名 printk("\nfile type name:%s\n",sb->s_type->name); list_for_each(linode,&sb->s_inodes) { pinode=
64、list_entry(linode,struct inode,i_sb_list); count++; printk("%lu\t",pinode->i_ino);//打印索引結(jié)點(diǎn)號(hào) } } spin_unlock((spinlock_t *)SB_LOCK_ADDRESS); printk("\nThe number of inodes:%llu\n",sizeof(struct inode)*count); return 0; } static void __exit my_exit(void) { printk("unloading
65、.....\n"); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL"); makefile obj-m:=path.o CURRENT_PATH:=$(shell pwd) LINUX_KERNEL:=$(shell uname -r) LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL) all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules clean: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
- 溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 幼兒園中班上期數(shù)學(xué)任務(wù)單
- 地球上生命的起源 (2)
- 智慧產(chǎn)業(yè)園區(qū)云平臺(tái)建設(shè)方案
- 溢若安好,便是晴(精品)
- 纖維支氣管鏡檢查的護(hù)理
- 溫州小吃(精品)
- 四川地震專業(yè)知識(shí)講座
- 圓柱與圓錐的復(fù)習(xí)課課件(人教課標(biāo)版六年級(jí)下冊(cè)數(shù)學(xué)課件)(1)
- 課題1第2課時(shí)物質(zhì)的性質(zhì)(教育精品)
- 奚永娟資料we_love_animals
- 四年級(jí)上冊(cè)《億以上數(shù)的認(rèn)識(shí)》
- 教科版二年級(jí)下冊(cè)語(yǔ)文七色光四 (2)(教育精品)
- 《美麗的小興安嶺》PPT課件(修改版) (5)
- 防止金融詐騙宣傳講稿-課件
- 門診輸液的觀察與護(hù)理--課件