“writeToFile:atomically:”在具有某些ACL的文件上失败

时间:2010-12-28 15:04:31

标签: cocoa serialization plist acl hfs+

如果我的可写文件的ACL规则为deny delete,则任何[plistableObject writeFoFile:undeletableFile atomically:YES]调用都会返回NO,而非原子写入会成功。

我知道,原子写入意味着写入临时文件,并且 - 如果成功写入 - 最终重命名。然而,它的这个特殊含义感觉奇怪 所以我想知道,这是由于......

  1. 在HFS +中没有直接'重命名',
  2. 执行-[NS(Array|Dictionary|Data|String) writeToFile:atomically:]
  3. 的不足之处
  4. 在Mac OS X中实施ACL的不足之处?
  5. 先谢谢

    丹尼尔


    原始问题:
    前几天我在Mac上发现了这种奇怪的行为,我从备份中恢复了:
    大多数应用程序无法保持他们的首选项 - 特别是Mail.app警告错误消息,表明它无法写入~/Library/Preferences

    深入挖掘,我发现 - 不知何故 - 大多数plist都有一个指令group:everyone deny delete的ACL;放弃这条规则挽救了这一天。

    我怀疑NSArray|NSDictionary|NSWhatHaveYou的{​​{1}}对此行为负责* - 果然 - 我写的测试工具只有在传递writeToFile:atomically:作为第二个参数时才会成功文件存在并且具有这样的ACL ...

    (*其中“责任”我只是指非写作部分; ACL情况完全是另一回事)

    所以我想知道:

    这是一个错误还是一个功能?

    虽然 - 从技术上讲 - 这个方法会写一个文件并在完成后重命名,从用户的角度来看它不会删除任何内容......

    如果这是一个错误:
    是应该针对NSArray和朋友提出还是针对ACL的实施?

    任何想法都非常感激!

    干杯

    丹尼尔

1 个答案:

答案 0 :(得分:0)

HFS source中进行了一些挖掘后,我得出的结论是,在Mac OS中没有文件系统本地rename功能。

相反,它实现为(伪代码)

link!
successful:
   return 0
// otherwise
unlink!
successful:
  link!
  return error_code
// otherwise
return error_code

所以这种行为是可以预期的: - (

那就是说,我对文件系统或低级编程都知之甚少,无法确定原生rename的创建是否值得为实现它而烦恼。

我强烈感觉这样做是正确的,但是......


修改

作为jfortman pointed out,通过使用以下序列,原子重命名实际上是可行的并且相当直接:

  1. 写入tempfile
  2. exchangedata( path_to_tempfile, path_to_destination_file, options )(顺便说一下:自Darwin 1.3.1 / Mac OS X 10.0以来此函数所在的manpage states ...)
  3. 删除临时文件