This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Another set of doc patches from Abigail
[perl5.git] / lib / File / Copy.pm
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 #
5 # Additions copyright 1996 by Charles Bailey.  Permission is granted
6 # to distribute the revised code under the same terms as Perl itself.
7
8 package File::Copy;
9
10 use strict;
11 use Carp;
12 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION $Too_Big
13             &copy &syscopy &cp &mv);
14
15 # Note that this module implements only *part* of the API defined by
16 # the File/Copy.pm module of the File-Tools-2.0 package.  However, that
17 # package has not yet been updated to work with Perl 5.004, and so it
18 # would be a Bad Thing for the CPAN module to grab it and replace this
19 # module.  Therefore, we set this module's version higher than 2.0.
20 $VERSION = '2.02';
21
22 require Exporter;
23 @ISA = qw(Exporter);
24 @EXPORT = qw(copy move);
25 @EXPORT_OK = qw(cp mv);
26
27 $Too_Big = 1024 * 1024 * 2;
28
29 sub _catname { #  Will be replaced by File::Spec when it arrives
30     my($from, $to) = @_;
31     if (not defined &basename) {
32         require File::Basename;
33         import  File::Basename 'basename';
34     }
35     if ($^O eq 'VMS')  { $to = VMS::Filespec::vmspath($to) . basename($from); }
36     elsif ($^O eq 'MacOS') { $to .= ':' . basename($from); }
37     elsif ($to =~ m|\\|)   { $to .= '\\' . basename($from); }
38     else                   { $to .= '/' . basename($from); }
39 }
40
41 sub copy {
42     croak("Usage: copy(FROM, TO [, BUFFERSIZE]) ")
43       unless(@_ == 2 || @_ == 3);
44
45     my $from = shift;
46     my $to = shift;
47
48     my $from_a_handle = (ref($from)
49                          ? (ref($from) eq 'GLOB'
50                             || UNIVERSAL::isa($from, 'GLOB')
51                             || UNIVERSAL::isa($from, 'IO::Handle'))
52                          : (ref(\$from) eq 'GLOB'));
53     my $to_a_handle =   (ref($to)
54                          ? (ref($to) eq 'GLOB'
55                             || UNIVERSAL::isa($to, 'GLOB')
56                             || UNIVERSAL::isa($to, 'IO::Handle'))
57                          : (ref(\$to) eq 'GLOB'));
58
59     if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) {
60         $to = _catname($from, $to);
61     }
62
63     if (defined &syscopy && \&syscopy != \&copy
64         && !$to_a_handle
65         && !($from_a_handle && $^O eq 'os2' )   # OS/2 cannot handle handles
66         && !($from_a_handle && $^O eq 'mpeix')  # and neither can MPE/iX.
67        )        
68     {
69         return syscopy($from, $to);
70     }
71
72     my $closefrom = 0;
73     my $closeto = 0;
74     my ($size, $status, $r, $buf);
75     local(*FROM, *TO);
76     local($\) = '';
77
78     if ($from_a_handle) {
79         *FROM = *$from{FILEHANDLE};
80     } else {
81         $from = "./$from" if $from =~ /^\s/;
82         open(FROM, "< $from\0") or goto fail_open1;
83         binmode FROM or die "($!,$^E)";
84         $closefrom = 1;
85     } 
86  
87     if ($to_a_handle) {
88         *TO = *$to{FILEHANDLE};
89     } else {        
90         $to = "./$to" if $to =~ /^\s/;
91         open(TO,"> $to\0") or goto fail_open2;
92         binmode TO or die "($!,$^E)";
93         $closeto = 1;
94     }  
95
96     if (@_) {
97         $size = shift(@_) + 0;
98         croak("Bad buffer size for copy: $size\n") unless ($size > 0);
99     } else {
100         $size = -s FROM;
101         $size = 1024 if ($size < 512);
102         $size = $Too_Big if ($size > $Too_Big);
103     }
104
105     $! = 0;
106     for (;;) {
107         my ($r, $w, $t);
108         defined($r = sysread(FROM, $buf, $size))
109             or goto fail_inner;
110         last unless $r;
111         for ($w = 0; $w < $r; $w += $t) {
112             $t = syswrite(TO, $buf, $r - $w, $w)
113                 or goto fail_inner;
114         }
115     }
116
117     close(TO) || goto fail_open2 if $closeto;
118     close(FROM) || goto fail_open1 if $closefrom;
119
120     # Use this idiom to avoid uninitialized value warning.
121     return 1;
122     
123     # All of these contortions try to preserve error messages...
124   fail_inner:
125     if ($closeto) {
126         $status = $!;
127         $! = 0;
128         close TO;
129         $! = $status unless $!;
130     }
131   fail_open2:
132     if ($closefrom) {
133         $status = $!;
134         $! = 0;
135         close FROM;
136         $! = $status unless $!;
137     }
138   fail_open1:
139     return 0;
140 }
141
142 sub move {
143     my($from,$to) = @_;
144     my($copied,$fromsz,$tosz1,$tomt1,$tosz2,$tomt2,$sts,$ossts);
145
146     if (-d $to && ! -d $from) {
147         $to = _catname($from, $to);
148     }
149
150     ($tosz1,$tomt1) = (stat($to))[7,9];
151     $fromsz = -s $from;
152     if ($^O eq 'os2' and defined $tosz1 and defined $fromsz) {
153       # will not rename with overwrite
154       unlink $to;
155     }
156     return 1 if rename $from, $to;
157
158     ($sts,$ossts) = ($! + 0, $^E + 0);
159     # Did rename return an error even though it succeeded, because $to
160     # is on a remote NFS file system, and NFS lost the server's ack?
161     return 1 if defined($fromsz) && !-e $from &&           # $from disappeared
162                 (($tosz2,$tomt2) = (stat($to))[7,9]) &&    # $to's there
163                 ($tosz1 != $tosz2 or $tomt1 != $tomt2) &&  #   and changed
164                 $tosz2 == $fromsz;                         # it's all there
165  
166     ($tosz1,$tomt1) = (stat($to))[7,9];  # just in case rename did something
167     return 1 if ($copied = copy($from,$to)) && unlink($from);
168   
169     ($tosz2,$tomt2) = ((stat($to))[7,9],0,0) if defined $tomt1;
170     unlink($to) if !defined($tomt1) or $tomt1 != $tomt2 or $tosz1 != $tosz2;
171     ($!,$^E) = ($sts,$ossts);
172     return 0;
173 }
174
175 *cp = \&copy;
176 *mv = \&move;
177
178 # &syscopy is an XSUB under OS/2
179 unless (defined &syscopy) {
180     if ($^O eq 'VMS') {
181         *syscopy = \&rmscopy;
182     } elsif ($^O eq 'mpeix') {
183         *syscopy = sub {
184             return 0 unless @_ == 2;
185             # Use the MPE cp program in order to
186             # preserve MPE file attributes.
187             return system('/bin/cp', '-f', $_[0], $_[1]) == 0;
188         };
189     } else {
190         *syscopy = \&copy;
191     }
192 }
193
194 1;
195
196 __END__
197
198 =head1 NAME
199
200 File::Copy - Copy files or filehandles
201
202 =head1 SYNOPSIS
203
204         use File::Copy;
205
206         copy("file1","file2");
207         copy("Copy.pm",\*STDOUT);'
208         move("/dev1/fileA","/dev2/fileB");
209
210         use POSIX;
211         use File::Copy cp;
212
213         $n=FileHandle->new("/dev/null","r");
214         cp($n,"x");'
215
216 =head1 DESCRIPTION
217
218 The File::Copy module provides two basic functions, C<copy> and
219 C<move>, which are useful for getting the contents of a file from
220 one place to another.
221
222 =over 4
223
224 =item *
225
226 The C<copy> function takes two
227 parameters: a file to copy from and a file to copy to. Either
228 argument may be a string, a FileHandle reference or a FileHandle
229 glob. Obviously, if the first argument is a filehandle of some
230 sort, it will be read from, and if it is a file I<name> it will
231 be opened for reading. Likewise, the second argument will be
232 written to (and created if need be).
233
234 B<Note that passing in
235 files as handles instead of names may lead to loss of information
236 on some operating systems; it is recommended that you use file
237 names whenever possible.>  Files are opened in binary mode where
238 applicable.  To get a consistent behaviour when copying from a
239 filehandle to a file, use C<binmode> on the filehandle.
240
241 An optional third parameter can be used to specify the buffer
242 size used for copying. This is the number of bytes from the
243 first file, that wil be held in memory at any given time, before
244 being written to the second file. The default buffer size depends
245 upon the file, but will generally be the whole file (up to 2Mb), or
246 1k for filehandles that do not reference files (eg. sockets).
247
248 You may use the syntax C<use File::Copy "cp"> to get at the
249 "cp" alias for this function. The syntax is I<exactly> the same.
250
251 =item *
252
253 The C<move> function also takes two parameters: the current name
254 and the intended name of the file to be moved.  If the destination
255 already exists and is a directory, and the source is not a
256 directory, then the source file will be renamed into the directory
257 specified by the destination.
258
259 If possible, move() will simply rename the file.  Otherwise, it copies
260 the file to the new location and deletes the original.  If an error occurs
261 during this copy-and-delete process, you may be left with a (possibly partial)
262 copy of the file under the destination name.
263
264 You may use the "mv" alias for this function in the same way that
265 you may use the "cp" alias for C<copy>.
266
267 =back
268
269 File::Copy also provides the C<syscopy> routine, which copies the
270 file specified in the first parameter to the file specified in the
271 second parameter, preserving OS-specific attributes and file
272 structure.  For Unix systems, this is equivalent to the simple
273 C<copy> routine.  For VMS systems, this calls the C<rmscopy>
274 routine (see below).  For OS/2 systems, this calls the C<syscopy>
275 XSUB directly.
276
277 =head2 Special behaviour if C<syscopy> is defined (VMS and OS/2)
278
279 If both arguments to C<copy> are not file handles,
280 then C<copy> will perform a "system copy" of
281 the input file to a new output file, in order to preserve file
282 attributes, indexed file structure, I<etc.>  The buffer size
283 parameter is ignored.  If either argument to C<copy> is a
284 handle to an opened file, then data is copied using Perl
285 operators, and no effort is made to preserve file attributes
286 or record structure.
287
288 The system copy routine may also be called directly under VMS and OS/2
289 as C<File::Copy::syscopy> (or under VMS as C<File::Copy::rmscopy>, which
290 is the routine that does the actual work for syscopy).
291
292 =over 4
293
294 =item rmscopy($from,$to[,$date_flag])
295
296 The first and second arguments may be strings, typeglobs, typeglob
297 references, or objects inheriting from IO::Handle;
298 they are used in all cases to obtain the
299 I<filespec> of the input and output files, respectively.  The
300 name and type of the input file are used as defaults for the
301 output file, if necessary.
302
303 A new version of the output file is always created, which
304 inherits the structure and RMS attributes of the input file,
305 except for owner and protections (and possibly timestamps;
306 see below).  All data from the input file is copied to the
307 output file; if either of the first two parameters to C<rmscopy>
308 is a file handle, its position is unchanged.  (Note that this
309 means a file handle pointing to the output file will be
310 associated with an old version of that file after C<rmscopy>
311 returns, not the newly created version.)
312
313 The third parameter is an integer flag, which tells C<rmscopy>
314 how to handle timestamps.  If it is E<lt> 0, none of the input file's
315 timestamps are propagated to the output file.  If it is E<gt> 0, then
316 it is interpreted as a bitmask: if bit 0 (the LSB) is set, then
317 timestamps other than the revision date are propagated; if bit 1
318 is set, the revision date is propagated.  If the third parameter
319 to C<rmscopy> is 0, then it behaves much like the DCL COPY command:
320 if the name or type of the output file was explicitly specified,
321 then no timestamps are propagated, but if they were taken implicitly
322 from the input filespec, then all timestamps other than the
323 revision date are propagated.  If this parameter is not supplied,
324 it defaults to 0.
325
326 Like C<copy>, C<rmscopy> returns 1 on success.  If an error occurs,
327 it sets C<$!>, deletes the output file, and returns 0.
328
329 =back
330
331 =head1 RETURN
332
333 All functions return 1 on success, 0 on failure.
334 $! will be set if an error was encountered.
335
336 =head1 AUTHOR
337
338 File::Copy was written by Aaron Sherman I<E<lt>ajs@ajs.comE<gt>> in 1995,
339 and updated by Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>> in 1996.
340
341 =cut
342