阻塞讀
ssize_t ret;
vhile (len != 0 && (ret = read(fd, buf, len))!=0) {
if (ret = -1) {
if (errno == EINTR)
continue;
perror("read");
break;
}
len -= ret;
buf += ret;
}
這裏處理了5種情況,可以封裝爲一個新的read函數。
read調用原型
ssize_t read(int fd, void *buf, size_t len);
- 如果返回值 == 0,說明已經達到文件末尾(EOF)[情況1]
- 如果沒有數據可讀,調用回阻塞(sleep),直到有數據可讀
- 如果返回值 < 0,說明讀取過程中出錯。例如:
- EINTR,表示在讀取任何字節之前接收到信號。read調用可以重新執行 [情況2]
- 非EINTR,表示更嚴重錯誤,不能重新執行read調用 [情況3]
- 如果返回值 == len,讀取的所有len個字節都被保存到buf中 [情況4]
- 如果返回值 > 0 且 < len,有可能:
- 讀取過程中信號中斷/讀取中出錯;
- 可讀數據大於0字節小於len字節;
- 在讀取len之前到達了EOF
- 可以再次執行read調用,把剩餘字節讀入緩衝區或者給出錯誤信息 [情況5]
非阻塞讀
非阻塞讀可以避免沒有數據可讀時阻塞在哪裏,而是立即返回,表示沒有數據可讀。需要額外檢查errno值是否爲EAGIN
char buf[BUFFSIZE];
ssize_t nr;
start:
nr = read(fd, buf, BUFFSIZE];
if (nr == -1) {
if (errno == EINTR)
goto start;
if (errno == EAGAIN)
/* resubmit later*/
else
/* error */
}