"writeToFile: atomically:" не работает с файлом с определенным списком ACL - PullRequest
0 голосов
/ 28 декабря 2010

Если у меня есть файл для записи с ACL-правилом deny delete, любой вызов [plistableObject writeFoFile:undeletableFile atomically:YES] возвращает NO, тогда как неатомарная запись завершается успешно.

Я знаю, что атомарная запись означает, что записан временный файл и & mdash; если написано успешно & mdash; в итоге переименован. Этот конкретный смысл этого кажется странным , хотя.
Интересно, это из-за ...

  1. отсутствие прямого переименования в HFS +,
  2. Недостаток в реализации -[NS(Array|Dictionary|Data|String) writeToFile:atomically:] или
  3. Недостаток в реализации ACL в Mac OS X?

Заранее спасибо

Daniel


Оригинальный вопрос:
Такое странное поведение я обнаружил на днях на Mac, восстановленном из резервной копии:
Большинство приложений не смогли сохранить свои предпочтения - особенно Mail.app, который предупреждал с сообщением об ошибке, предполагая, что он не смог записать в ~/Library/Preferences.

Копая глубже, я обнаружил, что - так или иначе - большинство списков имеют ACL с директивой group:everyone deny delete; Отказ от этого правила спас день.

Я подозревал, что NSArray|NSDictionary|NSWhatHaveYou writeToFile:atomically: несет ответственность * за это поведение и - конечно же, инструмент тестирования, который я написал, успешно работает только при передаче NO в качестве второго аргумента, если файл существует и имеет такой ACL на месте ...

(* где под "ответственным" я подразумеваю только неписывающую часть; ситуация с ACL была совсем другой)

Так что мне интересно:

Это ошибка или особенность?

Хотя - технически - этот метод записывает файл и после завершения переименовывает его, с точки зрения пользователя он ничего не удаляет ...

Если , это ошибка:
Должно ли оно быть подано против NSArray и друзей или против реализации ACL?

Любые мысли очень ценятся!

Приветствия

Daniel

1 Ответ

0 голосов
/ 09 января 2011

После некоторого поиска в источнике HFS я пришел к выводу, что в Mac OS не существует такой функции, как встроенная в файловую систему rename функция.

Вместо этого он реализован как (псевдокод)

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

Так что такого поведения следует ожидать: - (

Тем не менее, я не знаю достаточно ни о файловых системах, ни о низкоуровневом программировании, чтобы решить, будет ли создание нативного rename стоить хлопот его реализации.

Я сильно чувствую , это было бы правильно, но ...


Редактировать

Как указал jfortman , атомное переименование действительно возможно и довольно просто благодаря следующей последовательности:

  1. запись в временный файл
  2. exchangedata( path_to_tempfile, path_to_destination_file, options ) (кстати: справочная страница заявляет, что эта функция существует начиная с Darwin 1.3.1 / Mac OS X 10.0 ...)
  3. удалить временный файл
...