操作系統課程設計文件系統ls實現與內核編碼_第1頁
操作系統課程設計文件系統ls實現與內核編碼_第2頁
操作系統課程設計文件系統ls實現與內核編碼_第3頁
操作系統課程設計文件系統ls實現與內核編碼_第4頁
操作系統課程設計文件系統ls實現與內核編碼_第5頁
已閱讀5頁,還剩20頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 西 安 郵 電 大 學 (計算機學院)操作系統課程設計報告題 目:文件系統ls實現與內核編碼 專業名稱: 班 級: 學生姓名: 學號(8位): 指導教師: 設計起止時間: 2014年5月19日2014年5月30日一. 設計目的操作系統是控制和管理計算機硬件和軟件資源的虛擬機,其中的文件系統是對軟件和設備進行管理的系統,文件系統是操作系統中非常重要的一個模塊,它的實現占用了操作系統源碼的最大編碼量,其好壞也直接影響著用戶對操作系統的感受程度。通過對操作系統課程設計的實踐,進一步加深對文件系統的認識和理解,并在此基礎上培養學生的工程應用能力。實驗分別從用戶態和內核態兩個層實踐文件系統的部分功能。

2、二. 設計內容1. 在linux下編程實現帶參數的shell命令 ls。實現的功能如下:l 支持 -l 參數;l 輸出結果按字典排序;l 列出“.”文件,支持-a參數,在沒有-a時候不顯示隱藏文件;l 顯示記錄總數。l 支持對給定的目錄進行操作,如 ls /tmp;l 輸出結果分欄排序,每欄的寬度由這一欄最長的文件名決定,顯示的欄數還受終端顯示器的寬度影響,每一列盡可能的等寬;l 正確顯示文件特殊屬性suid、sgid和sticky,參見聯機幫助確保程序能處理各種情況;l 支持標準的ls支持選項-r,它的功能是遞歸地列出目錄中所有的文件包含子目錄中的文件;l 支持標準的ls支持選項-u,它會顯

3、示出文件的最后訪問時間,如果用了-u而不用-l,會有什么結果?2. 修改文件讀權限。當關掉一個文件的讀權限,就不能打開這個文件來讀。如果從一個終端登錄,打開一個文件,保持文件的打開狀態,然后從另外的終端登錄,去掉文件的讀權限,這時有什么事情會發生?編寫一個程序,先用open()打開一個文件,用read()讀一些內容,調用sleep()等待20s以后,再讀一些內容,從另外的終端,再等待的20s內去掉文件的讀權限,這樣會有什么結果?3. 調試linux操作系統原理與應用第8章文件系統p215 的例子4. 編寫內核模塊顯示目錄或文件的信息。給內核模塊傳入參數path,其中path為絕對路徑:l 當p

4、ath為目錄時,顯示目錄對應的dentrey結構中的相關信息(可打印的信息);l 當path為文件時,顯示文件對應的indoe結構中的相關信息(可打印的信息);l 當路徑錯誤時,有錯誤提示信息。三概要設計1功能模塊圖;處理命令行參數獲取命令行參數獲取屏幕寬度運行命令處理路徑非法情況處理無路徑情況處理路徑為目錄的情況處理路徑為文件的情況(1)、實現ls(2) 、修改文件權限關閉文件讀取文件內容睡眠20秒打開錯誤,退出程序否讀取文件內容是判斷文件是否存在運行命令解鎖遍歷各超級塊的索引結點號遍歷系統中的超級塊加鎖(3) 、調試例子移除內核文件信息輸出目錄信息輸出打開文件或目錄非法路徑提示分析絕對路徑

