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