2012-11-04 42 views
0

下面的代碼在由於信號中斷而失敗時重新啓動read()函數。 read()從它被中斷的地方恢復閱讀。因此,如果read()在讀取EOF字符之前中斷,它會返回多少字節它讀取?Unix系統中的文件讀取()函數

int r_read(int fd, void *buf, int size) 
{ 
    while((retval=read(fd,buf,size))==-1 && errno ==EINTR); 
    return retval; 
} 

問候。

+0

有沒有這樣的事情'EOF'字符。 – alk

回答

2

如果errno == EINTR,則表示read在它根據man頁面可以讀取任何數據之前被中斷。即從我的閱讀中,就好像一個read的狀態EINTR就沒有發生就流中的數據而言。因此,您似乎可以簡單地重試而不必擔心丟失了任何字節。我覺得這有點令人驚訝,而且我沒有真正測試過它,但這就是手冊所說的。

這裏是從該名男子頁的實際文本:

EINTR被信號中斷任何數據被讀取之前調用;見信號(7)。

編輯:我現在測試了這個,我發現如果我中斷了讀取,只有在讀取之前中斷讀取才會返回EINTR。否則,它將成功返回,讀取的字節數少於請求的數量。因此,要獲得所需的字節數,您需要重新啓動,如其他答案所示。

+0

與我在想的一樣,但是我的教科書沒有提及它,並且我所做的返回的字節數是總和,正如Brette Hale所提到的。 – Naruto

3

這就是爲什麼讀取的字節數應該保持爲總數,以避免中斷問題。它對於非阻塞I/O也很有用。

{ 
    int ret = 0, nread; 
    char *nbuf = (char *) buf; 

    while ((nread = read(fd, nbuf, size)) != 0) 
    { 
     if (nread > 0) 
      ret += nread, nbuf += nread, size -= nread; 
     elif (errno != EINTR) 
      break; 
    } 

    return ret; 
} 
+0

'read()'需要'size_t'並返回'ssize_t'而不是'int'。 – alk

0

沒有「EOF字符」,因此存在文件結束條件,該條件表示爲0字節的讀取。 EINTR錯誤僅在read在等待某事發生時中斷,即之前底層資源產生任何數據時設置。

由於EOF通常會導致read停止等待並返回一個值,因此不會中斷read,如果這樣做,它只會返回它具有的EOF指示符。如果read被中斷,而等待用於EOF(在它被底層資源公佈之前),它當然會返回-1並設置EINTR。

+0

假設read()函數讀取了10個字節的數據並存儲在buffer中。現在如果unix中的read()函數被信號中斷,並且我重新啓動了讀取函數(如上所示),那麼將在下一個字節中存儲緩衝區,currentposition + 1或將從緩衝區的開始寫入。 – Naruto

+0

@UmerFarooq如果'read'在讀完10個字節後中斷,它將返回10,您的函數也會返回。 'errno'將保持不變。 – user4815162342