5、插入內核(4) 、內核傳參2各個模塊詳細的功能描述。(1)、實現lsu 運行命令:在終端下運行程序。u 獲取屏幕寬度:調用系統函數ioctl(),獲取當前終端的寬度。u 獲取命令行參數:遍歷命令行獲取命令參數a、u、l、r及其組合,并存入params 數組中。u 處理命令行參數:根據上一步得到的param 分析當前運行時的參數類型并記錄在paramflag中。u 處理無路徑情況:顯示當前目錄的所有信息,并根據上一步得到的paramflag參數組合分類的顯示。u 處理路徑為目錄的情況:顯示該目錄的所有信息,并根據上一步得到的paramflag參數組合分類的顯示。u 處理路徑為文件的情況:顯示該文

6、件的所有信息,并根據上一步得到的paramflag參數組合分類的顯示。u 處理路徑非法情況:顯示錯誤提示并退出程序。(2) 、修改文件權限u 打開文件:文件不存在則報錯,文件存在則進行操作。當修改權限之后,再次打開文件并進行操作。u 讀取文件內容:成功打開文件則讀取文件中存在的數據。在睡眠前后都進行讀取文件內容。u 睡眠:在第一次讀取文件內容之后睡眠20秒,方便進行修改權限操作。(3) 、調試例子u 加、解鎖:在對超級塊操作前,加鎖防止系統其他進程對超級塊進行修改;在操作完成后解鎖。u 獲取超級塊信息:遍歷超級塊,獲取超級塊的基本信息并輸出。u 打印各超級塊的索引結點號:遍歷各超級塊中的索引結

7、點并輸出相關信息。(4)、內核傳參u 文件操作:對由命令傳入的絕對路徑對應的目錄或文件進行打開操作。u 獲取dentry結構體的信息:若絕對路徑指向的是目錄,則打印其dentry結構體中的相關信息。u 獲取inode結構體的信息:若絕對路徑指向的是文件,則打印其dentry結構體中的相關信息。四詳細設計1功能函數的調用關系圖(1)、實現lshasdirs()showfileinfo()showfilename()disposeparam()compareu()compare()dirread()main()其中:void dirread( int, char * ):讀取目錄下文件和子目錄的內

8、容信息。int compare( const void *, const void * ):按字典順序排序。int compareu( const void *, const void * ):在有-u而沒有-l的情況下,按最近時間由近到遠的順序排序。void disposeparam( int, char * ):根據參數的種類,分類對該目錄或文件進行不同的顯示操作。int hasdirs( char * ):判斷當前獲取的子目錄路徑是否之前被找到。void showfilename( char * ):顯示文件名。void showfilesinfo( struct stat, char

9、*, int ):顯示文件的詳細信息。close()sleep()read()open()(2) 、修改文件權限其中:open():調用文件操作函數,打開文件返回文件描述符。read():調用文件操作函數,讀取文件中的內容。sleep():調用線程操作函數,是程序睡眠20秒,等待修改權限。close():調用文件操作函數,關閉文件。(3)、調試例子spin_unlock()list_entry()list_for_eachspin_lock()其中:spin_lock():加鎖操作,在對超級塊操作前,加鎖防止系統其他進程對超級塊進行修改。list_for_each:鏈表宏定義,用來遍歷鏈表,鏈

10、表中存放個超級塊的地址。list_entry():獲取超級塊的地址。spin_unlock():解鎖操作。(4) 、內核傳參path_exit()showdirinfo()showfileinfo()openfile()path_init()其中:static _init int path_init( void ):插入內核時系統調用該函數對其初始化。static int openfile( char * ):自定義函數,根據插入內核時傳入的參數,打開相應的路徑獲取信息。static int showfileinfo( void ):說明路徑指向的是文件,并輸出文件inode結構體中的信息。s

11、tatic int showdirinfo( void ):說明路徑指向的是目錄,并輸出目錄dentry結構體中的信息。static _exit void path_exit( void ):移除內核時系統調用該函數輸出相應信息。showfileinfo()(是)傳參:文件狀態stat、文件名、有參數u標志有參數-lshowfilename()(否)傳入參數:文件名參數有-r,傳入參數:當前找到的子目錄的完整路徑hasdir()(否)顯示目錄下的文件名,傳參:命令行參數、文件路徑(是)傳參:命令行參數、子目錄完整路徑有-r有-u無-lcompare()(否)compareu()(是)dispo

