生活随笔
收集整理的這篇文章主要介紹了
操作系统实践(四/五)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
??本次實(shí)驗(yàn)課的內(nèi)容涉及到以下幾個(gè)方面: ????1.文件的內(nèi)核實(shí)現(xiàn) ????2.標(biāo)準(zhǔn)的輸入輸出 ????3.系統(tǒng)調(diào)用dup和pipe
??文件最基本的系統(tǒng)調(diào)用是open和close,open一個(gè)文件后會(huì)返回一個(gè)fd,作為這個(gè)文件的標(biāo)識(shí),后續(xù)有關(guān)于這個(gè)文件的操作都使用fd去完成。
1.文件的內(nèi)核實(shí)現(xiàn)
??文件的內(nèi)核實(shí)現(xiàn)中圍繞著四個(gè)結(jié)構(gòu)體:索引節(jié)點(diǎn)、file結(jié)構(gòu)體、文件描述符表、進(jìn)程控制塊。下面介紹下它們各自存儲(chǔ)的內(nèi)容: ??索引節(jié)點(diǎn)中保存了文件的大小、文件存放在磁盤的位置、文件的創(chuàng)建時(shí)間、修改時(shí)間、文件的所有者、文件的訪問權(quán)限 ??file結(jié)構(gòu)體file結(jié)構(gòu)體存了被打開文件的信息、文件對(duì)應(yīng)的索引節(jié)點(diǎn)(inode)、文件的當(dāng)前訪問位置、文件的打開模式(只讀、只寫、可讀可寫) ??文件描述符表是一個(gè)數(shù)組,數(shù)組的元素類型是指針,指針指向一個(gè)file結(jié)構(gòu)體,用于保存被打開的文件。當(dāng)內(nèi)核打開文件時(shí),分配一個(gè)file結(jié)構(gòu)體表示被打開的文件,將該file結(jié)構(gòu)體指針保存在文件描述符表中 ??進(jìn)程控制塊是操作系統(tǒng)表示進(jìn)程狀態(tài)的數(shù)據(jù)結(jié)構(gòu),存放用于描述進(jìn)程情況及控制進(jìn)程運(yùn)行所需的全部信息(進(jìn)程標(biāo)識(shí)信息、處理機(jī)狀態(tài)、進(jìn)程調(diào)度信息、打開文件列表,即文件描述符表,記錄了該進(jìn)程打開的文件)
2.標(biāo)準(zhǔn)的輸入輸出
??標(biāo)準(zhǔn)的輸入輸出就是指write和read
write ( 1 , buf
, sizeof ( buf
) ) ;
read ( 0 , buf
, sizeof ( buf
) ) ;
3.系統(tǒng)調(diào)用dup和pipe
?? dup(重定向) ??dup就是讓一個(gè)新的fd去指向一個(gè)文件,這樣文件就有了兩個(gè)指向。可以把老fd解放出來,去完成其他操作。 還有一個(gè)變形的dup2,完成一樣的功能。調(diào)用方式不同 ??pipe(管道) ??pipe的實(shí)現(xiàn)是基于隊(duì)列,一端作為輸入端,一端作為輸出端。整體結(jié)構(gòu)如下: ??以上就是這次實(shí)驗(yàn)課的全部理論學(xué)習(xí)啦,下面看看作業(yè)吧!這次的作業(yè)沒有關(guān)于dup和pipe的內(nèi)容,是上節(jié)課mysys實(shí)現(xiàn)的變形。 ??源代碼如下:
#include
< stdio
. h
>
#include
< unistd
. h
>
#include
< stdlib
. h
>
#include
< sys
/ types
. h
>
#include
< sys
/ wait
. h
>
#include
< string
. h
> void mysys ( char
* command
) { char
* argv
[ 512 ] ; int num
= 0 ; char temp
[ 512 ] ; for ( int i
= 0 ; command
[ i
] != '\0' ; i
++ ) { int index
= 0 ; while ( command
[ i
] != '\0' && command
[ i
] != ' ' ) { temp
[ index
++ ] = command
[ i
++ ] ; } temp
[ index
] = '\0' ; if ( command
[ i
] == '\0' ) break ; argv
[ num
] = ( char
* ) malloc ( strlen ( temp
) ) ; strcpy ( argv
[ num
] , temp
) ; num
++ ; } argv
[ num
] = ( char
* ) malloc ( strlen ( temp
) ) ; strcpy ( argv
[ num
] , temp
) ; num
++ ; argv
[ num
] = NULL ; pid_t pid
; if ( command
== NULL ) return ; if ( ( pid
= fork ( ) ) < 0 ) { } else if ( pid
== 0 ) { execvp ( argv
[ 0 ] , argv
) ; exit ( 127 ) ; } else { sleep ( 1 ) ; } return ;
} int
main ( ) { while ( 1 ) { write ( 1 , "> " , 3 ) ; char buf
[ 80 ] ; int count
; count
= read ( 0 , buf
, sizeof ( buf
) ) ; buf
[ count
- 1 ] = 0 ; if ( strcmp ( buf
, "exit" ) == 0 ) break ; mysys ( buf
) ; } return 0 ;
}
??第四次,打板兒!
??第五次的內(nèi)容和上次一樣的,區(qū)別的是作業(yè),就寫在一篇里了。 ??源代碼如下:
#include
< stdio
. h
>
#include
< unistd
. h
>
#include
< stdlib
. h
>
#include
< sys
/ types
. h
>
#include
< sys
/ wait
. h
>
#include
< string
. h
>
#include
< sys
/ stat
. h
>
#include
< fcntl
. h
> void mysys ( char
* command
) { char
* argv
[ 512 ] ; int num
= 0 ; char temp
[ 512 ] ; for ( int i
= 0 ; command
[ i
] != '\0' ; i
++ ) { int index
= 0 ; while ( command
[ i
] != '\0' && command
[ i
] != ' ' ) { temp
[ index
++ ] = command
[ i
++ ] ; } temp
[ index
] = '\0' ; if ( command
[ i
] == '\0' ) break ; argv
[ num
] = ( char
* ) malloc ( strlen ( temp
) ) ; strcpy ( argv
[ num
] , temp
) ; num
++ ; } argv
[ num
] = ( char
* ) malloc ( strlen ( temp
) ) ; strcpy ( argv
[ num
] , temp
) ; num
++ ; argv
[ num
] = NULL ; pid_t pid
; if ( command
== NULL ) return ; if ( ( pid
= fork ( ) ) < 0 ) { } else if ( pid
== 0 ) { if ( strcmp ( argv
[ 0 ] , "echo" ) == 0 ) { int i
, j
; int tag
= 0 ; for ( i
= 0 ; i
< num
; i
++ ) { for ( j
= 0 ; argv
[ i
] [ j
] != '\0' ; j
++ ) { if ( argv
[ i
] [ j
] = '>' && argv
[ i
] [ j
+ 1 ] != '\0' && i
== num
- 1 ) { tag
= 1 ; break ; } } if ( tag
== 1 ) break ; } if ( tag
== 1 ) { char filename
[ 10 ] ; int filename_index
= 0 ; for ( int j
= 1 ; argv
[ i
] [ j
] != '\0' ; j
++ ) { filename
[ filename_index
++ ] = argv
[ i
] [ j
] ; } filename
[ filename_index
] = '\0' ; char content
[ 20 ] ; int content_index
= 0 ; for ( int k
= 5 ; command
[ k
] != '\0' ; k
++ ) { if ( command
[ k
] == '>' ) { content
[ content_index
] = '\0' ; break ; } else content
[ content_index
++ ] = command
[ k
] ; } int fd
; fd
= open ( filename
, O_CREAT | O_RDWR , 0777 ) ; dup2 ( fd
, 1 ) ; write ( 1 , content
, sizeof ( content
) ) ; } else { execvp ( argv
[ 0 ] , argv
) ; } } else execvp ( argv
[ 0 ] , argv
) ; exit ( 127 ) ; } else { sleep ( 1 ) ; } return ;
} int
main ( ) { while ( 1 ) { write ( 1 , "> " , 3 ) ; char buf
[ 80 ] ; int count
; count
= read ( 0 , buf
, sizeof ( buf
) ) ; buf
[ count
- 1 ] = 0 ; if ( strcmp ( buf
, "exit" ) == 0 ) break ; mysys ( buf
) ; } return 0 ;
}
??這次的作業(yè)主要是增加一個(gè)要求:echo另外一個(gè)內(nèi)容寫入指定文件(之前的echo是輸出到屏幕,重定向后將1號(hào)指向文件,就不會(huì)在上輸出了)。但悲催的是:我這份代碼能夠完成新功能,對(duì)于普通功能的echo沒用了(嗚嗚嗚),也就是echo a b c沒了反應(yīng),到現(xiàn)在也沒找到問題。如果有人看出來,請?jiān)谙路皆u(píng)論區(qū)留言,感謝!
??上節(jié)課老師還讓實(shí)現(xiàn)pwd,cd,使用execvp無法完成,想了好久都沒有結(jié)果,但其實(shí)是有系統(tǒng)調(diào)用的:
char
* cwd
= getcwd ( buff
, sizeof ( buff
) ) ;
chdir ( comnd
[ 1 ] ) ;
因作者水平有限,如有錯(cuò)誤之處,請?jiān)谙路皆u(píng)論區(qū)指正,謝謝!
新人創(chuàng)作打卡挑戰(zhàn)賽 發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!
總結(jié)
以上是生活随笔 為你收集整理的操作系统实践(四/五) 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。