天天看點

UNIX安全讀寫函數——readn和writenUNIX安全讀寫函數——readn和writen

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不是答案的專欄