linux中的read和write系統呼叫
linux中read和write系統呼叫
在這裡小koala著重於read()和write()來讀寫普通檔案,因為小koala在編寫實際檔案讀寫函式時,疏忽了一些重要的地方,造成無休止的向系統中寫資料,最後系統崩潰。當時瞬間“三觀”盡毀。現在較為詳細地分析錯誤的原因,有問題或是模糊的話,希望大神們告訴小koala,先行謝過了。
在《深入理解linux核心》中虛擬檔案系統一章中有這樣的說明:
VFS所隱含的主要思想在於引入了一個通用的檔案模型(common file model),這個模型能夠表示所有支援的檔案系統。linux核心對每個檔案讀寫操作都必須使用一個指標,指向要訪問的具體檔案系統的適當函式。換句話說,當應用程式對read()或是write()呼叫引起核心呼叫相應的sys_read()或是sys_write()服務例程,檔案在核心記憶體中是由一個file資料結構來表示的。這種資料結構中包含一個稱為f_op的欄位,該欄位中包含一個指向專對某一個檔案系統(如sysfs虛擬檔案系統)的讀寫函式指標,sys_read()或是sys_write()查詢到指向該函式的指標,並呼叫它。這樣一來,應用程式的read()或是write()就被轉化為相對間接的呼叫:
file->f_op->read() 或 file->f_op->write()
read()系統呼叫
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbytes);
在man手冊中是這樣解釋的:
read() attempts t read up to count bytes from file descriptor fd into the buffer starting at buf. on files that support seeking, the read operation commences at the current file offset, and the file offset is incremented by the number of bytes read. if the current file offset is at or past the end of file,no bytes are read, and read() return zero.(有部分省略)
write()系統呼叫
#include <unistd.h>
ssize_t write(int fd, void *buf, size_t nbytes);
在man手冊中是這樣解釋的:
write() writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd. The number of bytes written may be less than count if ,for example, there si insufficient space on the underlying physical medium. for a seekable file writing takes place at the current file offset, and the file offset is incremented by the number of bytes actually written.(有部分省略)
但是現在我想著重分析的是返回值!!分析我出現錯誤的原因歸根到底是在返回值中。
read()返回值:讀到的位元組數,若已到檔案尾,返回0;若錯誤發生,返回-1。
write()返回值:通常與引數nbytes相同,否則表示出錯!!!這裡的潛在意思有兩層:1 若返回-1,那麼寫操作失敗。 2(針對於具體檔案的寫操作file->f_op->write()指向的函式)返回值小於nbytes時,核心很可能會再次寫餘下的資料,形成死迴圈,檔案系統寫滿,系統掛了!!!
所以在寫實際的檔案系統的寫操作時一定注意其返回值,否則可能系統崩潰了。