I'm developing a sandboxed app for Mac OS X 10.7 and I'm trying to implement file saving in a way similar to NSDocument:
- Rewrite the file's new contents to a temporary file
- Overwrite the original file with the temporary file
The issue I'm having is that the sandbox is denying step 2. I see the following line in Console:
sandboxd: XXXX deny file-write-create /Volumes/Home/sbooth/Test Files/Test
I already have this file open for reading and writing, and I have the File System Read/Write Access entitlement enabled. I know NSDocument does this with no special entitlements so I'm trying to figure out what I've missed.
Here is how I'm doing things now (this portion of the app is in C++, not Objective-C/C++):
FSRef tempFileFSRef;
if(noErr != FSPathMakeRef((const UInt8 *)tempFileName, &tempFileFSRef, NULL))
; // Handle it
CFURLRef destinationDirURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, mURL);
FSRef destinationDirFSRef;
if(!CFURLGetFSRef(destinationDirURL, &destinationDirFSRef))
; // Handle it
CFRelease(destinationDirURL), destinationDirURL = NULL;
CFStringRef destinationName = CFURLCopyLastPathComponent(mURL);
FSRef target;
OSStatus result = FSCopyObjectSync(&tempFileFSRef, &destinationDirFSRef, destinationName, &target, kFSFileOperationOverwrite | kFSFileOperationSkipSourcePermissionErrors);
if(noErr != result)
; // Handle it
The code works correctly if I disable sandboxing.
Edit: Additional information was requested by Femi. I open the file using C stdio:
FILE *f = fopen(reinterpret_cast<const char *>(buf), "r");
and it closed using fclose before the temp file is created.
My entitlements are:
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.music.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
It's also worth noting that Apple says in their App Sandbox Design Guide that:
If you are managing documents using any technology other than the NSDocument class, you must convert to using this class. The NSDocument class automatically works with Powerbox. NSDocument also provides support for keeping documents within your sandbox if the user moves them using Finder.
FSCopyObjectSyncreturning an error? - Michael Dautermann