errno!=EINTR

errno!=EINTR注意read()如果讀到數據爲0,那麼就表示文件結束了,如果在讀的過程中遇到了中斷那麼會返回-1,同時置errno爲EINTR。 因此判斷read的條件: 如果read返回<=0 如果==0 表示文件結束, 處理 如果<0 && errno==EINTR 表示中斷,處理 否則,出錯 但是write()如果寫入的數據爲0,那麼就表示出錯,也就是無法寫入了,而如果在寫的過程中遇到了中斷,那麼write()會返回-1,同時置errno爲EINTR。 因此判斷write是否成功時,條件是write返回的結果是否<=0 if<=0 { if<0 if="" errno="=EINTR" else="" if="=0" break="" ssize_t="" readn="" int="" fd="" void="" vptr="" size_t="" n="" size_t="" nleft="" ssize_t="" nread="" char="" ptr="" ptr="vptr;" nleft="n;" while="" nleft="">0 ) { if ( ( nread = read ( fd,ptr,nleft ) ) < 0 ) { if ( errno == EINTR ) nread = 0; else return ( -1 ); } nleft-=nread; ptr+=nread; } return ( n-nleft ); } ssize_t writen ( int fd, const void *ptr, size_t n ) { size_t nleft; ssize_t nwritten; const char *ptr; ptr=vptr; nleft=n; while ( nleft>0 ) { if( ( nwritten=write( fd, ptr, nleft ) )<=0 ) { if( nwritten<0 && errno == EINTR ) nwritten = 0; else return (-1); } nleft-=nwritten; ptr+=nwritten; } return (n); } 寫函數write ssize_t write(int fd,const void *buf,size_t nbytes) write函數將buf中的nbytes字節內容寫入文件描述符fd。成功時返回寫的字節數,失敗時返回-1,並設置errno變量。 在網絡程序中,當我們向套接字文件描述符寫時有倆種可能: 1) write的返回值大於0,表示寫了部分或者是全部的數據; 2) 返回的值小於0,此時出現了錯誤,我們要根據錯誤類型來處理。 如果錯誤爲EINTR表示在寫的時候出現了中斷錯誤。如果爲EPIPE表示網絡連接出現了問題(對方已經關閉了連接)。 讀函數read   ssize_t read(int fd,void *buf,size_t nbyte)   read函數是負責從fd中讀取內容。當讀成功時,read返回實際所讀的字節數。如果返回的值是0,表示已經讀到文件的結束了。小於0表示出現了錯誤。如果錯誤爲EINTR說明讀是由中斷引起的,如果是ECONNREST表示網絡連接出了問題。

 

一下是學習時讀的代碼:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>

#define BUFFER_SIZE 1024

int main(int argc,char **argv)
{

int from_fd,to_fd;
int bytes_read,bytes_write;
char buffer[BUFFER_SIZE];
char *ptr;

if(argc!=3)
{
fprintf(stderr,"Usage:%s fromfile tofile/n/a",argv[0]);
exit(1);
}

/* 打開源文件 */

if((from_fd=open(argv[1],O_RDONLY))==-1)
{
fprintf(stderr,"Open %s Error:%s/n",argv[1],strerror(errno));
exit(1);
}

/* 創建目的文件 */

if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)
{
fprintf(stderr,"Open %s Error:%s/n",argv[2],strerror(errno));
exit(1);
}

/* 以下代碼是一個經典的拷貝文件的代碼 */

while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
{
/* 一個致命的錯誤發生了 */
if((bytes_read==-1)&&(errno!=EINTR)) break;
else if(bytes_read>0)
{
ptr=buffer;
while(bytes_write=write(to_fd,ptr,bytes_read))
{
/* 一個致命錯誤發生了 */
if((bytes_write==-1)&&(errno!=EINTR))break;
/* 寫完了所有讀的字節 */
else if(bytes_write==bytes_read) break;
/* 只寫了一部分,繼續寫 */
else if(bytes_write>0)
{
ptr+=bytes_write;
bytes_read-=bytes_write;
}
}
/* 寫的時候發生的致命錯誤 */
if(bytes_write==-1)break;

}
}
close(from_fd);
close(to_fd);
exit(0);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章