[comp.lang.perl] Almost ftw

merlyn@iwarp.intel.com (Randal Schwartz) (03/25/90)

In article <7514@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax (Larry Wall) writes:
[ his version of a file tree walker ]

Well, inspired by Larry's posting (yeah, it happens :-), and by the
ftw() manpage, here's my version (somewhat tested...):

================================================== snip snip
sub ftw {
	local($path, $fn) = @_;
	local(*CHILD);
	local($/) = "\000";
	local($_);
	$CHILD = open(CHILD,'-|');
	die "ftw: Cannot fork ($!)" unless defined $CHILD;
	unless ($CHILD) { # I am the child
		chdir $path || die "Cannot cd to $path ($!)";
		&ftw'helper($path);
		exit 0;
	}
	# I am the parent
	while ($_ = <CHILD>) {
		chop;
		do $fn($_);
	}
	close(CHILD);
}

sub ftw'helper {
	# expects to be cd'ed to $DIR
	local(*DIR); ($DIR) = @_;
	local($dev, $ino, $mode, $nlink) = stat('.');
	local($_,$name);

	opendir(DIR,'.') || die "Cannot open $DIR ($!)";
	local(@filenames) = sort readdir(DIR);
	closedir(DIR);

	if ($nlink == 2) {
		print grep(!/^\.\.?$/ && s#[^\000]+#$DIR/$&\000#, @filenames);
	} else {
		for (@filenames) {
			next if /^\.\.?$/;
			$name = "$DIR/$_";
			print $name,"\000";
			next unless -d $_ && -r _ && -x _;
			next if -l $_; # don't follow symlinks
			unless (chdir $_) {
				warn "Cannot chdir to $name ($!)";
				next;
			}
			&ftw'helper($name);
			chdir '..';
		}
	}
}

sub printit {
	print @_,"\n";
}

for (@ARGV) {
	print "== $_ == \n";
	&ftw($_,"printit");
}


================================================== snip snip

This allows a separate process to do the scrambling around the
directories, so that the pathnames are all clean by the time they hit
the function.  Yeah, I could add a "-depth" type switch, but this is
just something I whipped up in 15 minutes.  As soon as I start
actually *using* the beasty, it'll probably grow all sortsa switches.

@a=split(//,",rkeacrl hher PeJust anot");print splice(@a,@a*2/3,@a*2/3+1)while@a;
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/