12、separam()(文件)傳參:命令參數、路徑dirread()(無路徑、目錄)傳參:命令參數、路徑判斷路徑main()2各功能函數的數據流程圖(1)、實現lsclose()sleep()read()open()傳參:文件描述符、存儲讀取文件內容的buf、讀取文件長度程序睡眠20秒睡眠結束,繼續讀文件內容,傳參:文件描述符、存儲讀取文件內容的buf、讀取文件長度關閉文件再次打開文件,查看權限(2) 、修改文件權限(3) 、調試例子spin_unlock()list_entry()list_for_eachspin_lock()插入內核需要參數:sb_lock_address 傳參:鏈表結點,超

13、級塊地址鏈表頭 傳參:鏈表頭、超級塊類型、存儲所有超級塊信息的鏈表遍歷各超級塊的索引號節點并獲取索引結點的信息(4)、內核傳參路徑非法,顯示錯誤信息path_exit()showdirinfo()showfileinfo()openfile()path_init()傳參:絕對路徑文件目錄路徑3重點設計及編碼(1)、實現lsu 在只有-u的情況下按照最后訪問時間由近到遠排序,調用的是系統排序方法qsort( filepaths, count, sizeof( filepaths 0 ), compareu );其中compareu()是自定義的排序函數。int compareu( const v

14、oid *first, const void *last )struct stat buf1, buf2;stat( ( char * )first, &buf1);stat( ( char * )last, &buf2);return ( ( int )buf2.st_atime - ( int )buf1.st_atime );u 實現-r的功能。在void disposeparam( int paramflag, char *filepath )函數中查找當前目錄下存在的子目錄。if ( ( paramflag = 8 ) & s_isdir( buf.st_mode ) & strcm

15、p( filename, . ) & strcmp( filename, . ) & hasdirs( filepath ) = 0 )/ 判斷為目錄時過濾.和.并且若該目錄沒有被找出strcpy( dirpath dircount , filepath );hasdir = 1;/ 標志,在當前目錄下找到子目錄dircount+;/ 更新子目錄數然后再void dirread( int paramflag, char *path )函數中遞歸調用自身來顯示子目錄的相關內容。if ( paramflag = param_r & hasdir = 1 )/ 將子目錄的hasdir標志位置0,表示

16、子目錄下還未找到其子目錄hasdir = 0;for ( dirshow; dirshow dircount; )/ -l輸出總用量置0,-a分欄寬度置maxchar,遞歸調用自身total = 0;restlen = line;printf( n%s:n, dirpath dirshow );dirread( paramflag, dirpath dirshow+ );(2)、內核傳參u 判斷路徑指向的文件類型:file = filp_open( path, o_directory, 0 );if ( is_err( file ) )/ 不成功則以文件形式打開file = filp_open

17、( path, o_rdonly, 0444 );if ( is_err( file ) )/ 路徑錯誤printk( the paht %s failed!n, path );return 0;/ 該路徑指向一個文件printk( this is file!n );showfileinfo();filp_close( file, null );return 0;else/ 該路徑指向一個目錄printk( this is diretory!n );showdirinfo();filp_close( file, null );return 0;五測試數據及運行結果1正常測試數據和運行結果(1)

18、、實現lsu 無參有路徑的情況:u 無參數的情況、只有-a的情況、只有-u的情況:有上述的情況可以看出:如果用了-u而不用-l,輸出的文件名會按最后訪問時間由近到遠的順序而不是按字典順序排序。u 對比-l和-lu的輸出不同情況:不同之處在于輸出的時間,-l輸出最近修改時間,-lu輸出最近訪問時間。并且在-l的情況下會輸出三個特殊屬性sgid、suid、sticky位。u -r的情況:遞歸顯示子目錄信息u -aulr組合情況:(2) 、修改文件權限調用sleep()等待20s以后,再讀一些內容,從另外的終端,再等待的20s內去掉文件的讀權限,但是程序還是能從文件中讀取出內容。當再一次打開文件時由

