This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
When Gconvert is a macro around sprintf with a .* format we need
[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.
ac7b122d 27$VERSION = '2.07';
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}) &&
96a91e01 81 !($^O eq 'Win32' || $^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
5ce10329 277 use POSIX;
f716a1dd 278 use File::Copy cp;
279
23f3aea0 280 $n = FileHandle->new("/a/file","r");
f716a1dd 281 cp($n,"x");'
282
283=head1 DESCRIPTION
284
441496b2
CB
285The File::Copy module provides two basic functions, C<copy> and
286C<move>, which are useful for getting the contents of a file from
287one place to another.
288
289=over 4
290
291=item *
292
293The C<copy> function takes two
f716a1dd 294parameters: a file to copy from and a file to copy to. Either
295argument may be a string, a FileHandle reference or a FileHandle
296glob. Obviously, if the first argument is a filehandle of some
297sort, it will be read from, and if it is a file I<name> it will
298be opened for reading. Likewise, the second argument will be
96a91e01 299written to (and created if need be). Trying to copy a file on top
300of itself is a fatal error.
71be2cbc 301
302B<Note that passing in
9b957b78 303files as handles instead of names may lead to loss of information
304on some operating systems; it is recommended that you use file
e6434134 305names whenever possible.> Files are opened in binary mode where
8dcee03e 306applicable. To get a consistent behaviour when copying from a
e6434134 307filehandle to a file, use C<binmode> on the filehandle.
f716a1dd 308
309An optional third parameter can be used to specify the buffer
310size used for copying. This is the number of bytes from the
311first file, that wil be held in memory at any given time, before
312being written to the second file. The default buffer size depends
313upon the file, but will generally be the whole file (up to 2Mb), or
3141k for filehandles that do not reference files (eg. sockets).
315
316You may use the syntax C<use File::Copy "cp"> to get at the
317"cp" alias for this function. The syntax is I<exactly> the same.
318
441496b2
CB
319=item *
320
321The C<move> function also takes two parameters: the current name
71be2cbc 322and the intended name of the file to be moved. If the destination
323already exists and is a directory, and the source is not a
324directory, then the source file will be renamed into the directory
325specified by the destination.
326
327If possible, move() will simply rename the file. Otherwise, it copies
328the file to the new location and deletes the original. If an error occurs
329during this copy-and-delete process, you may be left with a (possibly partial)
441496b2
CB
330copy of the file under the destination name.
331
332You may use the "mv" alias for this function in the same way that
333you may use the "cp" alias for C<copy>.
334
335=back
336
9b957b78 337File::Copy also provides the C<syscopy> routine, which copies the
338file specified in the first parameter to the file specified in the
339second parameter, preserving OS-specific attributes and file
340structure. For Unix systems, this is equivalent to the simple
f1442e8b
SB
341C<copy> routine, which doesn't preserve OS-specific attributes. For
342VMS systems, this calls the C<rmscopy> routine (see below). For OS/2
343systems, this calls the C<syscopy> XSUB directly. For Win32 systems,
344this calls C<Win32::CopyFile>.
9b957b78 345
bcdb689b
JH
346On Mac OS (Classic), C<syscopy> calls C<Mac::MoreFiles::FSpFileCopy>,
347if available.
348
7509b657 349=head2 Special behaviour if C<syscopy> is defined (OS/2, VMS and Win32)
9b957b78 350
71be2cbc 351If both arguments to C<copy> are not file handles,
352then C<copy> will perform a "system copy" of
9b957b78 353the input file to a new output file, in order to preserve file
354attributes, indexed file structure, I<etc.> The buffer size
71be2cbc 355parameter is ignored. If either argument to C<copy> is a
356handle to an opened file, then data is copied using Perl
9b957b78 357operators, and no effort is made to preserve file attributes
358or record structure.
359
55497cff 360The system copy routine may also be called directly under VMS and OS/2
361as C<File::Copy::syscopy> (or under VMS as C<File::Copy::rmscopy>, which
71be2cbc 362is the routine that does the actual work for syscopy).
9b957b78 363
441496b2 364=over 4
55497cff 365
9b957b78 366=item rmscopy($from,$to[,$date_flag])
367
71be2cbc 368The first and second arguments may be strings, typeglobs, typeglob
369references, or objects inheriting from IO::Handle;
370they are used in all cases to obtain the
9b957b78 371I<filespec> of the input and output files, respectively. The
372name and type of the input file are used as defaults for the
373output file, if necessary.
374
375A new version of the output file is always created, which
376inherits the structure and RMS attributes of the input file,
377except for owner and protections (and possibly timestamps;
378see below). All data from the input file is copied to the
379output file; if either of the first two parameters to C<rmscopy>
380is a file handle, its position is unchanged. (Note that this
381means a file handle pointing to the output file will be
382associated with an old version of that file after C<rmscopy>
383returns, not the newly created version.)
384
385The third parameter is an integer flag, which tells C<rmscopy>
1fef88e7
JM
386how to handle timestamps. If it is E<lt> 0, none of the input file's
387timestamps are propagated to the output file. If it is E<gt> 0, then
9b957b78 388it is interpreted as a bitmask: if bit 0 (the LSB) is set, then
389timestamps other than the revision date are propagated; if bit 1
390is set, the revision date is propagated. If the third parameter
391to C<rmscopy> is 0, then it behaves much like the DCL COPY command:
392if the name or type of the output file was explicitly specified,
393then no timestamps are propagated, but if they were taken implicitly
394from the input filespec, then all timestamps other than the
395revision date are propagated. If this parameter is not supplied,
396it defaults to 0.
397
398Like C<copy>, C<rmscopy> returns 1 on success. If an error occurs,
399it sets C<$!>, deletes the output file, and returns 0.
400
55497cff 401=back
402
f716a1dd 403=head1 RETURN
404
441496b2
CB
405All functions return 1 on success, 0 on failure.
406$! will be set if an error was encountered.
f716a1dd 407
6c254d95
CN
408=head1 NOTES
409
410=over 4
411
412=item *
413
414On Mac OS (Classic), the path separator is ':', not '/', and the
415current directory is denoted as ':', not '.'. You should be careful
416about specifying relative pathnames. While a full path always begins
417with a volume name, a relative pathname should always begin with a
418':'. If specifying a volume name only, a trailing ':' is required.
419
420E.g.
421
422 copy("file1", "tmp"); # creates the file 'tmp' in the current directory
423 copy("file1", ":tmp:"); # creates :tmp:file1
424 copy("file1", ":tmp"); # same as above
425 copy("file1", "tmp"); # same as above, if 'tmp' is a directory (but don't do
426 # that, since it may cause confusion, see example #1)
427 copy("file1", "tmp:file1"); # error, since 'tmp:' is not a volume
428 copy("file1", ":tmp:file1"); # ok, partial path
429 copy("file1", "DataHD:"); # creates DataHD:file1
430
431 move("MacintoshHD:fileA", "DataHD:fileB"); # moves (don't copies) files from one
432 # volume to another
433
434=back
435
f716a1dd 436=head1 AUTHOR
437
441496b2 438File::Copy was written by Aaron Sherman I<E<lt>ajs@ajs.comE<gt>> in 1995,
bd3fa61c 439and updated by Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>> in 1996.
f716a1dd 440
441=cut
441496b2 442