是否有fsync但有路径参数

时间:2013-12-19 17:07:17

标签: c linux

是否有类似于fsync的linux系统调用,但是使用文件路径而不是文件描述符? 我使用utime修改文件修改时间,文件是USB,我需要确保在设置utime后将时间刷新到usb。

2 个答案:

答案 0 :(得分:2)

据我所知,没有。

为此,你需要

  1. open()文件
  2. 在由1返回的fd上调用fsync()
  3. close()由1返回的fd。
  4. open()包含目录
  5. 在4返回的fd上调用fsync()
  6. close()由4返回的fd。
  7. 在更新文件的元数据之后,步骤4到6 需要将目录的条目(带有文件的元数据)传送到磁盘。

    根据Throwback1986的评论,请注意,以任何方式递归工作。

答案 1 :(得分:1)

这是我从类似POSIX的系统中的一些实用程序例程中提取的一段代码。代码包括同步帮助函数以及递归调用者。它可能无法“开箱即用”编译,因为它来自一个专门的系统,但它足够接近让你走上正确的轨道。

  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;
    }