19、于無權限,文件打開錯誤。(3) 、調試例子u 查看程序中涉及的兩個全局變量:cat /proc/kallsyms | grep super_blocks結果:ffffffff81c4f3c0 d super_blockscat /proc/kallsyms | grep super_blocks結果:ffffffff81f027a0 b sb_lock u 運行結果:(部分內容)(4) 、內核傳參u 當路徑指向文件時,顯示文件inode信息:當路徑指向目錄時,顯示目錄dentry信息:2異常測試數據及運行結果(1)、實現ls(2)、修改文件權限(3)、內核傳參六調試情況,設計技巧及體會1改進方

20、案本次實驗完成的很不錯。在實現ls的功能中,完成了所有的要求,可以改進的地方有:將分欄情況模擬成系統顯示的效果(以列為主,以各列的文件名最大值為欄寬),而不是簡單的以行為主,以所有的文件名中最大值為欄寬;使用-r參數時,應使用鏈表結構而不是數組結構,這樣不會因為遞歸太深,子目錄太多而造成的越界現象。在實現內核傳遞參數的功能中,完成了所有的功能,可以的改進的地方就是盡可能的輸出有用的信息。2體會通過本次實驗,我實現了ls這個shell命令,為之后設計操作系統打下基礎;通過控制文件的訪問權限我理解了文件操作的工作原理;編寫內核代碼讓我掌握了通過命令傳入參數的方法。通過上網查找資料、查看課本等途徑,

21、讓我的自學能力更進一步,對linux和操作系統的知識理解得更加的深入。七參考文獻1linux操作系統原理與應用m. 陳莉君,康華編著. 第二版. 北京:清華大學出版社,2012.2 美molay.b 著. unix/linux編程實踐教程m. 楊宗源,黃海濤譯. 北京:清華大學出版社,2004.3 鳥哥. 鳥哥的linux私房菜m. 王世江,改編. 第三版. 北京:人民郵電出版社,2011.八附錄:1.ls#include #include #include #include #include #include #include #include #include #include #defi

22、neparam_none0/ 無參數#defineparam_a1/ -a: 顯示所有文件#defineparam_l2/ -l:一行顯示一個文件的詳細信息#define param_u4/ -u:顯示文件最后一次訪問時間#define param_r8/ -r:遞歸顯示文件與子目錄及其內容#define pathcount10/ 遞歸顯示目錄功能中子目錄的數量int restlen = 0;/ -l打印詳細信息時一行剩余長度int maxfilelen = 0;/ 存放某目錄下最長的文件名的長度int total = 0;/ -l顯示的總用量int hasdir = 0;/ -r中標志位,在

23、當前目錄下是否找到子目錄int dircount = 0;/ -r中目前遞歸找到的子目錄的數量int dirshow = 0;/ -r已顯示相關信息的子目錄的數量int line = 0;/ 屏幕的寬度char dirpath pathcount path_max + 1 = 0 ;/ -r中存儲子目錄路徑void dirread( int, char * );int compare( const void *, const void * );int compareu( const void *, const void * );void disposeparam( int, char * );

24、int hasdirs( char * );void showfilename( char * );void showfilesinfo( struct stat, char *, int );int main( int argc, char * argv )int i, j, k;int paramcount, paramflag;char path path_max + 1 ;/ 保存命令行中路徑char params 20 ;/ 存儲參數struct stat st;struct winsize size;j = 0;paramcount = 0;/ 帶參數的命令行數量paramflag

