【发布时间】:2016-11-10 22:37:33
【问题描述】:
当我试图回答这个问题时,出现了一个有趣的问题:
rename() 函数要求按照标准是原子的吗?
POSIX standard for rename 的“基本原理”部分指出:
这个
rename()函数相当于普通文件 由 ISO C 标准定义。它的包含在这里扩展了 定义包括对目录的操作并指定行为 当新参数命名一个已经存在的文件时。 那个 规范要求函数的动作是原子的。
但是,rename 上的 latest publicly-available ISO C Standard 部分完整地指出:
7.21.4.2
rename函数概要
#include <stdio.h> int rename(const char *old, const char *new);说明
rename函数使名称为old指向的字符串的文件从此名称中被称为 由new指向的字符串给出。名为old的文件没有 不再可以通过该名称访问。如果由字符串命名的文件指向 to bynew在调用rename函数之前存在, 行为是实现定义的。退货
如果操作成功,
rename函数返回零,如果失败则返回非零,在这种情况下,如果文件存在 以前它仍然以其原始名称而闻名。
在 ISO C 标准的rename() 部分中,对于任何类型的原子性没有任何类型的明确要求。
在编写了许多依赖于 rename() 明显特定于实现的原子性的程序后,我认为原子性是一项要求,并对 C 标准中缺乏原子性感到惊讶。
但是 POSIX 标准说 ISO C 标准要求 rename() 是原子的。
解释?
【问题讨论】:
-
您可能希望包含脚注 269。标题为 “Returns” 的段落可以解释为暗示原子性,并且注释 269 进一步支持了这一概念。
-
rename是否在不同文件系统之间复制文件?如果不是,我希望它在可用的情况下使用硬链接,从而使操作在应用程序级别确实是原子的。如果它是 FS 或媒体级别的原子是另一个问题。 -
这不是 POSIX 标准所说的。 “该规范”是指“扩展该定义以包括对目录的操作并指定新参数命名已存在的文件时的行为”,即 POSIX 标准的补充。特别是,“如果存在由 new 参数命名的链接,[...] 名为 new 的链接在整个重命名操作期间对其他线程保持可见,并引用到操作开始前 new 或 old 引用的文件。"
-
@T.C. POSIX 标准声明“这个
rename()函数对于常规文件等同于ISO C 标准定义的函数。...该规范要求函数的操作是原子的。”这是非常明确的. POSIX 标准规定 ISO C 标准要求rename()是原子的。但据我所知,ISO C 标准中没有任何内容需要原子性。然而,POSIX 标准规定 ISO C 标准需要这种原子性。因此问题。 -
我也可以使用省略号:“它包含在此处...指定新参数命名已存在的文件时的行为。该规范要求函数的动作是原子的。”
标签: c language-lawyer