Rixstep
 About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Home » Learning Curve » Developers Workshop

performFileOperation:

Apple Cocoa file system APIs fail...


Get It

Try It

Apple Cocoa file system APIs fail if the destination exists. There's no overwriting files in Apple's Cocoa; if you want to replace one file with another you can't overwrite even if permissions allow.

Conversely it normally doesn't matter if a file is write-protected: client applications using Apple's Cocoa file system APIs are going to have to circumvent this anyway.

There's a distinct difference between just 'saving' a file from within a Cocoa application and 'saving as': in the former case the inode is preserved and the file is overwritten; in the latter the file (or directory) is first removed. And the file will naturally have a new inode afterwards.

Unlike every other file system in existence, Apple's file system has no sanity checking to protect you: no matter what you ask Apple to do they'll try to do it - even if it means hosing your entire hard drive.

The following code snippet can help demonstrate a number of these issues. It's a straightforward command line driven program to copy a file from one location to another. The first time you run it everything is fine as the destination doesn't yet exist; the second and all subsequent times it will fail because the destination exists.

#import <Cocoa/Cocoa.h>

int main (int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int tag;

    [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceCopyOperation
            source:[@"<This Directory>" stringByExpandingTildeInPath]
            destination:[@"<Parent Directory>" stringByExpandingTildeInPath]
            files:[NSArray arrayWithObject:@"main.m"]
            tag:&tag
        ];
    [pool release]; return 0;
}

Put the above code into a command line project - or click on the code to get a prefab download. Put your project directory in the field marked '<This Directory>' and put the project directory's parent in the other field marked '<Parent Directory>'. If the source file is named 'main.m' the program will copy 'main.m' to the parent directory - the first time.

After that it will fail. Because the destination already exists.

It's easy to see where this leads. Directories can be overwritten by files; directories can be moved over subdirectories and subdirectories over their parent directories - and Apple's file system API won't even burp. But your computer will: you'll hose it.

See Also
Apple's File System APIs
Hosing OS X with Apple's Idea of 'Expected Behaviour'
Learning Curve: Rebel Scum: More Attacks on 'Expected Behaviour'

Apple: NSWorkspace Reference
Apple: NSFileManager Reference
Slashdot: Data Loss Bug In OS X 10.5 Leopard
Tom Karpik: Massive Data Loss Bug in Leopard
MacInTouch: Mac OS X 10.5 Leopard: Finder Data-Loss Bug

Learning Curve: 4893378 FAQ
Industry Watch: Sanity Checks at Apple
Learning Curve: A Sanity Check for Apple
Learning Curve: 4893378: 'Expected Behaviour'

About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Copyright © Rixstep. All rights reserved.