OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [Integration_test/] [synthetic_sim/] [perl_lib/] [File/] [Copy/] [Recursive.pm] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 alirezamon
package File::Copy::Recursive;
2
 
3
use strict;
4
 
5
BEGIN {
6
    # Keep older versions of Perl from trying to use lexical warnings
7
    $INC{'warnings.pm'} = "fake warnings entry for < 5.6 perl ($])" if $] < 5.006;
8
}
9
use warnings;
10
 
11
use Carp;
12
use File::Copy;
13
use File::Spec;    #not really needed because File::Copy already gets it, but for good measure :)
14
use Cwd ();
15
 
16
use vars qw(
17
  @ISA      @EXPORT_OK $VERSION  $MaxDepth $KeepMode $CPRFComp $CopyLink
18
  $PFSCheck $RemvBase $NoFtlPth  $ForcePth $CopyLoop $RMTrgFil $RMTrgDir
19
  $CondCopy $BdTrgWrn $SkipFlop  $DirPerms
20
);
21
 
22
require Exporter;
23
@ISA       = qw(Exporter);
24
@EXPORT_OK = qw(fcopy rcopy dircopy fmove rmove dirmove pathmk pathrm pathempty pathrmdir rcopy_glob rmove_glob);
25
 
26
$VERSION = '0.45';
27
 
28
$MaxDepth = 0;
29
$KeepMode = 1;
30
$CPRFComp = 0;
31
$CopyLink = eval { local $SIG{'__DIE__'}; symlink '', ''; 1 } || 0;
32
$PFSCheck = 1;
33
$RemvBase = 0;
34
$NoFtlPth = 0;
35
$ForcePth = 0;
36
$CopyLoop = 0;
37
$RMTrgFil = 0;
38
$RMTrgDir = 0;
39
$CondCopy = {};
40
$BdTrgWrn = 0;
41
$SkipFlop = 0;
42
$DirPerms = 0777;
43
 
44
my $samecheck = sub {
45
    return 1 if $^O eq 'MSWin32';    # need better way to check for this on winders...
46
    return if @_ != 2 || !defined $_[0] || !defined $_[1];
47
    return if $_[0] eq $_[1];
48
 
49
    my $one = '';
50
    if ($PFSCheck) {
51
        $one = join( '-', ( stat $_[0] )[ 0, 1 ] ) || '';
52
        my $two = join( '-', ( stat $_[1] )[ 0, 1 ] ) || '';
53
        if ( $one eq $two && $one ) {
54
            carp "$_[0] and $_[1] are identical";
55
            return;
56
        }
57
    }
58
 
59
    if ( -d $_[0] && !$CopyLoop ) {
60
        $one = join( '-', ( stat $_[0] )[ 0, 1 ] ) if !$one;
61
        my $abs = File::Spec->rel2abs( $_[1] );
62
        my @pth = File::Spec->splitdir($abs);
63
        while (@pth) {
64
            if ( $pth[-1] eq '..' ) {    # cheaper than Cwd::realpath() plus we don't want to resolve symlinks at this point, right?
65
                pop @pth;
66
                pop @pth unless -l File::Spec->catdir(@pth);
67
                next;
68
            }
69
            my $cur = File::Spec->catdir(@pth);
70
            last if !$cur;               # probably not necessary, but nice to have just in case :)
71
            my $two = join( '-', ( stat $cur )[ 0, 1 ] ) || '';
72
            if ( $one eq $two && $one ) {
73
 
74
                # $! = 62; # Too many levels of symbolic links
75
                carp "Caught Deep Recursion Condition: $_[0] contains $_[1]";
76
                return;
77
            }
78
 
79
            pop @pth;
80
        }
81
    }
82
 
83
    return 1;
84
};
85
 
86
my $glob = sub {
87
    my ( $do, $src_glob, @args ) = @_;
88
 
89
    local $CPRFComp = 1;
90
    require File::Glob;
91
 
92
    my @rt;
93
    for my $path ( File::Glob::bsd_glob($src_glob) ) {
94
        my @call = [ $do->( $path, @args ) ] or return;
95
        push @rt, \@call;
96
    }
97
 
98
    return @rt;
99
};
100
 
