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

mod_perl seems to be using the Apache installation directory as the current working director. This leads to problems when I do stuff like opendir(DIR, "."). I can't find any cure for this either, I have tried stuff such as
use lib ".";
and
use File::Basename; use Cwd; cwd(dirname($ENV{"SCRIPT_FILENAME"}));
but didn't work. AFAIK when running perl scripts as CGI the directory should be the same as the script's. I could use absolute paths, but that gets less prettier and no compatibility with other's scripts which uses relative paths.

This question really isn't much related to perl but is more of a configuration question but after some googling this is pretty much the only perl message board in existence.

Replies are listed 'Best First'.
Re: mod_perl's cwd not the same as the scripts location.
by lestrrat (Deacon) on Aug 21, 2005 at 02:44 UTC

    If you just want to do something in the script's current directory, you could use __FILE__

    use File::Basename qw(dirname); my $cwd = dirname(__FILE__);
Re: mod_perl's cwd not the same as the scripts location.
by Bob9000 (Scribe) on Aug 21, 2005 at 04:21 UTC

    This happens under Apache 2 because mod_perl expects that it might be run under a single-process multi-threaded version of Apache, where changing the working directory of the process would break other threads. The multi-threaded mode was a design change in Apache 2 to improve performance in environments (like Windows) which do not handle lots of processes well.

    The good news is that if you're on a unix-ish system, you're probably still running Apache in forking mode...and you can safely override mod_perl's default behavior to act more like the original. You'll need the ModPerl::RegistryPrefork module. (When I started using it I had to copy ModPerl/RegistryPrefork.pm into one of my @INC directories manually, but it looks like it's an official part of the distribution now.) With that installed, modify your Apache configuration to use ModPerl::RegistryPrefork in place of ModPerl::Registry, and your mod_perl scripts should run in their own directories.

      Windows. orz.
      No other way?
Re: mod_perl's cwd not the same as the scripts location.
by brian_d_foy (Abbot) on Aug 21, 2005 at 06:48 UTC

    You should never assume that the current working directory will be the same as the directory which contains the script. Indeed, most of my scripts live in a directory other than the one from which I use them. I put the scripts in my ~/bin and then let the shell figure out where they are when it traverses $PATH.

    You can look at things like FindBin to see if they'll work for you. I wouldn't try to change the current working directory in a mod_perl process: just use the right path when you want to do things like opendir(). To make things compatible and portable, you can set the base directory you want in the server configuration (or .htaccess or whatever) as an environment variable and go from there.

    It's not really a mod_perl problem, although as most people find out, mod_perl exposes a lot of things you've been getting away with.

    --
    brian d foy <brian@stonehenge.com>
Re: mod_perl's cwd not the same as the scripts location.
by sgifford (Prior) on Aug 22, 2005 at 01:19 UTC
    File::FindBin is a module designed to solve exactly this problem. It won't set the current working directory automatically, but it will tell you where the currently running script is, and you can add that to your library path or simply chdir to it. Remember that you'll need to do this in a BEGIN block before you use the modules that are in that directory.