C 跨平台 renameat2() 重命名如果不存在的功能

C cross-platform renameat2() rename-if-not-exists functionality

是否有非平台特定的方法来执行原子操作 "rename File1 to File2 if File2 does not exist, otherwise give an error"?我知道我可以检查 File2 是否存在,如果不存在则重命名文件,但是当其他进程在检查和 rename().

之间创建 File2 时,这会引入潜在的竞争条件

在 Linux 下有 renameat2() 函数,它通过设置 RENAME_NOREPLACE 标志来完成此操作。不幸的是,联机帮助页说

renameat2() is Linux-specific.

我什至不知道是所有的 libc 实现都支持这个调用,还是只支持 glibc。

对于我的用例,在同一目录内重命名就足够了,我不需要支持移动到完全不同的路径。

这可能与 and

有关

Is there a non-platform-specific way of doing an atomic "rename File1 to File2 if File2 does not exist, otherwise give an error"?

C 标准库仅提供 rename() 用于更改文件名,并且标准关于该函数是这样说的: "If a file named by the string pointed to by new exists prior to the call to the rename function, the behavior is implementation-defined." 因此,如果 "non-platform-specific" 被解释为 "specified by the C standard" 那就不行,没有这个机制

如果我们扩大 "non-platform-specific" 的范围以允许 POSIX 指定的设施,那么您可以依赖 link()

shall atomically create a new link for the existing file and the link count of the file shall be incremented by one. [and] shall fail if [... the second argument] resolves to an existing directory entry or refers to a symbolic link.

因此,您可以先为文件创建一个新的(硬的)link,如果指定的路径名​​指定一个现有文件或符号 link,则失败,然后删除原来的 [=33] =] 成功后。

您可能感兴趣的最著名的非 POSIX 平台是 Windows。我不确定是否有任何方法可以完成你在 Windows 上的要求,但如果有,你可以考虑编写一个使用条件编译的包装函数 select [=36] =] 或 Windows 实施。