alienhuman has asked for the wisdom of the Perl Monks concerning the following question:

Hey Monks,

I have a piece of code I have to maintain (not the author) that handles automatic moving of files from one host to another. It uses 2 different methods, one of which is FTP.

A section of code from the main subroutine follows. The line I'm concerned with has an arrow next to it.

if( -d $filename ) { if( $promotion_method == $METHOD_FTP ) { ------> push( @global_files, recurse_dir( $filename ) ); } elsif( $promotion_method == $METHOD_RDIST ) { $filename =~ s/\/$//; push( @global_files, $filename ); } else { logmsg( 'docopy', 2, "PANIC!!!! No valid promotion met +hod defined!" ); exit( 1 ); } } else { push( @global_files, $filename ); }

The value of $filename is: /web/bazaar/html-docs/avantgo/, which I've verified using perl -d.

The recurse_dir subroutine is hanging and core dumping. It follows. You can see a recent change that I made to the code (the old code is commented out). I did this because the subroutine was returning a list of files with an extra slash after the value of $filename (e.g. /web/bazaar/html-docs/avantgo//index.html). My question is, have I inadvertently created some kind of endless loop here?

# Recursively process directories sub recurse_dir { my $filename = shift; my @results; # removed the "/" from the following; $filename has a trailing + "/" (if it's a dir) # so this was returning "//" -- Chris 12.28.2001 #my @list = glob( "$filename/*" ); my @list = glob( "$filename*" ); foreach my $file (@list) { if ( -d $file ) { push @results, recurse_dir( $file ); } else { push @results, $file; } } return @results; }

When I run this in the debugger (perl -d) I get messages such as the following, which make me curious, because I don't know much about the internals of glob. And because after a few iterations of recurse_dir, it core dumps.

main::go(docopy.pl:61): push( @global_files, rec +urse_dir( $filename ) ); DB<4> n File::Glob::csh_glob(/usr/local/lib/perl5/5.6.1/sun4-solaris/File/Glob +.pm:175): 175: if (wantarray) { 99 levels deep in subroutine calls!

Any comments or suggestions are appreciated (except for "use -w"... I would've if I'd written this, but if I use "-w" now everything breaks, and I need to get this running ASAP. Afterwards I'm going to re-write it.)

Thanks,

Chris

p.s. And if anyone knows how to get info from a core dump, that'd be helpful too!

Replies are listed 'Best First'.
Re: recursive prob with glob?
by chromatic (Archbishop) on Dec 29, 2001 at 00:15 UTC
    If $filename does not have a trailing slash, this could very well be an endless loop. That fits the behavior you're seeing. My guess is that you're not passing in a trailing slash on the initial call. At the very least, use File::Spec's catdir() function to concatenate path components. While most Unix filesystems, in my experience, don't care about duplicate slashes, File::Spec will clean them for you.

    At best, skip the recursion yourself and use File::Find. You could also do this with readdir instead of glob, as you're asking for everything. Beware '.' and '..' though.

      Hmm. The initial call does have a trailing slash--I've been able to verify the value of $filename using perl -d... however, I'm going to take a look at File::Find and/or readdir. Thx for the help.

      Chris

        Or the other way, you have '//' and the glob is starting from root?  Notice that the next alternative does $filename =~ s/\/$//;.

          p