2013-12-19 38 views
1

是否有類似於fsync的linux系統調用,但使用文件路徑而不是文件描述符? 我使用utime修改文件修改時間,文件在USB中,我需要確保在設置好utime後時間刷新到usb。是否有fsync但路徑參數

回答

2

據我所知沒有。

要做到這一點,你需要

  1. open()文件
  2. 呼叫fsync()由FD返回1.
  3. close()的Fab 1。
  4. open()包含目錄
  5. 返回
  6. 致電fsync()由fd返回4.
  7. close()當你正在更新的文件的元數據中的步驟後4〜6 是必要的,以獲得目錄的(攜帶文件的元數據)到磁盤的FD由4

返回。

根據Throwback1986的評論請注意,這是不是以任何方式工作recursivly。

+1

並注意調用FSYNC上使用dir *不*遞歸同步的同步的目錄 – Throwback1986

+0

我需要寫的USB文件後致電UTIME中的文件和/或迪爾斯,當我應該叫UTIME所以時間修改與USB同步。 我想我可以使用futimes而不是utime。 爲什麼我需要打開包含目錄? – dragon135

+0

@ dragon135:你爲什麼要顯式設置修改時間戳,因爲這可以通過寫入文件來隱式完成?我在回答中提到爲什麼包含direcorey需要fsync'ed。我更新了我的答案,對此更加明確。 – alk

0

這是我從一些POSIX-like系統中的一些實用例程中解除的一段代碼。代碼包括同步幫助程序功能以及遞歸調用程序。它可能不是「開箱即用」編譯的,因爲它來自專門的系統,但它足夠接近您的正確軌道。

static int sync_path(const char *path) 
     { 
     int fd = 0; 
     int ret = 0; 


     if (path == NULL) 
      { 
      printf("Invalid path (NULL)"); 
      return -1; 
     } 

     fd = open(path, O_RDONLY); 
     if (fd < 0) 
      { 
     printf("Failed to open dir [%d:%s] (%s)", 
       errno, strerror(errno), path); 
     return errno; 
      } 

     ret = fsync(fd); 
     if (ret < 0) 
      { 

     printf("Failed to sync dir [%d:%s] (%s)", 
       errno, strerror(errno), path); 

      close(fd); 
     return errno; 
     } 

     ret = close(fd); 
     if (ret < 0) 
      { 
     printf("Failed to close dir [%d:%s] (%s)", 
         errno, strerror(errno), path); 

      return errno; 
     } 

     return 0; 
    } 


    int sync_tree(const char *path) 
    { 
     static size_t depth = 0; 

     struct dirent *entry = NULL; 

     DIR *dir = NULL; 

     const char *p = NULL; 

     int ret = 0; 


     if (path == NULL) 
     { 
       printf("Invalid path (NULL)"); 
      return -1; 
     } 

     depth++; 
     if (depth > MAX_RECURSION_DEPTH) 
     { 
       printf("Recursion limit reached [%d]", 
         MAX_RECURSION_DEPTH); 
      return -1; 
     } 

     ret = chdir(path); 
     if (ret) 
     { 
      printf("Unable to chdir [%d:%s] (%s)", 
      errno, strerror(errno), path); 

      return errno; 
     } 

     // Operate on the current dir (after the chdir above) 
     dir = opendir("./"); 
     if (dir == NULL) 
      { 
     printf("Unable to open dir [%d:%s] (%s)", 
       errno, strerror(errno), path); 
     return errno; 
     } 

     entry = readdir(dir); 
     while (entry && (ret == Success)) 
      { 
      p = entry -> d_name; 
      if (!p) 
      { 
       break; 
      } 

      if (entry -> d_type != DT_DIR) 
      { 
       ret = sync_path(p); 
      } 
      else 
      { 
       // If not dir is not . or .., then process it (depth-first) 
       if (strnicmp(p, ".", 1) && strnicmp(p, "..", 2)) 
       { 
       // Recursion here... 
       ret = sync_tree(p); 
       if (ret) 
      { 
       // Do nothing - any error message should already be handled 
      } 
       else 
      { 
       // Restore current dir 
       ret = chdir("../"); 
       if (ret) 
         { 
        printf("Unable to chdir [%d:%s] (%s)", 
        errno, strerror(errno), "../"); 

         } 
       else 
         { 
        // All is well... 
         } 
        } 
       } 
      } 

      if (ret == 0) 
      { 
       entry = readdir(dir); 
      } 
      } 
     closedir(dir); 

     // Sync this level 
     ret = sync_path("./"); 
     if (ret) 
     { 
      // Any error message should already be printed, so just return 
      return -1; 
     } 
     else 
     { 
      // All is well.. 
     } 

     depth--; 
     return Success; 
    }