#!/usr/bin/perl use Fcntl qw(SEEK_SET); # Read and validate command line my ($in, $out) = @ARGV; die "usage: cpinplace FROM TO\n" unless $in and $out; die "cpinplace: fatal: $in not a regular file\n" unless -f $in; die "cpinplace: fatal: $out not a regular file\n" if -e $out and not -f $out; # Bombs Away! open(IN,"<$in") && open(OUT,"+<$out") && seek(OUT,0,SEEK_SET) && truncate(OUT,0) or die "cpinplace: fatal: $!\n"; # OK, the output file is now truncated. # copy the file in place. my ($line, $n); while (($n=sysread(IN, $line, 512))>0) { my $stat = syswrite(OUT, $line); die "$!" unless defined $stat; warn "Write($stat) != Read($n)\n" unless $stat == $n; } __END__ =head1 NAME cpinplace - Overwrite one file with the contents of another =head1 USAGE cpinplace FROM TO =head1 DESCRIPTION C copies the contents of FROM to the file TO, ensuring that TO will have the same inode after the operation. This is useful because Mac OS X manages files by inode rather than by name. You can use C to overwrite a music file in the iTunes library, for example, such that iTunes doesn't realize that the file has changed. =head1 BUGS This utility doesn't copy stdin to a file. It also doesn't gracefully handle the case in which the file doesn't exist. It could quietly create the file, but instead it aborts with a "file not found" error.