UNIX安全讀寫函數——readn和writen
前言:位元組流套接字(TCP套接字)上的read和write函數所表現的行為不同于通常的檔案I/O。位元組流套接字調用read或write輸入或輸出的位元組數可能比請求的數量少,然而這并不是出錯的狀态。這是因為核心中用于套接字的緩沖區可能達到了極限。通常這種情況出現在一次讀多于4096個位元組或write在非阻塞情況下傳回不足位元組數。為了不多次調用read或防止write傳回不足位元組數,我們用下面的兩個函數來替代read和write。
readn
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
ssize_t safe_read(int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr=vptr;
nleft=n;
while(nleft > )
{
if((nread = read(fd,ptr,nleft)) < )
{
if(errno == EINTR) //被信号中斷,重讀
nread = ;
else //出錯
return -;
}
else if(nread == ) //EOF
break;
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}
writen
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
ssize_t safe_write(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while(nleft > )
{
if((nwritten = write(fd, ptr, nleft)) <= )
{
if(nwritten < && errno == EINTR) //被信号中斷,重寫
nwritten = ;
else //error
return -;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
總結
上面介紹了兩個安全讀寫函數,但是并不意味着這兩個函數在任何地方都完全适用,是以不要強迫自己使用。需要注意阻塞、效率等問題,當你隻是讀寫少量位元組時,就沒必要使用了。
回報與建議
- 微網誌:@AnSwEr不是答案
- github:AnSwErYWJ
- 部落格:AnSwEr不是答案的專欄