2017-07-28 54 views
-1

我正在寫一份dup()函數(我正在爲Linux api學習一本書)。open()using O_APPEND does not update EOF

我有一個名爲temp.txt的文件,它包含一行以下字符串:Hello, World

下面是代碼:

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

//NAIVE IMPLEMENTATION 
int dup_t(int old) { 
    if(old == -1) { 
     errno = EBADF; 
     return -1; 
    } 

    int flags; 
    flags = fcntl(old, F_GETFL); 
    if(flags == - 1) { 
     errno = EBADF; 
     return -1; 
    } 

    int new; 
    if((new = fcntl(old, F_DUPFD)) == - 1) { 
     errno = EBADF; 
     return - 1; 
    } 
    return new; 
} 

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

    if(argc == 1) { 
     printf("Error, no arguments given\n"); 
     exit(-1); 
    } 

    int fd, cpfd; 

    if((fd = open(&argv[1][0], O_RDWR | O_APPEND)) == -1) { 
     printf("Error opening the file\n"); 
     exit(-1); 
    } 

    cpfd = dup_t(fd); 
    if(cpfd == -1) { 
     printf("Error dup_t()\n"); 
     exit(-1); 
    } 

    if(close(fd) == -1) { 
     printf("Error closing fd\n"); 
     exit(-1); 
    } 

    if(write(cpfd, "kostas", 6) == - 1) { 
     printf("Error writting\n"); 
     exit(-1); 
    } 

    if(close(fd) == -1) { 
     printf("Error closing fd\n"); 
     exit(-1); 
    } 

    if(write(cpfd, "kostas", 6) == - 1) { 
     printf("Error writting\n"); 
     exit(-1); 
    } 

    if(close(cpfd) == -1) { 
     printf("Error closing cpfd\n"); 
     exit(-1); 
    } 
} 

所以,通過運行./prog temp.txt成功,文件temp.txt必須包含以下字符串。 Hello, WorldKostas

通過運行以下命令cat temp.txt輸出我得到的是Hello, World,但是,如果我打開像nano文本編輯器中的文件,我得到Hello, World(後跟其中包含一個新行)kostas

爲什麼cat命令會產生錯誤的輸出? 爲什麼在字符串Hello, World的末尾添加了新行?

我不是在尋找解決方法,我有興趣找出錯誤/問題的原因。

+0

您可以創建您的初始溫度。txt文件,不包含使用'echo -n「Hello,World」> temp.txt'的行尾字符。 –

+0

'EOF'是C標準庫函數使用的一個宏,不是一個標誌,也不是真正存儲在文件中的,也不是Linux API的一部分(因此'''''''''''''''''''''''''''''''')。 – Olaf

+1

@ KostasRim:1)不要假設誰的評論也是一個downvoter。 2)即使用戶是否自己決定是否將您的問題視爲DV候選人。無論哪種方式,向一位評論者抱怨DV都會產生反作用:如果他是,他可能下次不會發表評論,但是會默默地DV;我不認爲這是你真正想要的。否則,DVer將不會閱讀投訴,並且評論者可能會僅僅因爲誣告而考慮DV。只是我的想法。 – Olaf

回答

1
  1. 的文件已更新爲:

    Hello, World[eol] 
    Kostas[no end-of-line here] 
    
  2. cat將輸出文件內容究竟,這慣於輸出最終停產,這是你的終端顯示cat後:

    bash> cat xxx 
    Hello, World 
    Kostasbash> 
    

注:bash>是你的提示下,有時你的提示符可能包含carrier return,這將使光標在該行的開始,考慮這種情況

輸出提示之前:

bash> cat xxx 
    Hello, World 
    Kostas 
      ^cursor here 

載體回來後:

bash> cat xxx 
    Hello, World 
    Kostas 
    ^cursor here 

最後輸出提示:

bash> cat xxx 
    Hello, World 
    bash> 
      ^cursor here 

因此,如果在文件末尾沒有eol,您的提示可能會覆蓋cat的最後一行輸出。

順便說一句:

  1. 當使用vim打開一個文件,[noeol]將顯示在底部左邊以指示在文件
  2. 的末尾而不EOL文件當使用zsh,一個%將示出如果最後一個命令在最後不輸出eol,並且zsh將輸出一個額外的eol。
+0

我的終端名稱是'kostas',所以確實在隔夜這個名字。終端上唯一的區別是在'kostas'中增加了額外的's'。這就像'kostass'。我甚至沒有注意到這樣一個小細節。感謝您的回答。 – KostasRim