* Synced the perlfaq
[p5sagit/p5-mst-13.2.git] / lib / File / Copy.pm
CommitLineData
f716a1dd 1# File/Copy.pm. Written in 1994 by Aaron Sherman <ajs@ajs.com>. This
2# source code has been placed in the public domain by the author.
3# Please be kind and preserve the documentation.
4#
71be2cbc 5# Additions copyright 1996 by Charles Bailey. Permission is granted
6# to distribute the revised code under the same terms as Perl itself.
f716a1dd 7
8package File::Copy;
9
3b825e41 10use 5.006;
71be2cbc 11use strict;
b395063c 12use warnings;
6c254d95 13use File::Spec;
96a91e01 14use Config;
e63b3379 15# During perl build, we need File::Copy but Scalar::Util might not be built yet
e55c0a82 16# And then we need these games to avoid loading overload, as that will
17# confuse miniperl during the bootstrap of perl.
18my $Scalar_Util_loaded = eval q{ require Scalar::Util; require overload; 1 };
17f410f9 19our(@ISA, @EXPORT, @EXPORT_OK, $VERSION, $Too_Big, $Syscopy_is_copy);
20sub copy;
21sub syscopy;
22sub cp;
23sub mv;
71be2cbc 24
16f708c9 25$VERSION = '2.16';
f716a1dd 26
71be2cbc 27require Exporter;
28@ISA = qw(Exporter);
29@EXPORT = qw(copy move);
30@EXPORT_OK = qw(cp mv);
f716a1dd 31
441496b2 32$Too_Big = 1024 * 1024 * 2;
f716a1dd 33
8878f897 34sub croak {
35 require Carp;
36 goto &Carp::croak;
37}
38
754f2cd0 39sub carp {
40 require Carp;
41 goto &Carp::carp;
42}
43
bcdb689b 44my $macfiles;
45if ($^O eq 'MacOS') {
46 $macfiles = eval { require Mac::MoreFiles };
47 warn 'Mac::MoreFiles could not be loaded; using non-native syscopy'
3a2263fe 48 if $@ && $^W;
bcdb689b 49}
50
fc06fdeb 51# Look up the feature settings on VMS using VMS::Feature when available.
52
53my $use_vms_feature = 0;
54BEGIN {
55 if ($^O eq 'VMS') {
37930f0f 56 if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
fc06fdeb 57 $use_vms_feature = 1;
58 }
59 }
60}
61
62# Need to look up the UNIX report mode. This may become a dynamic mode
63# in the future.
64sub _vms_unix_rpt {
65 my $unix_rpt;
66 if ($use_vms_feature) {
67 $unix_rpt = VMS::Feature::current("filename_unix_report");
68 } else {
69 my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
70 $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
71 }
72 return $unix_rpt;
73}
74
75# Need to look up the EFS character set mode. This may become a dynamic
76# mode in the future.
77sub _vms_efs {
78 my $efs;
79 if ($use_vms_feature) {
80 $efs = VMS::Feature::current("efs_charset");
81 } else {
82 my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
83 $efs = $env_efs =~ /^[ET1]/i;
84 }
85 return $efs;
86}
87
88
6c254d95 89sub _catname {
71be2cbc 90 my($from, $to) = @_;
91 if (not defined &basename) {
92 require File::Basename;
93 import File::Basename 'basename';
94 }
6c254d95 95
96 if ($^O eq 'MacOS') {
97 # a partial dir name that's valid only in the cwd (e.g. 'tmp')
98 $to = ':' . $to if $to !~ /:/;
99 }
100
101 return File::Spec->catfile($to, basename($from));
f716a1dd 102}
103
236a0738 104# _eq($from, $to) tells whether $from and $to are identical
236a0738 105sub _eq {
e55c0a82 106 my ($from, $to) = map {
107 $Scalar_Util_loaded && Scalar::Util::blessed($_)
108 && overload::Method($_, q{""})
109 ? "$_"
110 : $_
111 } (@_);
112 return '' if ( (ref $from) xor (ref $to) );
113 return $from == $to if ref $from;
114 return $from eq $to;
236a0738 115}
116
f716a1dd 117sub copy {
71be2cbc 118 croak("Usage: copy(FROM, TO [, BUFFERSIZE]) ")
f716a1dd 119 unless(@_ == 2 || @_ == 3);
120
121 my $from = shift;
122 my $to = shift;
71be2cbc 123
671637fe 124 my $size;
125 if (@_) {
126 $size = shift(@_) + 0;
127 croak("Bad buffer size for copy: $size\n") unless ($size > 0);
128 }
129
71be2cbc 130 my $from_a_handle = (ref($from)
131 ? (ref($from) eq 'GLOB'
d704f39a 132 || UNIVERSAL::isa($from, 'GLOB')
133 || UNIVERSAL::isa($from, 'IO::Handle'))
71be2cbc 134 : (ref(\$from) eq 'GLOB'));
135 my $to_a_handle = (ref($to)
136 ? (ref($to) eq 'GLOB'
d704f39a 137 || UNIVERSAL::isa($to, 'GLOB')
138 || UNIVERSAL::isa($to, 'IO::Handle'))
71be2cbc 139 : (ref(\$to) eq 'GLOB'));
140
236a0738 141 if (_eq($from, $to)) { # works for references, too
754f2cd0 142 carp("'$from' and '$to' are identical (not copied)");
143 # The "copy" was a success as the source and destination contain
144 # the same data.
145 return 1;
96a91e01 146 }
147
ac7b122d 148 if ((($Config{d_symlink} && $Config{d_readlink}) || $Config{d_link}) &&
4c38808d 149 !($^O eq 'MSWin32' || $^O eq 'os2')) {
ac7b122d 150 my @fs = stat($from);
151 if (@fs) {
96a91e01 152 my @ts = stat($to);
16f708c9 153 if (@ts && $fs[0] == $ts[0] && $fs[1] == $ts[1] && !-p $from) {
754f2cd0 154 carp("'$from' and '$to' are identical (not copied)");
155 return 0;
96a91e01 156 }
157 }
158 }
159
71be2cbc 160 if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) {
161 $to = _catname($from, $to);
162 }
163
1a04d035 164 if (defined &syscopy && !$Syscopy_is_copy
e6434134 165 && !$to_a_handle
1d84e8df 166 && !($from_a_handle && $^O eq 'os2' ) # OS/2 cannot handle handles
167 && !($from_a_handle && $^O eq 'mpeix') # and neither can MPE/iX.
7509b657 168 && !($from_a_handle && $^O eq 'MSWin32')
fa648be5 169 && !($from_a_handle && $^O eq 'MacOS')
2986a63f 170 && !($from_a_handle && $^O eq 'NetWare')
1a04d035 171 )
71be2cbc 172 {
4c38808d 173 my $copy_to = $to;
174
175 if ($^O eq 'VMS' && -e $from) {
176
177 if (! -d $to && ! -d $from) {
178
fc06fdeb 179 my $vms_efs = _vms_efs();
180 my $unix_rpt = _vms_unix_rpt();
181 my $unix_mode = 0;
182 my $from_unix = 0;
183 $from_unix = 1 if ($from =~ /^\.\.?$/);
184 my $from_vms = 0;
185 $from_vms = 1 if ($from =~ m#[\[<\]]#);
186
187 # Need to know if we are in Unix mode.
188 if ($from_vms == $from_unix) {
189 $unix_mode = $unix_rpt;
190 } else {
191 $unix_mode = $from_unix;
192 }
193
4c38808d 194 # VMS has sticky defaults on extensions, which means that
195 # if there is a null extension on the destination file, it
196 # will inherit the extension of the source file
197 # So add a '.' for a null extension.
198
fc06fdeb 199 # In unix_rpt mode, the trailing dot should not be added.
200
201 if ($vms_efs) {
202 $copy_to = $to;
203 } else {
204 $copy_to = VMS::Filespec::vmsify($to);
205 }
4c38808d 206 my ($vol, $dirs, $file) = File::Spec->splitpath($copy_to);
fc06fdeb 207 $file = $file . '.'
208 unless (($file =~ /(?<!\^)\./) || $unix_rpt);
4c38808d 209 $copy_to = File::Spec->catpath($vol, $dirs, $file);
210
211 # Get rid of the old versions to be like UNIX
212 1 while unlink $copy_to;
213 }
214 }
215
079cb8cc 216 return syscopy($from, $copy_to) || 0;
71be2cbc 217 }
218
219 my $closefrom = 0;
220 my $closeto = 0;
671637fe 221 my ($status, $r, $buf);
48a5c399 222 local($\) = '';
f716a1dd 223
23ba2776 224 my $from_h;
71be2cbc 225 if ($from_a_handle) {
23ba2776 226 $from_h = $from;
f716a1dd 227 } else {
cfa308ca 228 open $from_h, "<", $from or goto fail_open1;
23ba2776 229 binmode $from_h or die "($!,$^E)";
e63b3379 230 $closefrom = 1;
1a04d035 231 }
232
671637fe 233 # Seems most logical to do this here, in case future changes would want to
234 # make this croak for some reason.
235 unless (defined $size) {
236 $size = tied(*$from_h) ? 0 : -s $from_h || 0;
237 $size = 1024 if ($size < 512);
238 $size = $Too_Big if ($size > $Too_Big);
239 }
240
23ba2776 241 my $to_h;
71be2cbc 242 if ($to_a_handle) {
23ba2776 243 $to_h = $to;
1a04d035 244 } else {
fa648be5 245 $to = _protect($to) if $to =~ /^\s/s;
e63b3379 246 $to_h = \do { local *FH };
247 open $to_h, ">", $to or goto fail_open2;
91ca337e 248 binmode $to_h or die "($!,$^E)";
71be2cbc 249 $closeto = 1;
1a04d035 250 }
f716a1dd 251
71be2cbc 252 $! = 0;
253 for (;;) {
254 my ($r, $w, $t);
23ba2776 255 defined($r = sysread($from_h, $buf, $size))
71be2cbc 256 or goto fail_inner;
257 last unless $r;
258 for ($w = 0; $w < $r; $w += $t) {
23ba2776 259 $t = syswrite($to_h, $buf, $r - $w, $w)
71be2cbc 260 or goto fail_inner;
f716a1dd 261 }
262 }
71be2cbc 263
23ba2776 264 close($to_h) || goto fail_open2 if $closeto;
265 close($from_h) || goto fail_open1 if $closefrom;
71be2cbc 266
48a5c399 267 # Use this idiom to avoid uninitialized value warning.
f716a1dd 268 return 1;
1a04d035 269
f716a1dd 270 # All of these contortions try to preserve error messages...
271 fail_inner:
272 if ($closeto) {
273 $status = $!;
274 $! = 0;
23ba2776 275 close $to_h;
f716a1dd 276 $! = $status unless $!;
277 }
278 fail_open2:
279 if ($closefrom) {
280 $status = $!;
281 $! = 0;
23ba2776 282 close $from_h;
f716a1dd 283 $! = $status unless $!;
284 }
285 fail_open1:
f716a1dd 286 return 0;
287}
9b957b78 288
e63b3379 289sub cp {
71be2cbc 290 my($from,$to) = @_;
e63b3379 291 my(@fromstat) = stat $from;
292 my(@tostat) = stat $to;
293 my $perm;
294
295 return 0 unless copy(@_) and @fromstat;
296
297 if (@tostat) {
298 $perm = $tostat[2];
299 } else {
300 $perm = $fromstat[2] & ~(umask || 0);
301 @tostat = stat $to;
302 }
303 # Might be more robust to look for S_I* in Fcntl, but we're
304 # trying to avoid dependence on any XS-containing modules,
305 # since File::Copy is used during the Perl build.
306 $perm &= 07777;
307 if ($perm & 06000) {
308 croak("Unable to check setuid/setgid permissions for $to: $!")
309 unless @tostat;
310
311 if ($perm & 04000 and # setuid
312 $fromstat[4] != $tostat[4]) { # owner must match
313 $perm &= ~06000;
314 }
315
316 if ($perm & 02000) { # setgid
317 my $ok = $fromstat[5] == $tostat[5]; # group must match
318 if ($ok) { # and we must be in group
319 my $uname = (getpwuid($>))[0] || '';
7fa8fd0b 320 my $group = (getpwuid($>))[3];
321 $ok = $group && $group == $fromstat[5] ||
322 grep { $_ eq $uname }
323 split /\s+/, (getgrgid($fromstat[5]))[3];
e63b3379 324 }
325 $perm &= ~06000 unless $ok;
326 }
327 }
328 return 0 unless @tostat;
329 return 1 if $perm == ($tostat[2] & 07777);
330 return eval { chmod $perm, $to; } ? 1 : 0;
331}
332
333sub _move {
334 croak("Usage: move(FROM, TO) ") unless @_ == 3;
335
336 my($from,$to,$fallback) = @_;
754f2cd0 337
fa76202e 338 my($fromsz,$tosz1,$tomt1,$tosz2,$tomt2,$sts,$ossts);
441496b2 339
71be2cbc 340 if (-d $to && ! -d $from) {
341 $to = _catname($from, $to);
342 }
343
344 ($tosz1,$tomt1) = (stat($to))[7,9];
345 $fromsz = -s $from;
e6434134 346 if ($^O eq 'os2' and defined $tosz1 and defined $fromsz) {
347 # will not rename with overwrite
348 unlink $to;
349 }
4c38808d 350
351 my $rename_to = $to;
352 if (-$^O eq 'VMS' && -e $from) {
353
354 if (! -d $to && ! -d $from) {
fc06fdeb 355
356 my $vms_efs = _vms_efs();
357 my $unix_rpt = _vms_unix_rpt();
358 my $unix_mode = 0;
359 my $from_unix = 0;
360 $from_unix = 1 if ($from =~ /^\.\.?$/);
361 my $from_vms = 0;
362 $from_vms = 1 if ($from =~ m#[\[<\]]#);
363
364 # Need to know if we are in Unix mode.
365 if ($from_vms == $from_unix) {
366 $unix_mode = $unix_rpt;
367 } else {
368 $unix_mode = $from_unix;
369 }
370
4c38808d 371 # VMS has sticky defaults on extensions, which means that
372 # if there is a null extension on the destination file, it
373 # will inherit the extension of the source file
374 # So add a '.' for a null extension.
375
fc06fdeb 376 # In unix_rpt mode, the trailing dot should not be added.
377
378 if ($vms_efs) {
379 $rename_to = $to;
380 } else {
381 $rename_to = VMS::Filespec::vmsify($to);
382 }
4c38808d 383 my ($vol, $dirs, $file) = File::Spec->splitpath($rename_to);
fc06fdeb 384 $file = $file . '.'
385 unless (($file =~ /(?<!\^)\./) || $unix_rpt);
4c38808d 386 $rename_to = File::Spec->catpath($vol, $dirs, $file);
387
388 # Get rid of the old versions to be like UNIX
389 1 while unlink $rename_to;
390 }
391 }
392
393 return 1 if rename $from, $rename_to;
71be2cbc 394
71be2cbc 395 # Did rename return an error even though it succeeded, because $to
396 # is on a remote NFS file system, and NFS lost the server's ack?
397 return 1 if defined($fromsz) && !-e $from && # $from disappeared
398 (($tosz2,$tomt2) = (stat($to))[7,9]) && # $to's there
c9fbd0c8 399 ((!defined $tosz1) || # not before or
400 ($tosz1 != $tosz2 or $tomt1 != $tomt2)) && # was changed
71be2cbc 401 $tosz2 == $fromsz; # it's all there
1a04d035 402
71be2cbc 403 ($tosz1,$tomt1) = (stat($to))[7,9]; # just in case rename did something
762548ba 404
405 {
406 local $@;
407 eval {
754f2cd0 408 local $SIG{__DIE__};
e63b3379 409 $fallback->($from,$to) or die;
762548ba 410 my($atime, $mtime) = (stat($from))[8,9];
411 utime($atime, $mtime, $to);
412 unlink($from) or die;
413 };
414 return 1 unless $@;
415 }
fa76202e 416 ($sts,$ossts) = ($! + 0, $^E + 0);
1a04d035 417
71be2cbc 418 ($tosz2,$tomt2) = ((stat($to))[7,9],0,0) if defined $tomt1;
419 unlink($to) if !defined($tomt1) or $tomt1 != $tomt2 or $tosz1 != $tosz2;
420 ($!,$^E) = ($sts,$ossts);
421 return 0;
441496b2 422}
9b957b78 423
e63b3379 424sub move { _move(@_,\&copy); }
425sub mv { _move(@_,\&cp); }
71be2cbc 426
9b957b78 427# &syscopy is an XSUB under OS/2
1d84e8df 428unless (defined &syscopy) {
429 if ($^O eq 'VMS') {
430 *syscopy = \&rmscopy;
431 } elsif ($^O eq 'mpeix') {
432 *syscopy = sub {
3f5ee302 433 return 0 unless @_ == 2;
1d84e8df 434 # Use the MPE cp program in order to
435 # preserve MPE file attributes.
436 return system('/bin/cp', '-f', $_[0], $_[1]) == 0;
437 };
cf2f24a4 438 } elsif ($^O eq 'MSWin32' && defined &DynaLoader::boot_DynaLoader) {
439 # Win32::CopyFile() fill only work if we can load Win32.xs
7509b657 440 *syscopy = sub {
441 return 0 unless @_ == 2;
442 return Win32::CopyFile(@_, 1);
443 };
bcdb689b 444 } elsif ($macfiles) {
fa648be5 445 *syscopy = sub {
446 my($from, $to) = @_;
447 my($dir, $toname);
448
449 return 0 unless -e $from;
450
451 if ($to =~ /(.*:)([^:]+):?$/) {
452 ($dir, $toname) = ($1, $2);
453 } else {
454 ($dir, $toname) = (":", $to);
455 }
456
457 unlink($to);
458 Mac::MoreFiles::FSpFileCopy($from, $dir, $toname, 1);
459 };
1d84e8df 460 } else {
1a04d035 461 $Syscopy_is_copy = 1;
1d84e8df 462 *syscopy = \&copy;
463 }
464}
f716a1dd 465
4661;
467
468__END__
a5f75d66 469
f716a1dd 470=head1 NAME
471
472File::Copy - Copy files or filehandles
473
a5f75d66 474=head1 SYNOPSIS
f716a1dd 475
5ce10329 476 use File::Copy;
f716a1dd 477
5ce10329 478 copy("file1","file2") or die "Copy failed: $!";
479 copy("Copy.pm",\*STDOUT);
441496b2 480 move("/dev1/fileA","/dev2/fileB");
f716a1dd 481
78e38bb6 482 use File::Copy "cp";
f716a1dd 483
23f3aea0 484 $n = FileHandle->new("/a/file","r");
c6dfe06b 485 cp($n,"x");
f716a1dd 486
487=head1 DESCRIPTION
488
441496b2 489The File::Copy module provides two basic functions, C<copy> and
490C<move>, which are useful for getting the contents of a file from
491one place to another.
492
493=over 4
494
0cdecedb 495=item copy
496X<copy> X<cp>
441496b2 497
498The C<copy> function takes two
f716a1dd 499parameters: a file to copy from and a file to copy to. Either
500argument may be a string, a FileHandle reference or a FileHandle
501glob. Obviously, if the first argument is a filehandle of some
502sort, it will be read from, and if it is a file I<name> it will
503be opened for reading. Likewise, the second argument will be
96a91e01 504written to (and created if need be). Trying to copy a file on top
505of itself is a fatal error.
71be2cbc 506
507B<Note that passing in
9b957b78 508files as handles instead of names may lead to loss of information
509on some operating systems; it is recommended that you use file
e6434134 510names whenever possible.> Files are opened in binary mode where
8dcee03e 511applicable. To get a consistent behaviour when copying from a
e6434134 512filehandle to a file, use C<binmode> on the filehandle.
f716a1dd 513
514An optional third parameter can be used to specify the buffer
515size used for copying. This is the number of bytes from the
3a964d77 516first file, that will be held in memory at any given time, before
f716a1dd 517being written to the second file. The default buffer size depends
338de517 518upon the file, but will generally be the whole file (up to 2MB), or
f716a1dd 5191k for filehandles that do not reference files (eg. sockets).
520
e63b3379 521You may use the syntax C<use File::Copy "cp"> to get at the C<cp>
522alias for this function. The syntax is I<exactly> the same. The
4efe685a 523behavior is nearly the same as well: as of version 2.15, <cp> will
e63b3379 524preserve the source file's permission bits like the shell utility
525C<cp(1)> would do, while C<copy> uses the default permissions for the
526target file (which may depend on the process' C<umask>, file
527ownership, inherited ACLs, etc.). If an error occurs in setting
528permissions, C<cp> will return 0, regardless of whether the file was
529successfully copied.
9c76cba2 530
0cdecedb 531=item move
532X<move> X<mv> X<rename>
441496b2 533
534The C<move> function also takes two parameters: the current name
71be2cbc 535and the intended name of the file to be moved. If the destination
536already exists and is a directory, and the source is not a
537directory, then the source file will be renamed into the directory
538specified by the destination.
539
540If possible, move() will simply rename the file. Otherwise, it copies
541the file to the new location and deletes the original. If an error occurs
542during this copy-and-delete process, you may be left with a (possibly partial)
441496b2 543copy of the file under the destination name.
544
e63b3379 545You may use the C<mv> alias for this function in the same way that
546you may use the <cp> alias for C<copy>.
441496b2 547
0cdecedb 548=item syscopy
549X<syscopy>
441496b2 550
9b957b78 551File::Copy also provides the C<syscopy> routine, which copies the
552file specified in the first parameter to the file specified in the
553second parameter, preserving OS-specific attributes and file
554structure. For Unix systems, this is equivalent to the simple
f1442e8b 555C<copy> routine, which doesn't preserve OS-specific attributes. For
556VMS systems, this calls the C<rmscopy> routine (see below). For OS/2
557systems, this calls the C<syscopy> XSUB directly. For Win32 systems,
558this calls C<Win32::CopyFile>.
9b957b78 559
bcdb689b 560On Mac OS (Classic), C<syscopy> calls C<Mac::MoreFiles::FSpFileCopy>,
561if available.
562
338de517 563B<Special behaviour if C<syscopy> is defined (OS/2, VMS and Win32)>:
9b957b78 564
71be2cbc 565If both arguments to C<copy> are not file handles,
566then C<copy> will perform a "system copy" of
9b957b78 567the input file to a new output file, in order to preserve file
568attributes, indexed file structure, I<etc.> The buffer size
71be2cbc 569parameter is ignored. If either argument to C<copy> is a
570handle to an opened file, then data is copied using Perl
9b957b78 571operators, and no effort is made to preserve file attributes
572or record structure.
573
55497cff 574The system copy routine may also be called directly under VMS and OS/2
575as C<File::Copy::syscopy> (or under VMS as C<File::Copy::rmscopy>, which
71be2cbc 576is the routine that does the actual work for syscopy).
9b957b78 577
578=item rmscopy($from,$to[,$date_flag])
0cdecedb 579X<rmscopy>
9b957b78 580
71be2cbc 581The first and second arguments may be strings, typeglobs, typeglob
582references, or objects inheriting from IO::Handle;
583they are used in all cases to obtain the
9b957b78 584I<filespec> of the input and output files, respectively. The
585name and type of the input file are used as defaults for the
586output file, if necessary.
587
588A new version of the output file is always created, which
589inherits the structure and RMS attributes of the input file,
590except for owner and protections (and possibly timestamps;
591see below). All data from the input file is copied to the
592output file; if either of the first two parameters to C<rmscopy>
593is a file handle, its position is unchanged. (Note that this
594means a file handle pointing to the output file will be
595associated with an old version of that file after C<rmscopy>
596returns, not the newly created version.)
597
598The third parameter is an integer flag, which tells C<rmscopy>
1fef88e7 599how to handle timestamps. If it is E<lt> 0, none of the input file's
600timestamps are propagated to the output file. If it is E<gt> 0, then
9b957b78 601it is interpreted as a bitmask: if bit 0 (the LSB) is set, then
602timestamps other than the revision date are propagated; if bit 1
603is set, the revision date is propagated. If the third parameter
604to C<rmscopy> is 0, then it behaves much like the DCL COPY command:
605if the name or type of the output file was explicitly specified,
606then no timestamps are propagated, but if they were taken implicitly
607from the input filespec, then all timestamps other than the
608revision date are propagated. If this parameter is not supplied,
609it defaults to 0.
610
611Like C<copy>, C<rmscopy> returns 1 on success. If an error occurs,
612it sets C<$!>, deletes the output file, and returns 0.
613
55497cff 614=back
615
f716a1dd 616=head1 RETURN
617
441496b2 618All functions return 1 on success, 0 on failure.
619$! will be set if an error was encountered.
f716a1dd 620
6c254d95 621=head1 NOTES
622
623=over 4
624
625=item *
626
627On Mac OS (Classic), the path separator is ':', not '/', and the
628current directory is denoted as ':', not '.'. You should be careful
629about specifying relative pathnames. While a full path always begins
630with a volume name, a relative pathname should always begin with a
631':'. If specifying a volume name only, a trailing ':' is required.
632
633E.g.
634
635 copy("file1", "tmp"); # creates the file 'tmp' in the current directory
636 copy("file1", ":tmp:"); # creates :tmp:file1
637 copy("file1", ":tmp"); # same as above
0cdecedb 638 copy("file1", "tmp"); # same as above, if 'tmp' is a directory (but don't do
6c254d95 639 # that, since it may cause confusion, see example #1)
640 copy("file1", "tmp:file1"); # error, since 'tmp:' is not a volume
641 copy("file1", ":tmp:file1"); # ok, partial path
642 copy("file1", "DataHD:"); # creates DataHD:file1
0cdecedb 643
907fbfa1 644 move("MacintoshHD:fileA", "DataHD:fileB"); # moves (doesn't copy) files from one
6c254d95 645 # volume to another
646
647=back
648
f716a1dd 649=head1 AUTHOR
650
441496b2 651File::Copy was written by Aaron Sherman I<E<lt>ajs@ajs.comE<gt>> in 1995,
bd3fa61c 652and updated by Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>> in 1996.
f716a1dd 653
654=cut
441496b2 655