Expand technical documentation

Adds section on safe saving.
This commit is contained in:
Dietrich Epp 2022-04-11 17:16:48 -04:00
parent 3bf095fb49
commit d81cce155d
4 changed files with 74 additions and 3 deletions

View File

@ -87,7 +87,7 @@ In this API, files are identified by volume ID, the directory ID within that vol
## FSSpec API
The FSSpec API does not change semantics, but provides a simple data structure which is used to store the volume ID, directory ID, and filename. This structure is called `FSSpec`.
Mac System 7 introduces the FSSPec API. It does not change semantics, but provides a simple data structure which is used to store the volume ID, directory ID, and filename. This structure is called `FSSpec`.
```c
struct FSSpec {

View File

@ -1,7 +1,7 @@
---
layout: page
title: Filesystems
nav_order: 5
nav_order: 4
permalink: /tech/filesystems
parent: Technical Guide
---

View File

@ -8,4 +8,4 @@ has_children: true
# Technical Guide
This guide explains how files and filesystems work on different versions of Mac OS. There are some important differences that make it so you cant just
This guide explains how files and filesystems work on different versions of Mac OS. There are some important differences—you cant just write code once and have it work well across a wide variety of Mac OS systems.

71
docs/tech/safe-saving.md Normal file
View File

@ -0,0 +1,71 @@
---
layout: page
title: Safe Saving
nav_order: 5
permalink: /tech/safe-saving
parent: Technical Guide
---
# Safe Saving
There are a number of different goals for when your program saves a file:
- I/O errors should be reported. If the data does not make it to disk, then tell the user that the operation failed.
- Saves are atomic. After saving, you either get the old version of the file or the complete new version of the file. If your program crashes, its okay if the old file is untouched, but its not okay if its been partially overwritten.
- Saves preserve file references. Any references to a document (aliases or bookmarks) remain valid after modifying the document.
- Saves do not change the creation date, or other metadata associated with the file.
If your first thought is, “that sounds like it could be complicated”, then youre in good company. Theodore Tso wrote an article in 2009, [Dont fear the fsync!][tso-fsync] which covers some of these issues on Linux in detail.
[tso-fsync]: https://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/
## Classic Mac OS
HFS and HFS+ support an operation which exchanges the contents of files. The high-level API call looks like this:
```c
OSErr FSpExchangeFiles(
const FSSpec * source,
const FSSpec * dest);
```
This function exchanges the _contents_ of the two files (both forks), and exchanges the modification dates, but leaves the other metadata alone.
The recipe for safe saving on HFS volumes is:
1. Save the document to a temporary file on the same volume.
1. Exchange the contents of the original file and the temporary file with `FSpExchangeFiles`.
You can test that `FSpExchangeFiles` is supported by a volume by getting the volume parameters. Not all filesystems support this operation.
## Mac OS X
Mac OS X provides a Unix system call that provides the same functionality as `FSpExchangeFiles`, but with a Unix API.
```c
int exchangedata(
const char * path1
const char * path2,
unsigned int options);
```
However, this function does not work on APFS.
## Mac OS X 10.6+
Starting on Mac OS X 10.6, the Foundation framework provides a method for safely replacing an item on the filesystem with a new item. This method is present on `NSFileManager`:
```objc
- (BOOL)replaceItemAtURL:(NSURL *)originalItemURL
withItemAtURL:(NSURL *)newItemURL
backupItemName:(NSString *)backupItemName
options:(NSFileManagerItemReplacementOptions)options
resultingItemURL:(NSURL * _Nullable *)resultingURL
error:(NSError * _Nullable *)error;
```
This method should be preferred for Mac OS X 10.6 and newer. Unlike `exchangedata()`, this function works on APFS.