Rosyna asked on the carbon-dev list:
But it makes me wonder, is there anyway on Mac OS X to generate a”fast path” from an FSRef? That is, a path that is just the supershort volfs version of the path?
I need to use this myself now and then, so here’s a code snippet that does that:
#import <Carbon/Carbon.h>
#include <sys/mount.h>
const char* shortPath(FSRef* ref) {
FSCatalogInfo info;
if (FSGetCatalogInfo(ref,kFSCatInfoVolume|kFSCatInfoNodeID,&info,NULL,NULL,NULL)==noErr) {
FSRef root;
if (FSGetVolumeInfo(info.volume,0,NULL,0,NULL,NULL,&root)==noErr) {
char* path = calloc(1,PATH_MAX+1);
if (FSRefMakePath(&root,(UInt8*)path,PATH_MAX)==noErr) {
struct statfs fs;
if (!statfs(path,&fs)&&(fs.f_flags&MNT_DOVOLFS)) {
snprintf(path,PATH_MAX,"/.vol/%lu/%lu",fs.f_fsid.val[0],info.nodeID);
return path;
}
}
if (FSRefMakePath(ref,(UInt8*)path,PATH_MAX)==noErr) {
return path;
}
free(path);
}
}
return NULL;
}
To use it, pass in your FSRef and you’ll get one of these back:
- A short volfs path, if the volume supports volfs, or
- A normal path if the volume doesn’t support volfs and the path is shorter than PATH_MAX, or
- NULL.
If the return value is not NULL you’re responsible for freeing the path buffer after you’re done with it.
There are some issues with volfs paths you need to be aware of. The canonical reference here is Technical Q&A QA1113: The “/.vol” directory and “volfs”, which says:
WARNING:
Under no circumstances should your application construct paths within “/.vol”. This area of the file system is reserved strictly for the Carbon File Manager. The structure of the “volfs” file system is likely to change in a future releases of Mac OS X. You must use the following description of the “volfs” path structure for debugging and performance analysis only.
If you pass the path generated by my code snippet to any BSD routine it should work. You should however treat the path as opaque and not rely on its contents. About the only thing that also works is, if your FSRef points at a directory, you can concatenate the UTF8 name of a contained file (preceded by a slash) onto that path – you can’t add more than one though.
The snippet relies on one non-documented feature of the statfs call, namely, that the volfs volumeID is returned in the f_fsid.val[0] field. Needless to say this can break anytime in the future, and you may not want to rely on this for shipping applications. That said, it would certainly be useful to have the File Manager return a guaranteed short opaque path that could be passed to BSD calls. I plan to file a bug requesting this.
As QA1113 says, this could break in any future version of Mac OS X – I’m sure it works from 10.1.5 up to 10.4.9 though. You might want to insert a stat() call before returning the volfs path, if you’re really concerned about that… this is left as an exercise for the student.
Leave a Comment