101
my $move = sub {
102
    my $fl = shift;
103
    my @x;
104
    if ($fl) {
105
        @x = fcopy(@_) or return;
106
    }
107
    else {
108
        @x = dircopy(@_) or return;
109
    }
110
    if (@x) {
111
        if ($fl) {
112
            unlink $_[0] or return;
113
        }
114
        else {
115
            pathrmdir( $_[0] ) or return;
116
        }
117
        if ($RemvBase) {
118
            my ( $volm, $path ) = File::Spec->splitpath( $_[0] );
119
            pathrm( File::Spec->catpath( $volm, $path, '' ), $ForcePth, $NoFtlPth ) or return;
120
        }
121
    }
122
    return wantarray ? @x : $x[0];
123
};
124
 
125
my $ok_todo_asper_condcopy = sub {
126
    my $org  = shift;
127
    my $copy = 1;
128
    if ( exists $CondCopy->{$org} ) {
129
        if ( $CondCopy->{$org}{'md5'} ) {
130
 
131
        }
132
        if ($copy) {
133
 
134
        }
135
    }
136
    return $copy;
137
};
138
 
139
sub fcopy {
140
    $samecheck->(@_) or return;
141
    if ( $RMTrgFil && ( -d $_[1] || -e $_[1] ) ) {
142
        my $trg = $_[1];
143
        if ( -d $trg ) {
144
            my @trgx = File::Spec->splitpath( $_[0] );
145
            $trg = File::Spec->catfile( $_[1], $trgx[$#trgx] );
146
        }
147
        $samecheck->( $_[0], $trg ) or return;
148
        if ( -e $trg ) {
149
            if ( $RMTrgFil == 1 ) {
150
                unlink $trg or carp "\$RMTrgFil failed: $!";
151
            }
152
            else {
153
                unlink $trg or return;
154
            }
155
        }
156
    }
157
    my ( $volm, $path ) = File::Spec->splitpath( $_[1] );
158
    if ( $path && !-d $path ) {
159
        pathmk( File::Spec->catpath( $volm, $path, '' ), $NoFtlPth );
160
    }
161
    if ( -l $_[0] && $CopyLink ) {
162
        my $target = readlink( shift() );
163
        ($target) = $target =~ m/(.*)/;    # mass-untaint is OK since we have to allow what the file system does
164
        carp "Copying a symlink ($_[0]) whose target does not exist"
165
          if !-e $target && $BdTrgWrn;
166
        my $new = shift();
167
        unlink $new if -l $new;
168
        symlink( $target, $new ) or return;
169
    }
170
    elsif ( -d $_[0] && -f $_[1] ) {
171
        return;
172
    }
173
    else {
174
        return if -d $_[0];                # address File::Copy::copy() bug outlined in https://rt.perl.org/Public/Bug/Display.html?id=132866
175
        copy(@_) or return;
176
 
177
        my @base_file = File::Spec->splitpath( $_[0] );
178
        my $mode_trg = -d $_[1] ? File::Spec->catfile( $_[1], $base_file[$#base_file] ) : $_[1];
179
 
180
        chmod scalar( ( stat( $_[0] ) )[2] ), $mode_trg if $KeepMode;
181
    }
182
    return wantarray ? ( 1, 0, 0 ) : 1;    # use 0's incase they do math on them and in case rcopy() is called in list context = no uninit val warnings
183
}
184
 
185
sub rcopy {
186
    if ( -l $_[0] && $CopyLink ) {
187
        goto &fcopy;
188
    }
189
 
190
    goto &dircopy if -d $_[0] || substr( $_[0], ( 1 * -1 ), 1 ) eq '*';
191
    goto &fcopy;
192
}
193
 
194
sub rcopy_glob {
195
    $glob->( \&rcopy, @_ );
196
}
197
 
198
sub dircopy {
199
    if ( $RMTrgDir && -d $_[1] ) {
200
        if ( $RMTrgDir == 1 ) {
201
            pathrmdir( $_[1] ) or carp "\$RMTrgDir failed: $!";
202
        }
203
        else {
204
            pathrmdir( $_[1] ) or return;
205
        }
206
    }
207
    my $globstar = 0;
208
    my $_zero    = $_[0];
209
    my $_one     = $_[1];
210
    if ( substr( $_zero, ( 1 * -1 ), 1 ) eq '*' ) {
211
        $globstar = 1;
212
        $_zero = substr( $_zero, 0, ( length($_zero) - 1 ) );
213
    }
214
 
215
    $samecheck->( $_zero, $_[1] ) or return;
216
    if ( !-d $_zero || ( -e $_[1] && !-d $_[1] ) ) {
217
        $! = 20;
218
        return;
219
    }
220
 
221
    if ( !-d $_[1] ) {
222
        pathmk( $_[1], $NoFtlPth ) or return;
223
    }
224
    else {
225
        if ( $CPRFComp && !$globstar ) {
226
            my @parts = File::Spec->splitdir($_zero);
227
            while ( $parts[$#parts] eq '' ) { pop @parts; }
228
            $_one = File::Spec->catdir( $_[1], $parts[$#parts] );
229
        }
230
    }
231
    my $baseend = $_one;
232
    my $level   = 0;
233
    my $filen   = 0;
234
    my $dirn    = 0;
235
 
236
    my $recurs;    #must be my()ed before sub {} since it calls itself
237
    $recurs = sub {
238
        my ( $str, $end, $buf ) = @_;
239
        $filen++ if $end eq $baseend;
240
        $dirn++  if $end eq $baseend;
241
 
242
        $DirPerms = oct($DirPerms) if substr( $DirPerms, 0, 1 ) eq '0';
243
        mkdir( $end, $DirPerms ) or return if !-d $end;
244
        if ( $MaxDepth && $MaxDepth =~ m/^\d+$/ && $level >= $MaxDepth ) {
245
            chmod scalar( ( stat($str) )[2] ), $end if $KeepMode;
246
            return ( $filen, $dirn, $level ) if wantarray;
247
            return $filen;
248
        }
249
 
250
        $level++;
251
 
252
        my @files;
253
        if ( $] < 5.006 ) {
254
            opendir( STR_DH, $str ) or return;
255
            @files = grep( $_ ne '.' && $_ ne '..', readdir(STR_DH) );
256
            closedir STR_DH;
257
        }
258
        else {
259
            opendir( my $str_dh, $str ) or return;
260
            @files = grep( $_ ne '.' && $_ ne '..', readdir($str_dh) );
261
            closedir $str_dh;
262
        }
263
 
264
        for my $file (@files) {
265
            my ($file_ut) = $file =~ m{ (.*) }xms;
266
            my $org = File::Spec->catfile( $str, $file_ut );
267
            my $new = File::Spec->catfile( $end, $file_ut );
268
            if ( -l $org && $CopyLink ) {
269
                my $target = readlink($org);
270
                ($target) = $target =~ m/(.*)/;    # mass-untaint is OK since we have to allow what the file system does
271
                carp "Copying a symlink ($org) whose target does not exist"
272
                  if !-e $target && $BdTrgWrn;
273
                unlink $new if -l $new;
274
                symlink( $target, $new ) or return;
275
            }
276
            elsif ( -d $org ) {
277
                my $rc;
278
                if ( !-w $org && $KeepMode ) {
279
                    local $KeepMode = 0;
280
                    $rc = $recurs->( $org, $new, $buf ) if defined $buf;
281
                    $rc = $recurs->( $org, $new ) if !defined $buf;
282
                    chmod scalar( ( stat($org) )[2] ), $new;
283
                }
284
                else {
285
                    $rc = $recurs->( $org, $new, $buf ) if defined $buf;
286
                    $rc = $recurs->( $org, $new ) if !defined $buf;
287
                }
288
                if ( !$rc ) {
289
                    if ($SkipFlop) {
290
                        next;
291
                    }
292
                    else {
293
                        return;
294
                    }
295
                }
296
                $filen++;
297
                $dirn++;
298
            }
299
            else {
300
                if ( $ok_todo_asper_condcopy->($org) ) {
301
                    if ($SkipFlop) {
302
                        fcopy( $org, $new, $buf ) or next if defined $buf;
303
                        fcopy( $org, $new ) or next if !defined $buf;
304
                    }
305
                    else {
306
                        fcopy( $org, $new, $buf ) or return if defined $buf;
307
                        fcopy( $org, $new ) or return if !defined $buf;
308
                    }
309
                    chmod scalar( ( stat($org) )[2] ), $new if $KeepMode;
310
                    $filen++;
311
                }
312
            }
313
        }
314
        $level--;
315
        chmod scalar( ( stat($str) )[2] ), $end if $KeepMode;
316
        1;
317
 
318
    };
319
 
320
    $recurs->( $_zero, $_one, $_[2] ) or return;
321
    return wantarray ? ( $filen, $dirn, $level ) : $filen;
322
}
323
 
324
sub fmove { $move->( 1, @_ ) }
325
 
326
sub rmove {
327
    if ( -l $_[0] && $CopyLink ) {
328
        goto &fmove;
329
    }
330
 
331
    goto &dirmove if -d $_[0] || substr( $_[0], ( 1 * -1 ), 1 ) eq '*';
332
    goto &fmove;
333
}
334
 
335
sub rmove_glob {
336
    $glob->( \&rmove, @_ );
337
}
338
 
339
sub dirmove { $move->( 0, @_ ) }
340
 
341
sub pathmk {
342
    my ( $vol, $dir, $file ) = File::Spec->splitpath( shift() );
343
    my $nofatal = shift;
344
 
345
    $DirPerms = oct($DirPerms) if substr( $DirPerms, 0, 1 ) eq '0';
346
 
347
    if ( defined($dir) ) {
348
        my (@dirs) = File::Spec->splitdir($dir);
349
 
350
        for ( my $i = 0; $i < scalar(@dirs); $i++ ) {
351
            my $newdir = File::Spec->catdir( @dirs[ 0 .. $i ] );
352
            my $newpth = File::Spec->catpath( $vol, $newdir, "" );
353
 
354
            mkdir( $newpth, $DirPerms ) or return if !-d $newpth && !$nofatal;
355
            mkdir( $newpth, $DirPerms ) if !-d $newpth && $nofatal;
356
        }
357
    }
358
 
359
    if ( defined($file) ) {
360
        my $newpth = File::Spec->catpath( $vol, $dir, $file );
361
 
362
        mkdir( $newpth, $DirPerms ) or return if !-d $newpth && !$nofatal;
363
        mkdir( $newpth, $DirPerms ) if !-d $newpth && $nofatal;
364
    }
365
 
366
    1;
367
}
368
 
369
sub pathempty {
370
    my $pth = shift;
371
 
372
    my ( $orig_dev, $orig_ino ) = ( lstat $pth )[ 0, 1 ];
373
    return 2 if !-d _ || !defined($orig_dev) || ( $^O ne 'MSWin32' && !$orig_ino );    #stat.inode is 0 on Windows
374
 
375
    my $starting_point = Cwd::cwd();
376
    my ( $starting_dev, $starting_ino ) = ( lstat $starting_point )[ 0, 1 ];
377
    chdir($pth) or Carp::croak("Failed to change directory to “$pth”: $!");
378
    $pth = '.';
379
    _bail_if_changed( $pth, $orig_dev, $orig_ino );
380
 
381
    my @names;
382
    my $pth_dh;
383
    if ( $] < 5.006 ) {
384
        opendir( PTH_DH, $pth ) or return;
385
        @names = grep !/^\.\.?$/, readdir(PTH_DH);
386
        closedir PTH_DH;
387
    }
388
    else {
389
        opendir( $pth_dh, $pth ) or return;
390
        @names = grep !/^\.\.?$/, readdir($pth_dh);
391
        closedir $pth_dh;
392
    }
393
    _bail_if_changed( $pth, $orig_dev, $orig_ino );
394
 
395
    for my $name (@names) {
396
        my ($name_ut) = $name =~ m{ (.*) }xms;
397
        my $flpth = File::Spec->catdir( $pth, $name_ut );
398
 
399
        if ( -l $flpth ) {
400
            _bail_if_changed( $pth, $orig_dev, $orig_ino );
401
            unlink $flpth or return;
402
        }
403
        elsif ( -d $flpth ) {
404
            _bail_if_changed( $pth, $orig_dev, $orig_ino );
405
            pathrmdir($flpth) or return;
406
        }
407
        else {
408
            _bail_if_changed( $pth, $orig_dev, $orig_ino );
409
            unlink $flpth or return;
410
        }
411
    }
412
 
413
    chdir($starting_point) or Carp::croak("Failed to change directory to “$starting_point”: $!");
414
    _bail_if_changed( ".", $starting_dev, $starting_ino );
415
 
416
    return 1;
417
}
418
 
419
sub pathrm {
420
    my ( $path, $force, $nofail ) = @_;
421
 
422
    my ( $orig_dev, $orig_ino ) = ( lstat $path )[ 0, 1 ];
423
    return 2 if !-d _ || !defined($orig_dev) || !$orig_ino;
424
 
425
    # Manual test (I hate this function :/):
426
    #    sudo mkdir /foo && perl -MFile::Copy::Recursive=pathrm -le 'print pathrm("/foo",1)' && sudo rm -rf /foo
427
    if ( $force && File::Spec->file_name_is_absolute($path) ) {
428
        Carp::croak("pathrm() w/ force on abspath is not allowed");
429
    }
430
 
431
    my @pth = File::Spec->splitdir($path);
432
 
433
    my %fs_check;
434
    my $aggregate_path;
435
    for my $part (@pth) {
436
        $aggregate_path = defined $aggregate_path ? File::Spec->catdir( $aggregate_path, $part ) : $part;
437
        $fs_check{$aggregate_path} = [ ( lstat $aggregate_path )[ 0, 1 ] ];
438
    }
439
 
440
    while (@pth) {
441
        my $cur = File::Spec->catdir(@pth);
442
        last if !$cur;    # necessary ???
443
 
444
        if ($force) {
445
            _bail_if_changed( $cur, $fs_check{$cur}->[0], $fs_check{$cur}->[1] );
446
            if ( !pathempty($cur) ) {
447
                return unless $nofail;
448
            }
449
        }
450
        _bail_if_changed( $cur, $fs_check{$cur}->[0], $fs_check{$cur}->[1] );
451
        if ($nofail) {
452
            rmdir $cur;
453
        }
454
        else {
455
            rmdir $cur or return;
456
        }
457
        pop @pth;
458
    }
459
 
460
    return 1;
461
}
462
 
463
sub pathrmdir {
464
    my $dir = shift;
465
    if ( -e $dir ) {
466
        return if !-d $dir;
467
    }
468
    else {
469
        return 2;
470
    }
471
 
472
    my ( $orig_dev, $orig_ino ) = ( lstat $dir )[ 0, 1 ];
473
    return 2 if !defined($orig_dev) || ( $^O ne 'MSWin32' && !$orig_ino );
474
 
475
    pathempty($dir) or return;
476
    _bail_if_changed( $dir, $orig_dev, $orig_ino );
477
    rmdir $dir or return;
478
 
479
    return 1;
480
}
481
 
482
sub _bail_if_changed {
483
    my ( $path, $orig_dev, $orig_ino ) = @_;
484
 
485
    my ( $cur_dev, $cur_ino ) = ( lstat $path )[ 0, 1 ];
486
 
487
    if ( !defined $cur_dev || !defined $cur_ino ) {
488
        $cur_dev ||= "undef(path went away?)";
489
        $cur_ino ||= "undef(path went away?)";
490
    }
491
    else {
492
        $path = Cwd::abs_path($path);
493
    }
494
 
495
    if ( $orig_dev ne $cur_dev || $orig_ino ne $cur_ino ) {
496
        local $Carp::CarpLevel += 1;
497
        Carp::croak("directory $path changed: expected dev=$orig_dev ino=$orig_ino, actual dev=$cur_dev ino=$cur_ino, aborting");
498
    }
499
}
500
 
501
1;
502
 
503
__END__
504
 
505
=head1 NAME
506
 
507
File::Copy::Recursive - Perl extension for recursively copying files and directories
508
 
509
=head1 SYNOPSIS
510
 
511
  use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);
512
 
513
  fcopy($orig,$new[,$buf]) or die $!;
514
  rcopy($orig,$new[,$buf]) or die $!;
515
  dircopy($orig,$new[,$buf]) or die $!;
516
 
517
  fmove($orig,$new[,$buf]) or die $!;
518
  rmove($orig,$new[,$buf]) or die $!;
519
  dirmove($orig,$new[,$buf]) or die $!;
520
 
521
  rcopy_glob("orig/stuff-*", $trg [, $buf]) or die $!;
522
  rmove_glob("orig/stuff-*", $trg [,$buf]) or die $!;
523
 
524
=head1 DESCRIPTION
525
 
526
This module copies and moves directories recursively (or single files, well... singley) to an optional depth and attempts to preserve each file or directory's mode.
527
 
528
=head1 EXPORT
529
 
530
None by default. But you can export all the functions as in the example above and the path* functions if you wish.
531
 
532
=head2 fcopy()
533
 
534
This function uses File::Copy's copy() function to copy a file but not a directory. Any directories are recursively created if need be.
535
One difference to File::Copy::copy() is that fcopy attempts to preserve the mode (see Preserving Mode below)
536
The optional $buf in the synopsis is the same as File::Copy::copy()'s 3rd argument.
537
This function returns the same as File::Copy::copy() in scalar context and 1,0,0 in list context to accomodate rcopy()'s list context on regular files. (See below for more info)
538
 
539
=head2 dircopy()
540
 
541
This function recursively traverses the $orig directory's structure and recursively copies it to the $new directory.
542
$new is created if necessary (multiple non existent directories is ok (i.e. foo/bar/baz). The script logically and portably creates all of them if necessary).
543
It attempts to preserve the mode (see Preserving Mode below) and
544
by default it copies all the way down into the directory (see Managing Depth, below).
545
If a directory is not specified it croaks just like fcopy croaks if its not a file that is specified.
546
 
547
This function returns true or false: for true in scalar context it returns the number of files and directories copied,
548
whereas in list context it returns the number of files and directories, number of directories only, depth level traversed.
549
 
550
  my $num_of_files_and_dirs = dircopy($orig,$new);
551
  my($num_of_files_and_dirs,$num_of_dirs,$depth_traversed) = dircopy($orig,$new);
552
 
553
Normally it stops and returns if a copy fails. To continue on regardless, set $File::Copy::Recursive::SkipFlop to true.
554
 
555
    local $File::Copy::Recursive::SkipFlop = 1;
556
 
557
That way it will copy everythging it can in a directory and won't stop because of permissions, etc...
558
 
559
=head2 rcopy()
560
 
561
This function will allow you to specify a file *or* a directory. It calls fcopy() if you passed file and dircopy() if you passed a directory.
562
If you call rcopy() (or fcopy() for that matter) on a file in list context, the values will be 1,0,0 since no directories and no depth are used.
563
This is important because if it's a directory in list context and there is only the initial directory the return value is 1,1,1.
564
 
565
=head2 rcopy_glob()
566
 
567
This function lets you specify a pattern suitable for perl's File::Glob::bsd_glob() as the first argument. Subsequently each path returned by perl's File::Glob::bsd_glob() gets rcopy()ied.
568
 
569
It returns and array whose items are array refs that contain the return value of each rcopy() call.
570
 
571
It forces behavior as if $File::Copy::Recursive::CPRFComp is true.
572
 
573
=head2 fmove()
574
 
575
Copies the file then removes the original. You can manage the path the original file is in according to $RemvBase.
576
 
577
=head2 dirmove()
578
 
579
Uses dircopy() to copy the directory then removes the original. You can manage the path the original directory is in according to $RemvBase.
580
 
581
=head2 rmove()
582
 
583
Like rcopy() but calls fmove() or dirmove() instead.
584
 
585
=head2 rmove_glob()
586
 
587
Like rcopy_glob() but calls rmove() instead of rcopy()
588
 
589
=head3 $RemvBase
590
 
591
Default is false. When set to true the *move() functions will not only attempt to remove the original file or directory but will remove the given path it is in.
592
 
593
So if you:
594
 
595
   rmove('foo/bar/baz', '/etc/');
596
   # "baz" is removed from foo/bar after it is successfully copied to /etc/
597
 
598
   local $File::Copy::Recursive::Remvbase = 1;
599
   rmove('foo/bar/baz','/etc/');
600
   # if baz is successfully copied to /etc/ :
601
   # first "baz" is removed from foo/bar
602
   # then "foo/bar is removed via pathrm()
603
 
604
=head4 $ForcePth
605
 
606
Default is false. When set to true it calls pathempty() before any directories are removed to empty the directory so it can be rmdir()'ed when $RemvBase is in effect.
607
 
608
=head2 Creating and Removing Paths
609
 
610
=head3 $NoFtlPth
611
 
612
Default is false. If set to true  rmdir(), mkdir(), and pathempty() calls in pathrm() and pathmk() do not return() on failure.
613
 
614
If its set to true they just silently go about their business regardless. This isn't a good idea but it's there if you want it.
615
 
616
=head3 $DirPerms
617
 
618
Mode to pass to any mkdir() calls. Defaults to 0777 as per umask()'s POD. Explicitly having this allows older perls to be able to use FCR and might add a bit of flexibility for you.
619
 
620
Any value you set it to should be suitable for oct().
621
 
622
=head3 Path functions
623
 
624
These functions exist solely because they were necessary for the move and copy functions to have the features they do and not because they are of themselves the purpose of this module. That being said, here is how they work so you can understand how the copy and move functions work and use them by themselves if you wish.
625
 
626
=head4 pathrm()
627
 
628
Removes a given path recursively. It removes the *entire* path so be careful!!!
629
 
630
Returns 2 if the given path is not a directory.
631
 
632
  File::Copy::Recursive::pathrm('foo/bar/baz') or die $!;
633
  # foo no longer exists
634
 
635
Same as:
636
 
637
  rmdir 'foo/bar/baz' or die $!;
638
  rmdir 'foo/bar' or die $!;
639
  rmdir 'foo' or die $!;
640
 
641
An optional second argument makes it call pathempty() before any rmdir()'s when set to true.
642
 
643
  File::Copy::Recursive::pathrm('foo/bar/baz', 1) or die $!;
644
  # foo no longer exists
645
 
646
Same as:PFSCheck
647
 
648
  File::Copy::Recursive::pathempty('foo/bar/baz') or die $!;
649
  rmdir 'foo/bar/baz' or die $!;
650
  File::Copy::Recursive::pathempty('foo/bar/') or die $!;
651
  rmdir 'foo/bar' or die $!;
652
  File::Copy::Recursive::pathempty('foo/') or die $!;
653
  rmdir 'foo' or die $!;
654
 
655
An optional third argument acts like $File::Copy::Recursive::NoFtlPth, again probably not a good idea.
656
 
657
=head4 pathempty()
658
 
659
Recursively removes the given directory's contents so it is empty. Returns 2 if the given argument is not a directory, 1 on successfully emptying the directory.
660
 
661
   File::Copy::Recursive::pathempty($pth) or die $!;
662
   # $pth is now an empty directory
663
 
664
=head4 pathmk()
665
 
666
Creates a given path recursively. Creates foo/bar/baz even if foo does not exist.
667
 
668
   File::Copy::Recursive::pathmk('foo/bar/baz') or die $!;
669
 
670
An optional second argument if true acts just like $File::Copy::Recursive::NoFtlPth, which means you'd never get your die() if something went wrong. Again, probably a *bad* idea.
671
 
672
=head4 pathrmdir()
673
 
674
Same as rmdir() but it calls pathempty() first to recursively empty it first since rmdir can not remove a directory with contents.
675
Just removes the top directory the path given instead of the entire path like pathrm(). Returns 2 if the given argument does not exist (i.e. it's already gone). Returns false if it exists but is not a directory.
676
 
677
=head2 Preserving Mode
678
 
679
By default a quiet attempt is made to change the new file or directory to the mode of the old one.
680
To turn this behavior off set
681
  $File::Copy::Recursive::KeepMode
682
to false;
683
 
684
=head2 Managing Depth
685
 
686
You can set the maximum depth a directory structure is recursed by setting:
687
  $File::Copy::Recursive::MaxDepth
688
to a whole number greater than 0.
689
 
690
=head2 SymLinks
691
 
692
If your system supports symlinks then symlinks will be copied as symlinks instead of as the target file.
693
Perl's symlink() is used instead of File::Copy's copy().
694
You can customize this behavior by setting $File::Copy::Recursive::CopyLink to a true or false value.
695
It is already set to true or false depending on your system's support of symlinks so you can check it with an if statement to see how it will behave:
696
 
697
    if($File::Copy::Recursive::CopyLink) {
698
        print "Symlinks will be preserved\n";
699
    } else {
700
        print "Symlinks will not be preserved because your system does not support it\n";
701
    }
702
 
703
If symlinks are being copied you can set $File::Copy::Recursive::BdTrgWrn to true to make it carp when it copies a link whose target does not exist. It's false by default.
704
 
705
    local $File::Copy::Recursive::BdTrgWrn  = 1;
706
 
707
=head2 Removing existing target file or directory before copying.
708
 
709
This can be done by setting $File::Copy::Recursive::RMTrgFil or $File::Copy::Recursive::RMTrgDir for file or directory behavior respectively.
710
 
711
 
712
 
713
1 = carp() $! if removal fails
714
 
715
2 = return if removal fails
716
 
717
    local $File::Copy::Recursive::RMTrgFil = 1;
718
    fcopy($orig, $target) or die $!;
719
    # if it fails it does warn() and keeps going
720
 
721
    local $File::Copy::Recursive::RMTrgDir = 2;
722
    dircopy($orig, $target) or die $!;
723
    # if it fails it does your "or die"
724
 
725
This should be unnecessary most of the time but it's there if you need it :)
726
 
727
=head2 Turning off stat() check
728
 
729
By default the files or directories are checked to see if they are the same (i.e. linked, or two paths (absolute/relative or different relative paths) to the same file) by comparing the file's stat() info.
730
It's a very efficient check that croaks if they are and shouldn't be turned off but if you must for some weird reason just set $File::Copy::Recursive::PFSCheck to a false value. ("PFS" stands for "Physical File System")
731
 
732
=head2 Emulating cp -rf dir1/ dir2/
733
 
734
By default dircopy($dir1,$dir2) will put $dir1's contents right into $dir2 whether $dir2 exists or not.
735
 
736
You can make dircopy() emulate cp -rf by setting $File::Copy::Recursive::CPRFComp to true.
737
 
738
NOTE: This only emulates -f in the sense that it does not prompt. It does not remove the target file or directory if it exists.
739
If you need to do that then use the variables $RMTrgFil and $RMTrgDir described in "Removing existing target file or directory before copying" above.
740
 
741
That means that if $dir2 exists it puts the contents into $dir2/$dir1 instead of $dir2 just like cp -rf.
742
If $dir2 does not exist then the contents go into $dir2 like normal (also like cp -rf).
743
 
744
So assuming 'foo/file':
745
 
746
    dircopy('foo', 'bar') or die $!;
747
    # if bar does not exist the result is bar/file
748
    # if bar does exist the result is bar/file
749
 
750
    $File::Copy::Recursive::CPRFComp = 1;
751
    dircopy('foo', 'bar') or die $!;
752
    # if bar does not exist the result is bar/file
753
    # if bar does exist the result is bar/foo/file
754
 
755
You can also specify a star for cp -rf glob type behavior:
756
 
757
    dircopy('foo/*', 'bar') or die $!;
758
    # if bar does not exist the result is bar/file
759
    # if bar does exist the result is bar/file
760
 
761
    $File::Copy::Recursive::CPRFComp = 1;
762
    dircopy('foo/*', 'bar') or die $!;
763
    # if bar does not exist the result is bar/file
764
    # if bar does exist the result is bar/file
765
 
766
NOTE: The '*' is only like cp -rf foo/* and *DOES NOT EXPAND PARTIAL DIRECTORY NAMES LIKE YOUR SHELL DOES* (i.e. not like cp -rf fo* to copy foo/*).
767
 
768
=head2 Allowing Copy Loops
769
 
770
If you want to allow:
771
 
772
  cp -rf . foo/
773
 
774
type behavior set $File::Copy::Recursive::CopyLoop to true.
775
 
776
This is false by default so that a check is done to see if the source directory will contain the target directory and croaks to avoid this problem.
777
 
778
If you ever find a situation where $CopyLoop = 1 is desirable let me know. (i.e. it's a bad bad idea but is there if you want it)
779
 
780
(Note: On Windows this was necessary since it uses stat() to determine sameness and stat() is essentially useless for this on Windows.
781
The test is now simply skipped on Windows but I'd rather have an actual reliable check if anyone in Microsoft land would care to share)
782
 
783
=head1 SEE ALSO
784
 
785
L<File::Copy> L<File::Spec>
786
 
787
=head1 TO DO
788
 
789
I am currently working on and reviewing some other modules to use in the new interface so we can lose the horrid globals as well as some other undesirable traits and also more easily make available some long standing requests.
790
 
791
Tests will be easier to do with the new interface and hence the testing focus will shift to the new interface and aim to be comprehensive.
792
 
793
The old interface will work, it just won't be brought in until it is used, so it will add no overhead for users of the new interface.
794
 
795
I'll add this after the latest version has been out for a while with no new features or issues found :)
796
 
797
=head1 AUTHOR
798
 
799
Daniel Muey, L<http://drmuey.com/cpan_contact.pl>
800
 
801
=head1 COPYRIGHT AND LICENSE
802
 
803
Copyright 2004 by Daniel Muey
804
 
805
This library is free software; you can redistribute it and/or modify
806
it under the same terms as Perl itself.
807
 
808
=cut

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.