Stupid Mac OS X Tricks: Resolving Aliases

pudge on 2003-02-06T13:35:05

With MacPerl, you can pass a path to readlink(), and resolve the alias, because there is no actual symlink() on Mac OS. On Mac OS X, that won't work.

Aliases are resource files with the alias data in a resource of type "alis". Open the resource fork of the alias file, get the first "alis" resource, and pass it to ResolveAlias().

#!/usr/local/bin/perl use Mac::Errors; use Mac::Files; use Mac::Resources;

my $path = '/Users/pudge/Desktop/some alias'; my $res = FSpOpenResFile($path, 0) or die $Mac::Errors::MacError; # get resource by index; get first "alis" resource my $alis = GetIndResource('alis', 1) or die $Mac::Errors::MacError; my $link = ResolveAlias($alis); print $link;


How to create an alias? Again, in MacPerl, you can use symlink(). But not so in Mac OS X. Essentially, you do the reverse as above. Create a file with a resource fork,* make an alias to a path, and add the alias as an "alis" resource to the file. Also set the alias flag on the file. It's more complicated, of course.

#!/usr/local/bin/perl use MacPerl qw(GetFileInfo); use Mac::Errors; use Mac::Files; use Mac::Resources;

# workaround for Mac::Carbon bug that requires existing file my $path = '/Users/pudge/Desktop/some other alias'; open my $fh, "> $path" or die $!; close $fh;

# set "alias" attribute my $finfo = FSpGetFInfo($path) or die $Mac::Errors::MacError; $finfo->fdFlags( $finfo->fdFlags | 0x8000 ); # kIsAlias FSpSetFInfo($path, $finfo) or die $Mac::Errors::MacError;

# get target's creator, type, and alias my $target = '/Users/pudge/Desktop/some alias'; my($creator, $type) = GetFileInfo($target); my $alis = NewAlias($target) or die $Mac::Errors::MacError;

# make resource file, open it, add the resource, and close it FSpCreateResFile($path, $creator, $type, 0) or die $Mac::Errors::MacError; my $res = FSpOpenResFile($path, 0) or die $Mac::Errors::MacError; AddResource($alis, 'alis', 0, '') or die $Mac::Errors::MacError; CloseResFile($res);


* Note: there is, as documented, currently a bug in Mac::Carbon where you cannot pass a path to the API where the file does not exist. Hence the open() to create the file.