标准要求重命名是原子的吗?

时间:2016-11-10 22:37:33

标签: c language-lawyer

当我试图回答这个问题时,出现了一个有趣的问题:

Is mv atomic on my fs?

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)?

1 个答案:

答案 0 :(得分:4)

您对rename()的POSIX标准的引用来自(非规范性)“基本原理”部分。主要条目 - 实际的规范材料 - 开始:

  

对于rename(): [CX] [Option Start]此参考页面上描述的功能与ISO C标准一致。此处描述的要求与ISO C标准之间的任何冲突都是无意的。本卷POSIX.1-2008符合ISO C标准。 [Option End]

     

rename()函数应更改文件名。 old参数指向要重命名的文件的路径名。 new参数指向文件的新路径名。 [CX] [Option Start]如果new参数未解析为目录类型的文件的现有目录条目,并且new参数至少包含一个非 - <slash>字符,并在处理完所有符号链接后以一个或多个尾随<slash>个字符结尾,rename()将失败。

     

... [Option End]

条目的所有其余部分都在[CX](C扩展名)标记内,并讨论了其他特殊行为。

你引用的理由是:

  

rename()函数与ISO C标准定义的常规文件等效。它包含在此处扩展该定义以包括对目录的操作,并在新参数命名已存在的文件时指定行为。该规范要求函数的动作是原子的。

最后一句中提到的'那个规范'是扩展定义,包括对目录的操作规范和'当新参数命名已存在的文件时',而不是C标准中的规范,正如你所观察到的,没有说明原子性(非常合理;有些系统可以支持C和rename()而不能支持POSIX更严格的原子性要求)。

我发现这正是T.Ccomment中所提出的论点 - 我同意T.C。