unlink和close關系


 

今天看到nginx用文件鎖實現互斥的實現方案時,發現,unlink文件后還可需用fd,很是納悶!於是搜索到此文,並自測了下,漲姿勢了~分享給大家~

原理:

  每一個文件,都可以通過一個struct stat的結構體來獲得文件信息,其中一個成員st_nlink代表文件的鏈接數。
      當通過shell的touch命令或者在程序中open一個帶有O_CREAT的不存在的文件時,文件的鏈接數為1。

      通常open一個已存在的文件不會影響文件的鏈接數。open的作用只是使調用進程與文件之間建立一種訪問關系,即open之后返回fd,調用進程可以通過fd來read 、write 、 ftruncate等等一系列對文件的操作。
      close()就是消除這種調用進程與文件之間的訪問關系。自然,不會影響文件的鏈接數。在調用close時,內核會檢查打開該文件的進程數,如果此數為0,進一步檢查文件的鏈接數,如果這個數也為0,那么就刪除文件內容。

      link函數創建一個新目錄項,並且增加一個鏈接數。
      unlink函數刪除目錄項,並且減少一個鏈接數。如果鏈接數達到0並且沒有任何進程打開該文件(close了都),該文件內容才被真正刪除。如果在unlilnk之前沒有close,那么依舊可以訪問文件內容,當然文件名不存在了,fd還是可以訪問的嘛。
  
      綜上所訴,真正影響鏈接數的操作是link、unlink以及open的創建。
      刪除文件內容的真正含義是文件的鏈接數為0,而這個操作的本質完成者是unlink。

  close能夠實施刪除文件內容的操作,必定是因為在close之前有一個unlink操作。

驗證:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
    int fd;
    char buf[32];
    struct stat buff;
    struct stat buff2;

    if((fd=open("temp.txt",O_RDWR|O_CREAT|O_TRUNC,S_IRWXU))<0){
        printf("create file error!\n");
    }
    if(write(fd,"temp",5)<0){ printf("write wrror!\n"); }//后面unlink到0后,目錄里沒有文件了,但是fd還可以訪問其中內容!,因為本進程還沒有close,如果close之后就啥都沒鳥~
stat("temp.txt",&buff); printf("temp.link=%d\n",buff.st_nlink); link("temp.txt","test.txt"); stat("test.txt",&buff); printf("after link the tem.link =%d\n",buff.st_nlink); if(unlink("test.txt")<0){ printf("unlink error !\n"); } stat("temp.txt",&buff); printf("after unlink tem.link=%d\n",buff.st_nlink); if(unlink("temp.txt")<0){ printf("unlink error !\n"); }
//此處我們改用fstat函數而非stat,因為unlilnk已經刪除文件名,所以不可以通過文件名訪問
//但是fd仍然是打開着的,文件內容還沒有被
真正刪除,依舊可以使用fd獲得文件信息 fstat(fd,&buff); printf("after unlink tem.link=%u\n",buff.st_nlink); if((lseek(fd,0,SEEK_SET))==-1){ printf("lseek error!\n"); } if((read(fd,buf,5))<0){ printf("read error!\n"); } printf("%s,then ,close fd ,reopen \n",buf);
if((lseek(fd,0,SEEK_SET))==-1){
        printf("lseek error!\n"); } if((read(fd,buf,5))<0){ printf("read error!\n"); }
 printf("%s after reopen \n",buf);
return 0; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM