linux – 如何在没有竞争条件的情况下重命名()?

linux – 如何在没有竞争条件的情况下重命名()?,第1张

概述如果我想将A重命名为B,但只有当B不存在时,天真的事情就是检查B是否存在(具有访问权限(“B”,F_OK)或类似的东西),如果它不继续重命名.不幸的是,这会打开一个窗口,在这个窗口期间,其他一些进程可能会决定创建B,然后它会被覆盖 – 更糟糕的是,没有迹象表明曾经发生过类似的事情. 其他文件系统访问功能不受此影响 – 打开有O_EXCL(因此复制文件是安全的),最近Linux在syscalls上得 如果我想将A重命名为B,但只有当B不存在时,天真的事情就是检查B是否存在(具有访问权限(“B”,F_OK)或类似的东西),如果它不继续重命名.不幸的是,这会打开一个窗口,在这个窗口期间,其他一些进程可能会决定创建B,然后它会被覆盖 – 更糟糕的是,没有迹象表明曾经发生过类似的事情.

其他文件系统访问功能不受此影响 – 打开有O_EXCL(因此复制文件是安全的),最近Linux在syscalls上得到了一整套*,以防止大多数其他竞争条件 – 但不是这个特定的一个(renameat存在),但可以防止完全不同的问题).

它有解决方案吗?

解决方法 从linux内核3.15(2014年6月发布)开始,可以使用syscall(__ NR_renameat2,AT_FDCWD,“source-file”,“dest-file”,REname_norEPLACE)(包括< syscall.h>,< fcntl.h>和< linux / fs.h>).

这比link()更好,因为永远不会同时存在两个文件名(特别是使用link(),精确定时的断电可能会导致两个名称永远存在).

glibc 2.28(2018年8月发布)添加了一个renameat2()包装器,因此您可以使用它而不是syscall.h和linux / fs.h(尽管您很可能需要< stdio.h>和#define __GNU_SOURCE而不是).

有关更多详细信息,请参阅http://man7.org/linux/man-pages/man2/rename.2.html(尽管确实如此,但在编写时,不知道glibc现在有一个renameat2包装器).

总结

以上是内存溢出为你收集整理的linux – 如何在没有竞争条件的情况下重命名()?全部内容,希望文章能够帮你解决linux – 如何在没有竞争条件的情况下重命名()?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1039903.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存