25、 = param_none;/ 參數標志位,初始無餐/ 獲取屏幕寬度ioctl(stdout_fileno, tiocgwinsz, &size);line = size.ws_col;restlen = line;/ 讀取命令行中的參數for ( i = 1; i argc; i+ ) if ( argv i 0 = - ) for ( k = 1; k strlen( argv i ); k+, j+ )params j = argv i k ;paramcount+;params j = 0;/ 判斷當前命令的參數,更新參數標記位for (i = 0; i j; i+) switch(

26、params i )case a:paramflag |= param_a;break;case l:paramflag |= param_l;break;case u:paramflag |= param_u;break;case r:paramflag |= param_r;break;default:printf( 有未知的參數存在!n );return 0;/ 沒有路徑,顯示當前目錄if ( ( paramcount + 1 ) = argc ) strcpy( path, ./0 );dirread( paramflag, path );return 0;/ 有路經,判斷路徑非法、是

27、目錄、是文件i = 1 + paramcount;do strcpy( path, argvi );if ( stat( path, &st ) = -1 )/ 路徑非法printf( 目標文件或目錄%s不存在!n, path );return 0;/ 路徑為目錄if ( s_isdir( st.st_mode ) ) dirread( paramflag, path );else/ 路徑為文件disposeparam( paramflag, path );i+; while (i pw_name );/ 打印所有者的用戶名printf( %6s, grp-gr_name );/ 打印組名pr

28、intf( %7ld , (long)buf.st_size ); / 打印文件的大小 if ( hasu = 0 )strcpy( buf_time, ctime( &buf.st_mtime ) );/ 最后一次修改時間elsestrcpy( buf_time, ctime( &buf.st_atime ) );/ 最后一次訪問時間buf_time strlen( buf_time ) - 1 = 0;/ 去掉換行符printf( %s, buf_time );/ 打印文件的時間信息printf( %sn, filename );/ 打印文件名字total += (int)buf.st_b

29、locks;/ 計算當前目錄所有文件的總用量/ 沒有-l,只打印文件名并分欄對齊void showfilename( char *filename )int i, len;/ 本行剩余長度不足已顯示下一個文件名,換行if ( restlen maxfilelen ) printf( n );restlen = line;/ 打印文件名并分欄len = maxfilelen - strlen( filename );/ 當前顯示欄的剩余長度printf( %s , filename );/ 打印文件名if ( (int)* filename 0 )/ 文件名若為中文len += 2;for (

30、i = 0; i len; i+ )/ 當前欄剩余處打印空格printf( );restlen -= ( maxfilelen );/ 更新當前行的剩余長度/ -r下判斷是否已知參數路徑為一個目錄路徑int hasdirs( char *filepath )int i;for ( i = 0; i dircount; i+)if ( strcmp( filepath, dirpath i ) = 0 )return 1;return 0;/ 分析參數并分別執行不同的操作void disposeparam( int paramflag, char *filepath )struct stat b

31、uf;int i, j, hasu;char filename name_max + 1 ;/ 存儲文件名hasu = 0;/ 從完整路徑中解析文件名for ( i = 0, j = 0; i = 8 ) & s_isdir( buf.st_mode ) & strcmp( filename, . ) & strcmp( filename, . ) & hasdirs( filepath ) = 0 )/ 判斷為目錄時過濾.和.并且若該目錄沒有被找出strcpy( dirpath dircount , filepath );hasdir = 1;/ 標志,在當前目錄下找到子目錄dircount

32、+;/ 更新子目錄數/ 對參數分類操作if ( paramflag = 0 | paramflag = 4 | paramflag = 8 | paramflag = 12)/ paramflag為下列情況:param_none,param_u,param_r,param_u + param_rif ( filename 0 != . ) showfilename( filename );else if ( paramflag = 1 | paramflag = 5 | paramflag = 9 | paramflag = 13)/ paramflag為下列情況:param_a,param_

33、a + param_u,param_a + param_r,param_a + param_u + param_rshowfilename( filename );else if ( paramflag = 2 | paramflag = 10 )/ paramflag為下列情況:param_l,param_l + param_rif ( filename 0 != . ) showfilesinfo( buf, filename, hasu );else if ( paramflag = 3 | paramflag = 11 )/ paramflag為下列情況:param_a + param

