File exists on Mac OS X

P

Peter Hickman

I have a generic file renaming code that lowercases the filename but before it
does the renaming it checks if the lowercased version of the filename already
exists. This works fine on Linux however on Max OS X the filesystem is case
agnostic and so if the file ZXC exists then perl will report that zxc, zxC, zXc,
zXC, Zxc, ZxC and ZXc all also exist even if they don't.

Is there a way to keep my code portable but not get this problem?
 
A

Anno Siegel

Peter Hickman said:
I have a generic file renaming code that lowercases the filename but before it
does the renaming it checks if the lowercased version of the filename already
exists. This works fine on Linux however on Max OS X the filesystem is case
agnostic

Not necessarily, but usually it is.
and so if the file ZXC exists then perl will report that zxc,
zxC, zXc,
zXC, Zxc, ZxC and ZXc all also exist even if they don't.

It's worse than that. rename() will fail on a case-insensitive system
when the only difference in the new name is in case.
Is there a way to keep my code portable but not get this problem?

You need an intermediate name (or an auxiliary directory) to do this
kind of renaming. Look at File::Temp for a reasonably safe way of
creating unique file names.

Anno
 
P

Peter Hickman

Anno said:
It's worse than that. rename() will fail on a case-insensitive system
when the only difference in the new name is in case.




You need an intermediate name (or an auxiliary directory) to do this
kind of renaming. Look at File::Temp for a reasonably safe way of
creating unique file names.

Anno

Thanks for the information, I will look into File::Temp, it seems a mite
wasteful but if it works who cares.
 
B

Bo Lindbergh

It's worse than that. rename() will fail on a case-insensitive system
when the only difference in the new name is in case.

On what version of what OS? It works just fine on Mac OS X 10.3.4.

One possible approach is to lstat the old and new names and compare
the device and inode numbers for equality. If they match, you have
either two links to the same file or two case variants of the same
name; in either case, a rename would be non-destructive.

=cut

use Errno qw(EEXIST);

sub safer_rename ($$)
{
my($oldname,$newname)=@_;
my($olddev,$oldino,$newdev,$newino);

($olddev,$oldino) = lstat($oldname) or return;
if (($newdev,$newino) = lstat($newname)) {
if ($newdev!=$olddev || $oldino!=$newino) {
$! = EEXIST;
return;
}
}
return rename($oldname,$newname);
}
 
P

Peter Hickman

Bo said:
On what version of what OS? It works just fine on Mac OS X 10.3.4.

The problem , for me at least, is that I don't want to rename a file that does
not require renaming if a file with the lowercase version of the filename
already exists. However if I have ZXC as a file and do an -e zxc it will match
the ZXC and claim the file exists. Hence no renaming.

I'm going for the intermediate temporary file approach at the moment.
 
A

Anno Siegel

Bo Lindbergh said:
On what version of what OS? It works just fine on Mac OS X 10.3.4.

Indeed it does. That wasn't always the case, but I can't pinpoint
the version when it changed.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top