<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package File::Which;

use 5.004;
use strict;
use Exporter   ();
use File::Spec ();

use vars qw{$VERSION @ISA @EXPORT @EXPORT_OK};
BEGIN {
	$VERSION   = '1.09';
	@ISA       = 'Exporter';
	@EXPORT    = 'which';
	@EXPORT_OK = 'where';
}

use constant IS_VMS =&gt; ($^O eq 'VMS');
use constant IS_MAC =&gt; ($^O eq 'MacOS');
use constant IS_DOS =&gt; ($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'os2');

# For Win32 systems, stores the extensions used for
# executable files
# For others, the empty string is used
# because 'perl' . '' eq 'perl' =&gt; easier
my @PATHEXT = ('');
if ( IS_DOS ) {
	# WinNT. PATHEXT might be set on Cygwin, but not used.
	if ( $ENV{PATHEXT} ) {
		push @PATHEXT, split ';', $ENV{PATHEXT};
	} else {
		# Win9X or other: doesn't have PATHEXT, so needs hardcoded.
		push @PATHEXT, qw{.com .exe .bat};
	}
} elsif ( IS_VMS ) {
	push @PATHEXT, qw{.exe .com};
}

sub which {
	my ($exec) = @_;

	return undef unless $exec;

	my $all = wantarray;
	my @results = ();

	# check for aliases first
	if ( IS_VMS ) {
		my $symbol = `SHOW SYMBOL $exec`;
		chomp($symbol);
		unless ( $? ) {
			return $symbol unless $all;
			push @results, $symbol;
		}
	}
	if ( IS_MAC ) {
		my @aliases = split /\,/, $ENV{Aliases};
		foreach my $alias ( @aliases ) {
			# This has not been tested!!
			# PPT which says MPW-Perl cannot resolve `Alias $alias`,
			# let's just hope it's fixed
			if ( lc($alias) eq lc($exec) ) {
				chomp(my $file = `Alias $alias`);
				last unless $file;  # if it failed, just go on the normal way
				return $file unless $all;
				push @results, $file;
				# we can stop this loop as if it finds more aliases matching,
				# it'll just be the same result anyway
				last;
			}
		}
	}

	my @path = File::Spec-&gt;path;
	if ( IS_DOS or IS_VMS or IS_MAC ) {
		unshift @path, File::Spec-&gt;curdir;
	}

	foreach my $base ( map { File::Spec-&gt;catfile($_, $exec) } @path ) {
		for my $ext ( @PATHEXT ) {
			my $file = $base.$ext;

			# We don't want dirs (as they are -x)
			next if -d $file;

			if (
				# Executable, normal case
				-x _
				or (
					# MacOS doesn't mark as executable so we check -e
					IS_MAC
					||
					(
						IS_DOS
						and
						grep {
							$file =~ /$_\z/i
						} @PATHEXT[1..$#PATHEXT]
					)
					# DOSish systems don't pass -x on
					# non-exe/bat/com files. so we check -e.
					# However, we don't want to pass -e on files
					# that aren't in PATHEXT, like README.
					and -e _
				)
			) {
				return $file unless $all;
				push @results, $file;
			}
		}
	}

	if ( $all ) {
		return @results;
	} else {
		return undef;
	}
}

sub where {
	# force wantarray
	my @res = which($_[0]);
	return @res;
}

1;

__END__

=pod

=head1 NAME

File::Which - Portable implementation of the `which' utility

=head1 SYNOPSIS

  use File::Which;                  # exports which()
  use File::Which qw(which where);  # exports which() and where()
  
  my $exe_path = which('perldoc');
  
  my @paths = where('perl');
  - Or -
  my @paths = which('perl'); # an array forces search for all of them

=head1 DESCRIPTION

C&lt;File::Which&gt; was created to be able to get the paths to executable programs
on systems under which the `which' program wasn't implemented in the shell.

C&lt;File::Which&gt; searches the directories of the user's C&lt;PATH&gt; (as returned by
C&lt;File::Spec-E&lt;gt&gt;path()&gt;), looking for executable files having the name
specified as a parameter to C&lt;which()&gt;. Under Win32 systems, which do not have a
notion of directly executable files, but uses special extensions such as C&lt;.exe&gt;
and C&lt;.bat&gt; to identify them, C&lt;File::Which&gt; takes extra steps to assure that
you will find the correct file (so for example, you might be searching for
C&lt;perl&gt;, it'll try F&lt;perl.exe&gt;, F&lt;perl.bat&gt;, etc.)

=head1 Steps Used on Win32, DOS, OS2 and VMS

=head2 Windows NT

Windows NT has a special environment variable called C&lt;PATHEXT&gt;, which is used
by the shell to look for executable files. Usually, it will contain a list in
the form C&lt;.EXE;.BAT;.COM;.JS;.VBS&gt; etc. If C&lt;File::Which&gt; finds such an
environment variable, it parses the list and uses it as the different
extensions.

=head2 Windows 9x and other ancient Win/DOS/OS2

This set of operating systems don't have the C&lt;PATHEXT&gt; variable, and usually
you will find executable files there with the extensions C&lt;.exe&gt;, C&lt;.bat&gt; and
(less likely) C&lt;.com&gt;. C&lt;File::Which&gt; uses this hardcoded list if it's running
under Win32 but does not find a C&lt;PATHEXT&gt; variable.

=head2 VMS

Same case as Windows 9x: uses C&lt;.exe&gt; and C&lt;.com&gt; (in that order).

=head1 Functions

=head2 which($short_exe_name)

Exported by default.

C&lt;$short_exe_name&gt; is the name used in the shell to call the program (for
example, C&lt;perl&gt;).

If it finds an executable with the name you specified, C&lt;which()&gt; will return
the absolute path leading to this executable (for example, F&lt;/usr/bin/perl&gt; or
F&lt;C:\Perl\Bin\perl.exe&gt;).

If it does I&lt;not&gt; find the executable, it returns C&lt;undef&gt;.

If C&lt;which()&gt; is called in list context, it will return I&lt;all&gt; the
matches.

=head2 where($short_exe_name)

Not exported by default.

Same as C&lt;which($short_exe_name)&gt; in array context. Same as the
C&lt;`where'&gt; utility, will return an array containing all the path names
matching C&lt;$short_exe_name&gt;.

=head1 BUGS AND CAVEATS

Not tested on VMS or MacOS, although there is platform specific code
for those. Anyone who haves a second would be very kind to send me a
report of how it went.

File::Spec adds the current directory to the front of PATH if on
Win32, VMS or MacOS. I have no knowledge of those so don't know if the
current directory is searced first or not. Could someone please tell
me?

=head1 SUPPORT

Bugs should be reported via the CPAN bug tracker at

L&lt;http://rt.cpan.org/NoAuth/ReportBug.html?Queue=File-Which&gt;

For other issues, contact the maintainer.

=head1 AUTHOR

Adam Kennedy E&lt;lt&gt;adamk@cpan.orgE&lt;gt&gt;

Per Einar Ellefsen E&lt;lt&gt;pereinar@cpan.orgE&lt;gt&gt;

Originated in F&lt;modperl-2.0/lib/Apache/Build.pm&gt;. Changed for use in DocSet
(for the mod_perl site) and Win32-awareness by me, with slight modifications
by Stas Bekman, then extracted to create C&lt;File::Which&gt;.

Version 0.04 had some significant platform-related changes, taken from
the Perl Power Tools C&lt;`which'&gt; implementation by Abigail with
enhancements from Peter Prymmer. See
L&lt;http://www.perl.com/language/ppt/src/which/index.html&gt; for more
information.

=head1 COPYRIGHT

Copyright 2002 Per Einar Ellefsen.

Some parts copyright 2009 Adam Kennedy.

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 SEE ALSO

L&lt;File::Spec&gt;, L&lt;which(1)&gt;, Perl Power Tools:
L&lt;http://www.perl.com/language/ppt/index.html&gt;.

=cut
</pre></body></html>