“writeToFile:原子地:”使用某些 ACL 处理文件失败

发布于 2024-10-09 03:09:58 字数 1136 浏览 6 评论 0原文

如果我有一个 ACL 规则为 拒绝删除 的可写文件,则任何 [plistableObject writeFoFile:undeletableFileatomically:YES] 调用都会返回 NO,而非原子写入成功。

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

  1. HFS+ 中缺乏直接“重命名”,
  2. -[NS(Array|Dictionary|Data|String) writeToFile:atomically:] 实现中存在缺陷 或者
  3. Mac OS X 中 ACL 实施的缺陷?

预先感谢

丹尼尔


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

深入挖掘后,我发现,不知何故,大多数 plist 都有一个 ACL,其中包含指令 group:everyone Deny delete;放弃这条规则挽救了局面。

我怀疑 NSArray|NSDictionary|NSWhatHaveYouwriteToFile:atomically: 对这种行为负有责任*,并且——果然——我编写的测试工具只有在通过时才会成功 < code>NO 作为第二个参数,如果文件存在并且具有这样的 ACL...

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

所以我想知道:

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

虽然从技术上讲,此方法会写入一个文件并在完成后对其进行重命名,但从用户的角度来看,它并没有删除任何内容...

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

任何想法非常感谢!

干杯

丹尼尔

If I have a writable file with an ACL-rule of deny delete, any [plistableObject writeFoFile:undeletableFile atomically:YES] call returns NO, whereas non-atomic writes succeed.

I know, that the atomic write means that a temporary file is written and — if written successfully — eventually renamed. This particular implication of it feels odd, though.
So I wonder, is this due to...

  1. lack of a direct 'rename' in HFS+,
  2. a deficiency in the implementation of -[NS(Array|Dictionary|Data|String) writeToFile:atomically:] or
  3. a deficiency in the implementation of ACLs in Mac OS X?

Thanks in Advance

Daniel


Original question:
I've found this odd behavior the other day on a Mac I restored from a backup:
Most applications were unable to persist their preferences — especially Mail.app which warned with an error message, suggesting that it was unable to write to ~/Library/Preferences.

Digging deeper, I found that — somehow — most plists had an ACL with the directive group:everyone deny delete in place; ditching this rule saved the day.

I suspected NSArray|NSDictionary|NSWhatHaveYou's writeToFile:atomically: to be responsible* for this behavior and — sure enough — the test-tool I wrote only succeeds when passed NO as the second argument if the file exists and has such an ACL in place...

(* where by "responsible" I only mean the not-writing-part; the ACL situation was something else entirely)

So I wonder:

Is this a bug or a feature?

While — technically — this method writes a file and upon completion renames it, from a user perspective it is not deleting anything...

If it's a bug:
Should it be filed against NSArray and friends or against the implementation of ACLs?

Any thoughts much appreciated!

Cheers

Daniel

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一世旳自豪 2024-10-16 03:09:58

经过一番挖掘 HFS 源代码我得出的结论是,Mac OS 中不存在文件系统本机 rename 函数。

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

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

因此这种行为是可以预料的:-(

也就是说,我对文件系统或低级编程了解不够,无法决定是否创建本机重命名

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


编辑

作为jfortman指出,原子重命名实际上是可能的,而且很漂亮通过使用以下序列直接进行:

  1. 写入临时文件
  2. exchangedata( path_to_tempfile, path_to_destination_file, options ) (顺便说一句:manpage 指出 该函数自 Darwin 1.3.1/Mac OS X 10.0 起就已存在。 .)
  3. 删除临时文件

After some digging in the HFS source I've come to the conclusion that there is no such thing as a filesystem-native rename function in Mac OS.

Instead, it is implemented as (pseudocode)

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

So this behavior is to be expected :-(

That said, I don't know enough about either filesystems or low-level programming to decide whether the creation of a native rename would be worth the hassle implementing it.

I strongly feel it would be the right thing to do so, but...


Edit

As jfortman pointed out, an atomic rename would actually be possible and pretty straight-forward through use of the following sequence:

  1. write to tempfile
  2. exchangedata( path_to_tempfile, path_to_destination_file, options ) (by the way: the manpage states that this function is around since Darwin 1.3.1/Mac OS X 10.0...)
  3. delete tempfile
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文