my %lookfor: shared; @lookfor{ @ARGV } = ();
####
$line =~ $_ and $lookfor->{ $_ } = $line for keys %{ $lookfor };
##
##
last if keys %$lookfor == grep defined, values %$lookfor;
##
##
my @dones : shared = ( 0 ) x @cmds;
##
##
\$dones[ $_ ],
##
##
$$doneRef = 1;
##
##
sleep 1 while grep( $_, @dones ) < @cmds;
##
##
## Set the quitNow if the value indicates this
$$quitNow = ( $lookfor->{ $_ } eq '1' );
##
##
#! perl -slw
use strict;
use threads qw[ async ];
use threads::shared;
our $DRIVES ||= 'C';
die "Nothing to search for" unless $ARGV[ 0 ];
sub runAndCheck {
my( $cmd, $doneRef, $quitNow, $lookfor ) = @_;
## Execute the command and retain the pid
my $pid = open CMD, "$cmd |" or die "$cmd : $!";
## While we haven't been told to quit
## And ther eis still output from teh commands
while( not $$quitNow and my $line = ) {
chomp $line;
## If the number of keys == the number of true values
## We've found (1 of) everything, so we go home.
last if keys %$lookfor == grep $_, values %$lookfor;
## For each of the search terms
for ( keys %{ $lookfor } ) {
## Skip it if someone already found it
next if $lookfor->{ $_ } and $lookfor->{ $_ } ne '1';
## If this line contains it
if( $line =~ $_ ) {
## Set the quitNow if the value indicates this
$$quitNow = ( $lookfor->{ $_ } eq '1' );
## And record the context.
$lookfor->{ $_ } = $line;
}
}
}
close CMD; ##Shut the pipe
kill 1, $pid; ## Kill the child process
$$doneRef = 1; ## Flag we're done
}
my @cmds = map{ "attrib /s $_:\\* " } split '', $DRIVES;
my @dones : shared = ( 0 ) x @cmds; ## Used to indicate when the threads are done
my %lookfor: shared; ## Used to pas teh search terms in. and the results out.
my $quitNow: shared = 0; ## Used to signal early termination
for my $searchTerm ( @ARGV ) {
## look for and remove the trailing 'stopper' flag
## $1 will be defined if it is found.
$searchTerm =~ s[(!)?$][];
## Set the flag true if it was and false otherwise
$lookfor{ $searchTerm } = defined $1;
}
##start the threads
async{
runAndCheck(
$cmds[ $_ ],
\$dones[ $_ ],
\$quitNow,
\%lookfor
);
}->detach for 0 .. $#cmds;
## Wait until all the reads signal they are done
## Ie. count the number of true values in @done
## and continue waiting while this is less than the number of @cmds
sleep 1 while grep( $_, @dones ) < @cmds;
## If we found anything, report it
if( grep defined, %lookfor ) {
printf "%20s : %s\n", $_,
( $lookfor{ $_ } and $lookfor{ $_ } ne '1' )
? " was found at '$lookfor{ $_ }'"
: " was not found."
for keys %lookfor;
}
else {
print "None of @ARGV were found";
}
__END__
## No 'stopper flag', everything is found
P:\test>412014 -DRIVES=CDPR junk\.htm$ 412014 copyrght cmd\.exe CMD\.EXE$
CMD\.EXE$ : was found at 'A C:\WINDOWS\SYSTEM32\CMD.EXE'
cmd\.exe : was found at 'A C:\Program Files\Classic PhoneTools\inssuitecmd.exe'
412014 : was found at 'A P:\test\412014.pl'
junk\.htm$ : was found at 'A P:\test\junk.htm'
copyrght : was found at ' R R:\cookbook\copyrght.htm'
## A 'stopper flag' set on an item (that also hapens to be early in the search path)
## and the other thread quit before having found anything
P:\test>412014 -DRIVES=CDPR junk\.htm$ 412014 copyrght! cmd\.exe CMD\.EXE$
CMD\.EXE$ : was not found.
cmd\.exe : was not found.
412014 : was not found.
junk\.htm$ : was not found.
copyrght : was found at ' R R:\cookbook\copyrght.htm'