2015-09-22 63 views
1

Advanced Programming in the UNIX Environnement引用(頁505),第13.6節:瞭解文件截斷

我們需要截斷該文件,因爲 守護程序的上一個實例可能有一個進程ID比我們大,具有較大的 字符串長度。例如,如果守護程序 的先前實例是進程ID 12345,並且新實例是進程ID 9999,那麼當我們 將進程ID寫入文件時,我們將在 文件中留下99995。截斷文件會阻止前一個守護進程 的數據顯示爲應用於當前守護進程。

這有人評論此功能:

already_running(void) 
{ 
    int fd; 
    char buf[16]; 
    fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE); 
    if (fd < 0) { 
     syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno)); 
     exit(1); 
    } 
    if (lockfile(fd) < 0) { 
     if (errno == EACCES || errno == EAGAIN) { 
      close(fd); 
      return(1); 
     } 
     syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno)); 
     exit(1); 
    } 
    ftruncate(fd, 0); 
    sprintf(buf, "%ld", (long)getpid()); 
    write(fd, buf, strlen(buf)+1); 
    return 0; 
} 

我不明白這是怎麼可能的行爲,以及文件截斷如何防止發生這種行爲。有人可以解釋這一點嗎?

感謝您的回答!

+1

的調用' ftruncate'在重寫文件之前將文件長度重置爲0,這樣就不可能在文件的新版本中存在任何以前的內容(如果之前的內容大於新內容,可能會發生這種情況)。 –

+0

是的,但只有在您要覆蓋現有文件時纔有必要,並且新內容可能會比舊內容短。否則它是多餘的(但無害)。 –

回答

4

在上面的例子中,文件最初是5個字節長。當您打開它進行寫入,並且在不截斷的情況下將字符串「9999」寫入它時,它將僅覆蓋前4個字節,並將第5個字節留在原地。因此該文件將讀取「99995」。截斷將文件長度設置爲0,有效地刪除以前的內容。

1

Hellmar已經提供的回答你的問題 - 但在縮短代碼的興趣,你可以簡化公開徵集到:

already_running(void) 
{ 
    int fd; 
    char buf[16]; 
    fd = open(LOCKFILE, O_RDWR|O_CREAT|O_TRUNC, LOCKMODE); 
    ... 

的(誰不喜歡代碼高爾夫?)將O_TRUNC添加到標誌將導致該文件被截斷。 http://linux.die.net/man/2/open

如果該文件已經存在,並且是一個普通文件和開放模式 允許寫入(即是O_RDWR或O_WRONLY)也將被截斷,以 長度爲0