当我试图回答这个问题时,出现了一个有趣的问题:
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
的文件为否 该名称可以更长时间访问如果由字符串指定的文件指向 在调用new
函数之前存在rename
行为是实现定义的。返回
如果操作成功,
rename
函数返回零,如果失败则返回非零值,在这种情况下如果文件存在则返回 以前它仍然以其原始名称而闻名。
在ISO C标准的rename()
部分中,对任何类型的原子性都没有明确的要求。
编写了许多程序,这些程序依赖于rename()
显然特定于实现的原子性,我认为原子性是一项要求,并且对C标准的缺乏感到惊讶。
但POSIX标准表明ISO C标准要求rename()
是原子的。
说明(S)?
答案 0 :(得分:4)
您对rename()
的POSIX标准的引用来自(非规范性)“基本原理”部分。主要条目 - 实际的规范材料 - 开始:
对于rename(): [CX] 此参考页面上描述的功能与ISO C标准一致。此处描述的要求与ISO C标准之间的任何冲突都是无意的。本卷POSIX.1-2008符合ISO C标准。
rename()
函数应更改文件名。old
参数指向要重命名的文件的路径名。new
参数指向文件的新路径名。 [CX] 如果new
参数未解析为目录类型的文件的现有目录条目,并且new
参数至少包含一个非 -<slash>
字符,并在处理完所有符号链接后以一个或多个尾随<slash>
个字符结尾,rename()
将失败。...
条目的所有其余部分都在[CX]
(C扩展名)标记内,并讨论了其他特殊行为。
你引用的理由是:
此
rename()
函数与ISO C标准定义的常规文件等效。它包含在此处扩展该定义以包括对目录的操作,并在新参数命名已存在的文件时指定行为。该规范要求函数的动作是原子的。
最后一句中提到的'那个规范'是扩展定义,包括对目录的操作规范和'当新参数命名已存在的文件时',而不是C标准中的规范,正如你所观察到的,没有说明原子性(非常合理;有些系统可以支持C和rename()
而不能支持POSIX更严格的原子性要求)。