34、_l,param_a + param_l + param_rshowfilesinfo( buf, filename, hasu );else if ( paramflag = 6 | paramflag = 14 )/ paramflag為下列情況:param_l + param_u,param_l + param_u + param_rhasu = 1;if ( filename 0 != . )showfilesinfo( buf, filename, hasu );else if ( paramflag = 7 | paramflag = 15 )/ paramflag為下列情況:pa

35、ram_a + param_l + param_u,param_l + param_u + param_a + param_rhasu = 1;showfilesinfo( buf, filename, hasu );elseprintf( 參數出現錯誤匹配或存在未知參數!n );exit( 0 );/ 調用系統排序函數,按字典順序排序int compare( const void *first, const void *last )return strcmp( (char *)first, (char *)last );/ 調用系統排序函數,按最近訪問時間排序int compareu( co

36、nst void *first, const void *last )struct stat buf1, buf2;stat( ( char * )first, &buf1);stat( ( char * )last, &buf2);return ( ( int )buf2.st_atime - ( int )buf1.st_atime );/ 讀取當前目錄下的內容void dirread( int paramflag, char *path ) struct dirent *dt;/ 獲取文件的信息dir *dir;/ 目錄流 int i, j, count;char filepaths 2

37、56 path_max + 1 = ;/ 存儲文件的完整路徑count = 0;/ 記錄當前目錄下包含的文件和子目錄的名字maxfilelen = 0;/ 初始化當前目錄下文件名的最大值/ 完善完整路徑,若目錄的最后一個字符不是/,則加上if ( path strlen(path)-1 != /) strcat( path, / );strcat( path, 0 );/ 打開目錄,遍歷目錄下的文件并獲取其信息 dir = opendir( path ); while ( ( dt = readdir( dir ) ) != null ) if ( maxfilelen d_name ) )m

38、axfilelen = strlen( dt-d_name ) + 1; count+; closedir( dir );/ 關閉目錄流/ 打開目錄,獲取該目錄下所有的文件名的完整路徑 dir = opendir( path );/再次打開路徑 for ( i = 0; i d_name ); filepaths i strlen( path ) + strlen( dt-d_name ) = 0; closedir( dir );/ 調用系統排序方法排序/ 所有有-u但沒有-l的時候按照最近訪問時間排序,其他按字典排序if ( ( paramflag & param_u ) = 4 & (

39、paramflag & param_l ) = 0 )qsort( filepaths, count, sizeof( filepaths 0 ), compareu );elseqsort( filepaths, count, sizeof( filepaths 0 ), compare );/ 逐個顯示該目錄下的文件或子目錄的信息 for ( i = 0; i = param_r & hasdir = 1 )/ 將子目錄的hasdir標志位置0,表示子目錄下還未找到其子目錄hasdir = 0;for ( dirshow; dirshow dircount; )/ -l輸出總用量置0,-a

40、分欄寬度置maxchar,遞歸調用自身total = 0;restlen = line;printf( n%s:n, dirpath dirshow );dirread( paramflag, dirpath dirshow+ );2. 文件權限#include #include #include #include void main( int argc, char *argv )int fd, n;char buf 15 ;/ 沒有輸入目標文件if ( argc = 1 )printf( 輸入錯誤,請按照如下格式:n./my_file 文件名或文件路徑n );exit( 0 );/ 第一次打

41、開文件fd = open( argv1, o_rdonly );if ( fd = -1 )printf( 文件打開錯誤,文件權限不夠或不存在!n );exit( 0 );/ 首次讀取文件的內容printf( 第一次打開文件操作n );n = read( fd, buf, 10 );buf n = 0;printf( no.1 讀取了%d字節的數據:%s, n, buf );printf( 修改文件權限n );sleep( 20 );/ 睡眠20秒/ 再次讀取文件內容printf( n睡眠10秒結束n );n = read( fd, buf, 10 );buf n = 0;printf( no.2 讀取了

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論