是否有类似于fsync的linux系统调用,但是使用文件路径而不是文件描述符? 我使用utime修改文件修改时间,文件是USB,我需要确保在设置utime后将时间刷新到usb。
答案 0 :(得分:2)
据我所知,没有。
为此,你需要
open()
文件fsync()
。close()
由1返回的fd。open()
包含目录fsync()
。close()
由4返回的fd。在更新文件的元数据之后,步骤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;
}