Re: Proposed addition to File::Copy: move
[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#
5
6package File::Copy;
7
441496b2 8use Exporter;
f716a1dd 9use Carp;
55497cff 10use UNIVERSAL qw(isa);
441496b2 11use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION $Too_Big);
12use strict;
f716a1dd 13
14@ISA=qw(Exporter);
441496b2 15@EXPORT=qw(copy move);
16@EXPORT_OK=qw(cp mv);
f716a1dd 17
441496b2 18$VERSION = '1.6';
19$Too_Big = 1024 * 1024 * 2;
f716a1dd 20
21sub VERSION {
22 # Version of File::Copy
441496b2 23 return $VERSION;
f716a1dd 24}
25
26sub copy {
27 croak("Usage: copy( file1, file2 [, buffersize]) ")
28 unless(@_ == 2 || @_ == 3);
29
55497cff 30 if (defined &File::Copy::syscopy &&
31 \&File::Copy::syscopy != \&File::Copy::copy &&
32 ref(\$_[1]) ne 'GLOB' &&
33 !(defined ref $_[1] and isa($_[1], 'GLOB')))
34 { return File::Copy::syscopy($_[0],$_[1]) }
a5f75d66 35
f716a1dd 36 my $from = shift;
37 my $to = shift;
f716a1dd 38 my $closefrom=0;
39 my $closeto=0;
40 my ($size, $status, $r, $buf);
41 local(*FROM, *TO);
48a5c399 42 local($\) = '';
f716a1dd 43
441496b2 44 if (ref($from) && (isa($from,'GLOB') || isa($from,'IO::Handle'))) {
f716a1dd 45 *FROM = *$from;
441496b2 46 } elsif (ref(\$from) eq 'GLOB') {
47 *FROM = $from;
f716a1dd 48 } else {
441496b2 49 open(FROM,"<$from") or goto fail_open1;
9b957b78 50 binmode FROM;
f716a1dd 51 $closefrom = 1;
52 }
53
441496b2 54 if (ref($to) && (isa($to,'GLOB') || isa($to,'IO::Handle'))) {
f716a1dd 55 *TO = *$to;
441496b2 56 } elsif (ref(\$to) eq 'GLOB') {
57 *TO = $to;
f716a1dd 58 } else {
441496b2 59 open(TO,">$to") or goto fail_open2;
9b957b78 60 binmode TO;
f716a1dd 61 $closeto=1;
62 }
63
64 if (@_) {
65 $size = shift(@_) + 0;
66 croak("Bad buffer size for copy: $size\n") unless ($size > 0);
67 } else {
68 $size = -s FROM;
69 $size = 1024 if ($size < 512);
441496b2 70 $size = $Too_Big if ($size > $Too_Big);
f716a1dd 71 }
72
73 $buf = '';
74 while(defined($r = read(FROM,$buf,$size)) && $r > 0) {
75 if (syswrite (TO,$buf,$r) != $r) {
76 goto fail_inner;
77 }
78 }
441496b2 79 goto fail_inner unless defined($r);
f716a1dd 80 close(TO) || goto fail_open2 if $closeto;
81 close(FROM) || goto fail_open1 if $closefrom;
48a5c399 82 # Use this idiom to avoid uninitialized value warning.
f716a1dd 83 return 1;
84
85 # All of these contortions try to preserve error messages...
86 fail_inner:
87 if ($closeto) {
88 $status = $!;
89 $! = 0;
90 close TO;
91 $! = $status unless $!;
92 }
93 fail_open2:
94 if ($closefrom) {
95 $status = $!;
96 $! = 0;
97 close FROM;
98 $! = $status unless $!;
99 }
100 fail_open1:
f716a1dd 101 return 0;
102}
9b957b78 103
441496b2 104sub move {
105 my($from,$to) = @_;
106 my($copied,$tosz1,$tomt1,$tosz2,$tomt2,$sts,$ossts);
107
108 return 1 if rename $from, $to;
109
110 ($tosz1,$tomt1) = (stat($to))[7,9];
111 return 1 if ($copied = copy($from,$to)) && unlink($from);
112
113 ($sts,$ossts) = ($! + 0, $^E + 0);
114 ($tosz2,$tomt2) = ((stat($to))[7,9],0,0) if defined $tomt1;
115 unlink($to) if !defined($tomt1) || $tomt1 != $tomt2 || $tosz1 != $tosz2;
116 ($!,$^E) = ($sts,$ossts);
117 return 0;
118}
9b957b78 119
441496b2 120{
121 local($^W) = 0; # Hush up used-once warning
122 *cp = \&copy;
123 *mv = \&move;
124}
9b957b78 125# &syscopy is an XSUB under OS/2
441496b2 126*syscopy = ($^O eq 'VMS' ? \&rmscopy : \&copy) unless defined &syscopy;
f716a1dd 127
1281;
129
130__END__
a5f75d66 131
f716a1dd 132=head1 NAME
133
134File::Copy - Copy files or filehandles
135
a5f75d66 136=head1 SYNOPSIS
f716a1dd 137
138 use File::Copy;
139
140 copy("file1","file2");
141 copy("Copy.pm",\*STDOUT);'
441496b2 142 move("/dev1/fileA","/dev2/fileB");
f716a1dd 143
144 use POSIX;
145 use File::Copy cp;
146
147 $n=FileHandle->new("/dev/null","r");
148 cp($n,"x");'
149
150=head1 DESCRIPTION
151
441496b2 152The File::Copy module provides two basic functions, C<copy> and
153C<move>, which are useful for getting the contents of a file from
154one place to another.
155
156=over 4
157
158=item *
159
160The C<copy> function takes two
f716a1dd 161parameters: a file to copy from and a file to copy to. Either
162argument may be a string, a FileHandle reference or a FileHandle
163glob. Obviously, if the first argument is a filehandle of some
164sort, it will be read from, and if it is a file I<name> it will
165be opened for reading. Likewise, the second argument will be
9b957b78 166written to (and created if need be). Note that passing in
167files as handles instead of names may lead to loss of information
168on some operating systems; it is recommended that you use file
169names whenever possible.
f716a1dd 170
171An optional third parameter can be used to specify the buffer
172size used for copying. This is the number of bytes from the
173first file, that wil be held in memory at any given time, before
174being written to the second file. The default buffer size depends
175upon the file, but will generally be the whole file (up to 2Mb), or
1761k for filehandles that do not reference files (eg. sockets).
177
178You may use the syntax C<use File::Copy "cp"> to get at the
179"cp" alias for this function. The syntax is I<exactly> the same.
180
441496b2 181=item *
182
183The C<move> function also takes two parameters: the current name
184and the intended name of the file to be moved. If possible, it
185will simply rename the file. Otherwise, it copies the file to
186the new location and deletes the original. If an error occurs during
187this copy-and-delete process, you may be left with a (possibly partial)
188copy of the file under the destination name.
189
190You may use the "mv" alias for this function in the same way that
191you may use the "cp" alias for C<copy>.
192
193=back
194
9b957b78 195File::Copy also provides the C<syscopy> routine, which copies the
196file specified in the first parameter to the file specified in the
197second parameter, preserving OS-specific attributes and file
198structure. For Unix systems, this is equivalent to the simple
199C<copy> routine. For VMS systems, this calls the C<rmscopy>
200routine (see below). For OS/2 systems, this calls the C<syscopy>
201XSUB directly.
202
55497cff 203=head2 Special behavior if C<syscopy> is defined (VMS and OS/2)
9b957b78 204
205If the second argument to C<copy> is not a file handle for an
441496b2 206already opened file, then C<copy> will perform a "system copy" of
9b957b78 207the input file to a new output file, in order to preserve file
208attributes, indexed file structure, I<etc.> The buffer size
209parameter is ignored. If the second argument to C<copy> is a
210Perl handle to an opened file, then data is copied using Perl
211operators, and no effort is made to preserve file attributes
212or record structure.
213
55497cff 214The system copy routine may also be called directly under VMS and OS/2
215as C<File::Copy::syscopy> (or under VMS as C<File::Copy::rmscopy>, which
9b957b78 216is just an alias for this routine).
217
441496b2 218=over 4
55497cff 219
9b957b78 220=item rmscopy($from,$to[,$date_flag])
221
222The first and second arguments may be strings, typeglobs, or
223typeglob references; they are used in all cases to obtain the
224I<filespec> of the input and output files, respectively. The
225name and type of the input file are used as defaults for the
226output file, if necessary.
227
228A new version of the output file is always created, which
229inherits the structure and RMS attributes of the input file,
230except for owner and protections (and possibly timestamps;
231see below). All data from the input file is copied to the
232output file; if either of the first two parameters to C<rmscopy>
233is a file handle, its position is unchanged. (Note that this
234means a file handle pointing to the output file will be
235associated with an old version of that file after C<rmscopy>
236returns, not the newly created version.)
237
238The third parameter is an integer flag, which tells C<rmscopy>
1fef88e7 239how to handle timestamps. If it is E<lt> 0, none of the input file's
240timestamps are propagated to the output file. If it is E<gt> 0, then
9b957b78 241it is interpreted as a bitmask: if bit 0 (the LSB) is set, then
242timestamps other than the revision date are propagated; if bit 1
243is set, the revision date is propagated. If the third parameter
244to C<rmscopy> is 0, then it behaves much like the DCL COPY command:
245if the name or type of the output file was explicitly specified,
246then no timestamps are propagated, but if they were taken implicitly
247from the input filespec, then all timestamps other than the
248revision date are propagated. If this parameter is not supplied,
249it defaults to 0.
250
251Like C<copy>, C<rmscopy> returns 1 on success. If an error occurs,
252it sets C<$!>, deletes the output file, and returns 0.
253
55497cff 254=back
255
f716a1dd 256=head1 RETURN
257
441496b2 258All functions return 1 on success, 0 on failure.
259$! will be set if an error was encountered.
f716a1dd 260
261=head1 AUTHOR
262
441496b2 263File::Copy was written by Aaron Sherman I<E<lt>ajs@ajs.comE<gt>> in 1995,
264and updated by Charles Bailey I<E<lt>bailey@genetics.upenn.eduE<gt>> in 1996.
f716a1dd 265
266=cut
441496b2 267