1*0Sstevel@tonic-gate# File/Copy.pm. Written in 1994 by Aaron Sherman <ajs@ajs.com>. This 2*0Sstevel@tonic-gate# source code has been placed in the public domain by the author. 3*0Sstevel@tonic-gate# Please be kind and preserve the documentation. 4*0Sstevel@tonic-gate# 5*0Sstevel@tonic-gate# Additions copyright 1996 by Charles Bailey. Permission is granted 6*0Sstevel@tonic-gate# to distribute the revised code under the same terms as Perl itself. 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gatepackage File::Copy; 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gateuse 5.006; 11*0Sstevel@tonic-gateuse strict; 12*0Sstevel@tonic-gateuse warnings; 13*0Sstevel@tonic-gateuse Carp; 14*0Sstevel@tonic-gateuse File::Spec; 15*0Sstevel@tonic-gateuse Config; 16*0Sstevel@tonic-gateour(@ISA, @EXPORT, @EXPORT_OK, $VERSION, $Too_Big, $Syscopy_is_copy); 17*0Sstevel@tonic-gatesub copy; 18*0Sstevel@tonic-gatesub syscopy; 19*0Sstevel@tonic-gatesub cp; 20*0Sstevel@tonic-gatesub mv; 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gate# Note that this module implements only *part* of the API defined by 23*0Sstevel@tonic-gate# the File/Copy.pm module of the File-Tools-2.0 package. However, that 24*0Sstevel@tonic-gate# package has not yet been updated to work with Perl 5.004, and so it 25*0Sstevel@tonic-gate# would be a Bad Thing for the CPAN module to grab it and replace this 26*0Sstevel@tonic-gate# module. Therefore, we set this module's version higher than 2.0. 27*0Sstevel@tonic-gate$VERSION = '2.07'; 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gaterequire Exporter; 30*0Sstevel@tonic-gate@ISA = qw(Exporter); 31*0Sstevel@tonic-gate@EXPORT = qw(copy move); 32*0Sstevel@tonic-gate@EXPORT_OK = qw(cp mv); 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate$Too_Big = 1024 * 1024 * 2; 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gatemy $macfiles; 37*0Sstevel@tonic-gateif ($^O eq 'MacOS') { 38*0Sstevel@tonic-gate $macfiles = eval { require Mac::MoreFiles }; 39*0Sstevel@tonic-gate warn 'Mac::MoreFiles could not be loaded; using non-native syscopy' 40*0Sstevel@tonic-gate if $@ && $^W; 41*0Sstevel@tonic-gate} 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gatesub _catname { 44*0Sstevel@tonic-gate my($from, $to) = @_; 45*0Sstevel@tonic-gate if (not defined &basename) { 46*0Sstevel@tonic-gate require File::Basename; 47*0Sstevel@tonic-gate import File::Basename 'basename'; 48*0Sstevel@tonic-gate } 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate if ($^O eq 'MacOS') { 51*0Sstevel@tonic-gate # a partial dir name that's valid only in the cwd (e.g. 'tmp') 52*0Sstevel@tonic-gate $to = ':' . $to if $to !~ /:/; 53*0Sstevel@tonic-gate } 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate return File::Spec->catfile($to, basename($from)); 56*0Sstevel@tonic-gate} 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gatesub copy { 59*0Sstevel@tonic-gate croak("Usage: copy(FROM, TO [, BUFFERSIZE]) ") 60*0Sstevel@tonic-gate unless(@_ == 2 || @_ == 3); 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate my $from = shift; 63*0Sstevel@tonic-gate my $to = shift; 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate my $from_a_handle = (ref($from) 66*0Sstevel@tonic-gate ? (ref($from) eq 'GLOB' 67*0Sstevel@tonic-gate || UNIVERSAL::isa($from, 'GLOB') 68*0Sstevel@tonic-gate || UNIVERSAL::isa($from, 'IO::Handle')) 69*0Sstevel@tonic-gate : (ref(\$from) eq 'GLOB')); 70*0Sstevel@tonic-gate my $to_a_handle = (ref($to) 71*0Sstevel@tonic-gate ? (ref($to) eq 'GLOB' 72*0Sstevel@tonic-gate || UNIVERSAL::isa($to, 'GLOB') 73*0Sstevel@tonic-gate || UNIVERSAL::isa($to, 'IO::Handle')) 74*0Sstevel@tonic-gate : (ref(\$to) eq 'GLOB')); 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate if ($from eq $to) { # works for references, too 77*0Sstevel@tonic-gate croak("'$from' and '$to' are identical (not copied)"); 78*0Sstevel@tonic-gate } 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate if ((($Config{d_symlink} && $Config{d_readlink}) || $Config{d_link}) && 81*0Sstevel@tonic-gate !($^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'vms')) { 82*0Sstevel@tonic-gate my @fs = stat($from); 83*0Sstevel@tonic-gate if (@fs) { 84*0Sstevel@tonic-gate my @ts = stat($to); 85*0Sstevel@tonic-gate if (@ts && $fs[0] == $ts[0] && $fs[1] == $ts[1]) { 86*0Sstevel@tonic-gate croak("'$from' and '$to' are identical (not copied)"); 87*0Sstevel@tonic-gate } 88*0Sstevel@tonic-gate } 89*0Sstevel@tonic-gate } 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) { 92*0Sstevel@tonic-gate $to = _catname($from, $to); 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate if (defined &syscopy && !$Syscopy_is_copy 96*0Sstevel@tonic-gate && !$to_a_handle 97*0Sstevel@tonic-gate && !($from_a_handle && $^O eq 'os2' ) # OS/2 cannot handle handles 98*0Sstevel@tonic-gate && !($from_a_handle && $^O eq 'mpeix') # and neither can MPE/iX. 99*0Sstevel@tonic-gate && !($from_a_handle && $^O eq 'MSWin32') 100*0Sstevel@tonic-gate && !($from_a_handle && $^O eq 'MacOS') 101*0Sstevel@tonic-gate && !($from_a_handle && $^O eq 'NetWare') 102*0Sstevel@tonic-gate ) 103*0Sstevel@tonic-gate { 104*0Sstevel@tonic-gate return syscopy($from, $to); 105*0Sstevel@tonic-gate } 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate my $closefrom = 0; 108*0Sstevel@tonic-gate my $closeto = 0; 109*0Sstevel@tonic-gate my ($size, $status, $r, $buf); 110*0Sstevel@tonic-gate local($\) = ''; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate my $from_h; 113*0Sstevel@tonic-gate if ($from_a_handle) { 114*0Sstevel@tonic-gate $from_h = $from; 115*0Sstevel@tonic-gate } else { 116*0Sstevel@tonic-gate $from = _protect($from) if $from =~ /^\s/s; 117*0Sstevel@tonic-gate $from_h = \do { local *FH }; 118*0Sstevel@tonic-gate open($from_h, "< $from\0") or goto fail_open1; 119*0Sstevel@tonic-gate binmode $from_h or die "($!,$^E)"; 120*0Sstevel@tonic-gate $closefrom = 1; 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate my $to_h; 124*0Sstevel@tonic-gate if ($to_a_handle) { 125*0Sstevel@tonic-gate $to_h = $to; 126*0Sstevel@tonic-gate } else { 127*0Sstevel@tonic-gate $to = _protect($to) if $to =~ /^\s/s; 128*0Sstevel@tonic-gate $to_h = \do { local *FH }; 129*0Sstevel@tonic-gate open($to_h,"> $to\0") or goto fail_open2; 130*0Sstevel@tonic-gate binmode $to_h or die "($!,$^E)"; 131*0Sstevel@tonic-gate $closeto = 1; 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate if (@_) { 135*0Sstevel@tonic-gate $size = shift(@_) + 0; 136*0Sstevel@tonic-gate croak("Bad buffer size for copy: $size\n") unless ($size > 0); 137*0Sstevel@tonic-gate } else { 138*0Sstevel@tonic-gate $size = tied(*$from_h) ? 0 : -s $from_h || 0; 139*0Sstevel@tonic-gate $size = 1024 if ($size < 512); 140*0Sstevel@tonic-gate $size = $Too_Big if ($size > $Too_Big); 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate $! = 0; 144*0Sstevel@tonic-gate for (;;) { 145*0Sstevel@tonic-gate my ($r, $w, $t); 146*0Sstevel@tonic-gate defined($r = sysread($from_h, $buf, $size)) 147*0Sstevel@tonic-gate or goto fail_inner; 148*0Sstevel@tonic-gate last unless $r; 149*0Sstevel@tonic-gate for ($w = 0; $w < $r; $w += $t) { 150*0Sstevel@tonic-gate $t = syswrite($to_h, $buf, $r - $w, $w) 151*0Sstevel@tonic-gate or goto fail_inner; 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate close($to_h) || goto fail_open2 if $closeto; 156*0Sstevel@tonic-gate close($from_h) || goto fail_open1 if $closefrom; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate # Use this idiom to avoid uninitialized value warning. 159*0Sstevel@tonic-gate return 1; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate # All of these contortions try to preserve error messages... 162*0Sstevel@tonic-gate fail_inner: 163*0Sstevel@tonic-gate if ($closeto) { 164*0Sstevel@tonic-gate $status = $!; 165*0Sstevel@tonic-gate $! = 0; 166*0Sstevel@tonic-gate close $to_h; 167*0Sstevel@tonic-gate $! = $status unless $!; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate fail_open2: 170*0Sstevel@tonic-gate if ($closefrom) { 171*0Sstevel@tonic-gate $status = $!; 172*0Sstevel@tonic-gate $! = 0; 173*0Sstevel@tonic-gate close $from_h; 174*0Sstevel@tonic-gate $! = $status unless $!; 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate fail_open1: 177*0Sstevel@tonic-gate return 0; 178*0Sstevel@tonic-gate} 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gatesub move { 181*0Sstevel@tonic-gate my($from,$to) = @_; 182*0Sstevel@tonic-gate my($fromsz,$tosz1,$tomt1,$tosz2,$tomt2,$sts,$ossts); 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate if (-d $to && ! -d $from) { 185*0Sstevel@tonic-gate $to = _catname($from, $to); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate ($tosz1,$tomt1) = (stat($to))[7,9]; 189*0Sstevel@tonic-gate $fromsz = -s $from; 190*0Sstevel@tonic-gate if ($^O eq 'os2' and defined $tosz1 and defined $fromsz) { 191*0Sstevel@tonic-gate # will not rename with overwrite 192*0Sstevel@tonic-gate unlink $to; 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate return 1 if rename $from, $to; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate # Did rename return an error even though it succeeded, because $to 197*0Sstevel@tonic-gate # is on a remote NFS file system, and NFS lost the server's ack? 198*0Sstevel@tonic-gate return 1 if defined($fromsz) && !-e $from && # $from disappeared 199*0Sstevel@tonic-gate (($tosz2,$tomt2) = (stat($to))[7,9]) && # $to's there 200*0Sstevel@tonic-gate ($tosz1 != $tosz2 or $tomt1 != $tomt2) && # and changed 201*0Sstevel@tonic-gate $tosz2 == $fromsz; # it's all there 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate ($tosz1,$tomt1) = (stat($to))[7,9]; # just in case rename did something 204*0Sstevel@tonic-gate return 1 if copy($from,$to) && unlink($from); 205*0Sstevel@tonic-gate ($sts,$ossts) = ($! + 0, $^E + 0); 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate ($tosz2,$tomt2) = ((stat($to))[7,9],0,0) if defined $tomt1; 208*0Sstevel@tonic-gate unlink($to) if !defined($tomt1) or $tomt1 != $tomt2 or $tosz1 != $tosz2; 209*0Sstevel@tonic-gate ($!,$^E) = ($sts,$ossts); 210*0Sstevel@tonic-gate return 0; 211*0Sstevel@tonic-gate} 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate*cp = \© 214*0Sstevel@tonic-gate*mv = \&move; 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gateif ($^O eq 'MacOS') { 218*0Sstevel@tonic-gate *_protect = sub { MacPerl::MakeFSSpec($_[0]) }; 219*0Sstevel@tonic-gate} else { 220*0Sstevel@tonic-gate *_protect = sub { "./$_[0]" }; 221*0Sstevel@tonic-gate} 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate# &syscopy is an XSUB under OS/2 224*0Sstevel@tonic-gateunless (defined &syscopy) { 225*0Sstevel@tonic-gate if ($^O eq 'VMS') { 226*0Sstevel@tonic-gate *syscopy = \&rmscopy; 227*0Sstevel@tonic-gate } elsif ($^O eq 'mpeix') { 228*0Sstevel@tonic-gate *syscopy = sub { 229*0Sstevel@tonic-gate return 0 unless @_ == 2; 230*0Sstevel@tonic-gate # Use the MPE cp program in order to 231*0Sstevel@tonic-gate # preserve MPE file attributes. 232*0Sstevel@tonic-gate return system('/bin/cp', '-f', $_[0], $_[1]) == 0; 233*0Sstevel@tonic-gate }; 234*0Sstevel@tonic-gate } elsif ($^O eq 'MSWin32') { 235*0Sstevel@tonic-gate *syscopy = sub { 236*0Sstevel@tonic-gate return 0 unless @_ == 2; 237*0Sstevel@tonic-gate return Win32::CopyFile(@_, 1); 238*0Sstevel@tonic-gate }; 239*0Sstevel@tonic-gate } elsif ($macfiles) { 240*0Sstevel@tonic-gate *syscopy = sub { 241*0Sstevel@tonic-gate my($from, $to) = @_; 242*0Sstevel@tonic-gate my($dir, $toname); 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate return 0 unless -e $from; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate if ($to =~ /(.*:)([^:]+):?$/) { 247*0Sstevel@tonic-gate ($dir, $toname) = ($1, $2); 248*0Sstevel@tonic-gate } else { 249*0Sstevel@tonic-gate ($dir, $toname) = (":", $to); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate unlink($to); 253*0Sstevel@tonic-gate Mac::MoreFiles::FSpFileCopy($from, $dir, $toname, 1); 254*0Sstevel@tonic-gate }; 255*0Sstevel@tonic-gate } else { 256*0Sstevel@tonic-gate $Syscopy_is_copy = 1; 257*0Sstevel@tonic-gate *syscopy = \© 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate} 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate1; 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate__END__ 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate=head1 NAME 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gateFile::Copy - Copy files or filehandles 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate=head1 SYNOPSIS 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate use File::Copy; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate copy("file1","file2") or die "Copy failed: $!"; 274*0Sstevel@tonic-gate copy("Copy.pm",\*STDOUT); 275*0Sstevel@tonic-gate move("/dev1/fileA","/dev2/fileB"); 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate use POSIX; 278*0Sstevel@tonic-gate use File::Copy cp; 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate $n = FileHandle->new("/a/file","r"); 281*0Sstevel@tonic-gate cp($n,"x");' 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate=head1 DESCRIPTION 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gateThe File::Copy module provides two basic functions, C<copy> and 286*0Sstevel@tonic-gateC<move>, which are useful for getting the contents of a file from 287*0Sstevel@tonic-gateone place to another. 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate=over 4 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate=item * 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gateThe C<copy> function takes two 294*0Sstevel@tonic-gateparameters: a file to copy from and a file to copy to. Either 295*0Sstevel@tonic-gateargument may be a string, a FileHandle reference or a FileHandle 296*0Sstevel@tonic-gateglob. Obviously, if the first argument is a filehandle of some 297*0Sstevel@tonic-gatesort, it will be read from, and if it is a file I<name> it will 298*0Sstevel@tonic-gatebe opened for reading. Likewise, the second argument will be 299*0Sstevel@tonic-gatewritten to (and created if need be). Trying to copy a file on top 300*0Sstevel@tonic-gateof itself is a fatal error. 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gateB<Note that passing in 303*0Sstevel@tonic-gatefiles as handles instead of names may lead to loss of information 304*0Sstevel@tonic-gateon some operating systems; it is recommended that you use file 305*0Sstevel@tonic-gatenames whenever possible.> Files are opened in binary mode where 306*0Sstevel@tonic-gateapplicable. To get a consistent behaviour when copying from a 307*0Sstevel@tonic-gatefilehandle to a file, use C<binmode> on the filehandle. 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gateAn optional third parameter can be used to specify the buffer 310*0Sstevel@tonic-gatesize used for copying. This is the number of bytes from the 311*0Sstevel@tonic-gatefirst file, that wil be held in memory at any given time, before 312*0Sstevel@tonic-gatebeing written to the second file. The default buffer size depends 313*0Sstevel@tonic-gateupon the file, but will generally be the whole file (up to 2Mb), or 314*0Sstevel@tonic-gate1k for filehandles that do not reference files (eg. sockets). 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gateYou may use the syntax C<use File::Copy "cp"> to get at the 317*0Sstevel@tonic-gate"cp" alias for this function. The syntax is I<exactly> the same. 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate=item * 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gateThe C<move> function also takes two parameters: the current name 322*0Sstevel@tonic-gateand the intended name of the file to be moved. If the destination 323*0Sstevel@tonic-gatealready exists and is a directory, and the source is not a 324*0Sstevel@tonic-gatedirectory, then the source file will be renamed into the directory 325*0Sstevel@tonic-gatespecified by the destination. 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gateIf possible, move() will simply rename the file. Otherwise, it copies 328*0Sstevel@tonic-gatethe file to the new location and deletes the original. If an error occurs 329*0Sstevel@tonic-gateduring this copy-and-delete process, you may be left with a (possibly partial) 330*0Sstevel@tonic-gatecopy of the file under the destination name. 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gateYou may use the "mv" alias for this function in the same way that 333*0Sstevel@tonic-gateyou may use the "cp" alias for C<copy>. 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate=back 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gateFile::Copy also provides the C<syscopy> routine, which copies the 338*0Sstevel@tonic-gatefile specified in the first parameter to the file specified in the 339*0Sstevel@tonic-gatesecond parameter, preserving OS-specific attributes and file 340*0Sstevel@tonic-gatestructure. For Unix systems, this is equivalent to the simple 341*0Sstevel@tonic-gateC<copy> routine, which doesn't preserve OS-specific attributes. For 342*0Sstevel@tonic-gateVMS systems, this calls the C<rmscopy> routine (see below). For OS/2 343*0Sstevel@tonic-gatesystems, this calls the C<syscopy> XSUB directly. For Win32 systems, 344*0Sstevel@tonic-gatethis calls C<Win32::CopyFile>. 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gateOn Mac OS (Classic), C<syscopy> calls C<Mac::MoreFiles::FSpFileCopy>, 347*0Sstevel@tonic-gateif available. 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate=head2 Special behaviour if C<syscopy> is defined (OS/2, VMS and Win32) 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gateIf both arguments to C<copy> are not file handles, 352*0Sstevel@tonic-gatethen C<copy> will perform a "system copy" of 353*0Sstevel@tonic-gatethe input file to a new output file, in order to preserve file 354*0Sstevel@tonic-gateattributes, indexed file structure, I<etc.> The buffer size 355*0Sstevel@tonic-gateparameter is ignored. If either argument to C<copy> is a 356*0Sstevel@tonic-gatehandle to an opened file, then data is copied using Perl 357*0Sstevel@tonic-gateoperators, and no effort is made to preserve file attributes 358*0Sstevel@tonic-gateor record structure. 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gateThe system copy routine may also be called directly under VMS and OS/2 361*0Sstevel@tonic-gateas C<File::Copy::syscopy> (or under VMS as C<File::Copy::rmscopy>, which 362*0Sstevel@tonic-gateis the routine that does the actual work for syscopy). 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate=over 4 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate=item rmscopy($from,$to[,$date_flag]) 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gateThe first and second arguments may be strings, typeglobs, typeglob 369*0Sstevel@tonic-gatereferences, or objects inheriting from IO::Handle; 370*0Sstevel@tonic-gatethey are used in all cases to obtain the 371*0Sstevel@tonic-gateI<filespec> of the input and output files, respectively. The 372*0Sstevel@tonic-gatename and type of the input file are used as defaults for the 373*0Sstevel@tonic-gateoutput file, if necessary. 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gateA new version of the output file is always created, which 376*0Sstevel@tonic-gateinherits the structure and RMS attributes of the input file, 377*0Sstevel@tonic-gateexcept for owner and protections (and possibly timestamps; 378*0Sstevel@tonic-gatesee below). All data from the input file is copied to the 379*0Sstevel@tonic-gateoutput file; if either of the first two parameters to C<rmscopy> 380*0Sstevel@tonic-gateis a file handle, its position is unchanged. (Note that this 381*0Sstevel@tonic-gatemeans a file handle pointing to the output file will be 382*0Sstevel@tonic-gateassociated with an old version of that file after C<rmscopy> 383*0Sstevel@tonic-gatereturns, not the newly created version.) 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gateThe third parameter is an integer flag, which tells C<rmscopy> 386*0Sstevel@tonic-gatehow to handle timestamps. If it is E<lt> 0, none of the input file's 387*0Sstevel@tonic-gatetimestamps are propagated to the output file. If it is E<gt> 0, then 388*0Sstevel@tonic-gateit is interpreted as a bitmask: if bit 0 (the LSB) is set, then 389*0Sstevel@tonic-gatetimestamps other than the revision date are propagated; if bit 1 390*0Sstevel@tonic-gateis set, the revision date is propagated. If the third parameter 391*0Sstevel@tonic-gateto C<rmscopy> is 0, then it behaves much like the DCL COPY command: 392*0Sstevel@tonic-gateif the name or type of the output file was explicitly specified, 393*0Sstevel@tonic-gatethen no timestamps are propagated, but if they were taken implicitly 394*0Sstevel@tonic-gatefrom the input filespec, then all timestamps other than the 395*0Sstevel@tonic-gaterevision date are propagated. If this parameter is not supplied, 396*0Sstevel@tonic-gateit defaults to 0. 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gateLike C<copy>, C<rmscopy> returns 1 on success. If an error occurs, 399*0Sstevel@tonic-gateit sets C<$!>, deletes the output file, and returns 0. 400*0Sstevel@tonic-gate 401*0Sstevel@tonic-gate=back 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate=head1 RETURN 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gateAll functions return 1 on success, 0 on failure. 406*0Sstevel@tonic-gate$! will be set if an error was encountered. 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate=head1 NOTES 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate=over 4 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate=item * 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gateOn Mac OS (Classic), the path separator is ':', not '/', and the 415*0Sstevel@tonic-gatecurrent directory is denoted as ':', not '.'. You should be careful 416*0Sstevel@tonic-gateabout specifying relative pathnames. While a full path always begins 417*0Sstevel@tonic-gatewith a volume name, a relative pathname should always begin with a 418*0Sstevel@tonic-gate':'. If specifying a volume name only, a trailing ':' is required. 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gateE.g. 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate copy("file1", "tmp"); # creates the file 'tmp' in the current directory 423*0Sstevel@tonic-gate copy("file1", ":tmp:"); # creates :tmp:file1 424*0Sstevel@tonic-gate copy("file1", ":tmp"); # same as above 425*0Sstevel@tonic-gate copy("file1", "tmp"); # same as above, if 'tmp' is a directory (but don't do 426*0Sstevel@tonic-gate # that, since it may cause confusion, see example #1) 427*0Sstevel@tonic-gate copy("file1", "tmp:file1"); # error, since 'tmp:' is not a volume 428*0Sstevel@tonic-gate copy("file1", ":tmp:file1"); # ok, partial path 429*0Sstevel@tonic-gate copy("file1", "DataHD:"); # creates DataHD:file1 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate move("MacintoshHD:fileA", "DataHD:fileB"); # moves (don't copies) files from one 432*0Sstevel@tonic-gate # volume to another 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate=back 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate=head1 AUTHOR 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gateFile::Copy was written by Aaron Sherman I<E<lt>ajs@ajs.comE<gt>> in 1995, 439*0Sstevel@tonic-gateand updated by Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>> in 1996. 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate=cut 442*0Sstevel@tonic-gate 443