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