You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Charlie Katz <ck...@cfa.harvard.edu> on 2012/03/26 20:43:55 UTC

difference between PerlSetEnv and $ENV{}= ?

Hi,

My web app uses the PGPLOT module to access PGPLOT, which is a scientific
plotting library commonly used in my field.  It is a Fortran library, with
a C wrapper around it, which is then wrapped in Perl.  This works fine in
my test scripts, producing the desired graphics.

The library requires that the environment variable PGPLOT_DIR be set so it
can find some required files.  Running from the command line, I just set
this in the shell, and PGPLOT works fine.  Running in Apache, I see
different behavior:

When I set this in httpd.conf:
  PerlSetEnv PGPLOT_DIR /my/pgplot/directory
my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT
library can't, and my code fails.

When I set this in httpd.conf:
  <Perl>
  $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
  </Perl>
my Perl programs can't see the value in $ENV, but the PGPLOT library can,
and my code works.


Can someone help me understand what the difference is between these two
cases?

Is the situation muddled because the PGPLOT library is a
Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment
passing is supposed to work.

Regards,
Charlie

RE: difference between PerlSetEnv and $ENV{}= ?

Posted by "Szekeres, Edward" <Ed...@PERKINELMER.COM>.
When I have had these issues in the past it is because Apache tends to limit things to within "server accessible" locations, which for security is not the whole hard disk.  The strategies I have taken to solve these is create explicit aliases in the httpd conf file, or sometimes easier, use symlinks to map out of the htdocs folder to locations elsewhere.

From: ckatzcfa@gmail.com [mailto:ckatzcfa@gmail.com] On Behalf Of Charlie Katz
Sent: Monday, March 26, 2012 2:44 PM
To: modperl@perl.apache.org
Subject: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ?

Hi,

My web app uses the PGPLOT module to access PGPLOT, which is a scientific plotting library commonly used in my field.  It is a Fortran library, with a C wrapper around it, which is then wrapped in Perl.  This works fine in my test scripts, producing the desired graphics.

The library requires that the environment variable PGPLOT_DIR be set so it can find some required files.  Running from the command line, I just set this in the shell, and PGPLOT works fine.  Running in Apache, I see different behavior:

When I set this in httpd.conf:
  PerlSetEnv PGPLOT_DIR /my/pgplot/directory
my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT library can't, and my code fails.

When I set this in httpd.conf:
  <Perl>
  $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
  </Perl>
my Perl programs can't see the value in $ENV, but the PGPLOT library can, and my code works.


Can someone help me understand what the difference is between these two cases?

Is the situation muddled because the PGPLOT library is a Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment passing is supposed to work.

Regards,
Charlie


Re: difference between PerlSetEnv and $ENV{}= ?

Posted by Charlie Katz <ck...@cfa.harvard.edu>.
Thanks for the detailed explanation.  I guess the explanation for the
behavior I see is that the C library called through Perl only has access to
the process global %ENV, and not to the particular $r->subprocess_env data
for the request through which it was called.

On Tue, Mar 27, 2012 at 1:53 PM, Torsten Förtsch
<to...@gmx.net>wrote:

> On Tuesday, 27 March 2012 12:48:01 Charlie Katz wrote:
> > Still, can someone explain why
> >
> >    PerlSetEnv  ENV_VAR /my/value
> >
> > has different effects than
> >
> >    <Perl>
> >    $ENV{ENV_VAR} = '/my/value';
> >    </Perl>
> >
> > ?
>
> The source of the problem is that apache 2 is in general multithreaded.
> Thus,
> one request may set $ENV{var}=1 while the other may $ENV{var}=2 at the same
> time. The environment is a process global variable.
>
> To deal with the problem apache invented $r->subprocess_env, a table
> similar
> to the process environment but request specific. Then if there is a need to
> spawn off a new process and it is done via the apache API that table is
> copied
> to the process environment in the child process. For mod_cgi that solves
> the
> problem.
>
> Perl itself adds another layer to the problem because at least some
> versions
> do not serialize access to the environment. So in principle it may even
> cause
> segfaults if 2 threads are trying to modify %ENV at the same time.
>
> When modperl was ported to apache 2 it was decided to map %ENV to
> $r->subprocess_env to prevent trouble.
>
> So, with the current implementation, if there is a current request %ENV
> maps
> to its subprocess_env table. Otherwise Perl's original functions are called
> and thus modify the process global environment, see modperl_env.c
>
> If you modify %ENV in a <Perl> block there is obviously no request since
> the
> code is executed at server startup. PerlSetEnv on the other hand is
> executed
> as soon as possible in the request cycle. At that time there is a current
> request and hence $r->subprocess_env is modified.
>
> There is another way to modify the environment, SetEnv. The difference
> between
> PerlSetEnv and SetEnv is the point within the request cycle when it is
> executed. As said before PerlSetEnv is done first thing. Apache's SetEnv is
> there to set environment variables for CGI scripts and other normal
> handlers.
> For those it is sufficient to populate subprocess_env just before the
> response
> handler is called. So, SetEnv lives in the fixup phase.
>
> Since I am not the author of the code I don't know for sure all of the
> above.
> But I think over time I have got quite a bit of understanding of the
> problem
> from reading the code. Of course, one could ask what happens in a
> multithreaded MPM when 2 PerlProcessConnectionHandlers simultaneously try
> to
> modify %ENV. I don't know. Maybe it segfaults since there is no $r in this
> situation.
>
> Would be good if someone could at least setup a test scenario for this
> case.
>
> Torsten Förtsch
>
> --
> Need professional modperl support? Hire me! (http://foertsch.name)
>
> Like fantasy? http://kabatinte.net
>
>
>

Re: difference between PerlSetEnv and $ENV{}= ?

Posted by Torsten Förtsch <to...@gmx.net>.
On Tuesday, 27 March 2012 12:48:01 Charlie Katz wrote:
> Still, can someone explain why
> 
>    PerlSetEnv  ENV_VAR /my/value
> 
> has different effects than
> 
>    <Perl>
>    $ENV{ENV_VAR} = '/my/value';
>    </Perl>
> 
> ?

The source of the problem is that apache 2 is in general multithreaded. Thus, 
one request may set $ENV{var}=1 while the other may $ENV{var}=2 at the same 
time. The environment is a process global variable.

To deal with the problem apache invented $r->subprocess_env, a table similar 
to the process environment but request specific. Then if there is a need to 
spawn off a new process and it is done via the apache API that table is copied 
to the process environment in the child process. For mod_cgi that solves the 
problem.

Perl itself adds another layer to the problem because at least some versions 
do not serialize access to the environment. So in principle it may even cause 
segfaults if 2 threads are trying to modify %ENV at the same time.

When modperl was ported to apache 2 it was decided to map %ENV to
$r->subprocess_env to prevent trouble.

So, with the current implementation, if there is a current request %ENV maps 
to its subprocess_env table. Otherwise Perl's original functions are called 
and thus modify the process global environment, see modperl_env.c

If you modify %ENV in a <Perl> block there is obviously no request since the 
code is executed at server startup. PerlSetEnv on the other hand is executed 
as soon as possible in the request cycle. At that time there is a current 
request and hence $r->subprocess_env is modified.

There is another way to modify the environment, SetEnv. The difference between 
PerlSetEnv and SetEnv is the point within the request cycle when it is 
executed. As said before PerlSetEnv is done first thing. Apache's SetEnv is 
there to set environment variables for CGI scripts and other normal handlers. 
For those it is sufficient to populate subprocess_env just before the response 
handler is called. So, SetEnv lives in the fixup phase.

Since I am not the author of the code I don't know for sure all of the above. 
But I think over time I have got quite a bit of understanding of the problem 
from reading the code. Of course, one could ask what happens in a 
multithreaded MPM when 2 PerlProcessConnectionHandlers simultaneously try to 
modify %ENV. I don't know. Maybe it segfaults since there is no $r in this 
situation.

Would be good if someone could at least setup a test scenario for this case.

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net


Re: difference between PerlSetEnv and $ENV{}= ?

Posted by Charlie Katz <ck...@cfa.harvard.edu>.
Okay, I figured it was something about the library being in a different
language.

Still, can someone explain why

   PerlSetEnv  ENV_VAR /my/value

has different effects than

   <Perl>
   $ENV{ENV_VAR} = '/my/value';
   </Perl>

?



On Mon, Mar 26, 2012 at 3:30 PM, Lloyd Richardson
<ll...@protectchildren.ca>wrote:

> Do the PerlSetEnv as you are, and use this module to ensure it is visible
> from your pgplot lib env.****
>
> ** **
>
> http://search.cpan.org/dist/Env-C/C.pm****
>
> ** **
>
> ** **
>
> *From:* ckatzcfa@gmail.com [mailto:ckatzcfa@gmail.com] *On Behalf Of *Charlie
> Katz
> *Sent:* March-26-12 2:26 PM
> *To:* randolf@modperl.pl
> *Cc:* modperl@perl.apache.org
> *Subject:* Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ?***
> *
>
> ** **
>
> I have also tried using SetEnv from mod_env, and neither the Perl nor the
> PGPLOT library can see the environment variable set that way.****
>
> On Mon, Mar 26, 2012 at 2:54 PM, Randolf Richardson <ra...@modperl.pl>
> wrote:****
>
> > Hi,
> >
> > My web app uses the PGPLOT module to access PGPLOT, which is a scientific
> > plotting library commonly used in my field.  It is a Fortran library,
> with
> > a C wrapper around it, which is then wrapped in Perl.  This works fine in
> > my test scripts, producing the desired graphics.
> >
> > The library requires that the environment variable PGPLOT_DIR be set so
> it
> > can find some required files.  Running from the command line, I just set
> > this in the shell, and PGPLOT works fine.  Running in Apache, I see
> > different behavior:
> >
> > When I set this in httpd.conf:
> >   PerlSetEnv PGPLOT_DIR /my/pgplot/directory
> > my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT
> > library can't, and my code fails.
> >
> > When I set this in httpd.conf:
> >   <Perl>
> >   $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
> >   </Perl>
> > my Perl programs can't see the value in $ENV, but the PGPLOT library can,
> > and my code works.
> >
> >
> > Can someone help me understand what the difference is between these two
> > cases?
> >
> > Is the situation muddled because the PGPLOT library is a
> > Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment
> > passing is supposed to work.****
>
>        Try this module:
>
>                http://httpd.apache.org/docs/current/mod/mod_env.html
>
> Randolf Richardson - randolf@inter-corporate.com
> Inter-Corporate Computer & Network Services, Inc.
> Beautiful British Columbia, Canada
> http://www.inter-corporate.com/
>
> ****
>
> ** **
>

RE: difference between PerlSetEnv and $ENV{}= ?

Posted by Lloyd Richardson <ll...@protectchildren.ca>.
Do the PerlSetEnv as you are, and use this module to ensure it is visible from your pgplot lib env.

http://search.cpan.org/dist/Env-C/C.pm


From: ckatzcfa@gmail.com [mailto:ckatzcfa@gmail.com] On Behalf Of Charlie Katz
Sent: March-26-12 2:26 PM
To: randolf@modperl.pl
Cc: modperl@perl.apache.org
Subject: Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ?

I have also tried using SetEnv from mod_env, and neither the Perl nor the PGPLOT library can see the environment variable set that way.
On Mon, Mar 26, 2012 at 2:54 PM, Randolf Richardson <ra...@modperl.pl>> wrote:
> Hi,
>
> My web app uses the PGPLOT module to access PGPLOT, which is a scientific
> plotting library commonly used in my field.  It is a Fortran library, with
> a C wrapper around it, which is then wrapped in Perl.  This works fine in
> my test scripts, producing the desired graphics.
>
> The library requires that the environment variable PGPLOT_DIR be set so it
> can find some required files.  Running from the command line, I just set
> this in the shell, and PGPLOT works fine.  Running in Apache, I see
> different behavior:
>
> When I set this in httpd.conf:
>   PerlSetEnv PGPLOT_DIR /my/pgplot/directory
> my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT
> library can't, and my code fails.
>
> When I set this in httpd.conf:
>   <Perl>
>   $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
>   </Perl>
> my Perl programs can't see the value in $ENV, but the PGPLOT library can,
> and my code works.
>
>
> Can someone help me understand what the difference is between these two
> cases?
>
> Is the situation muddled because the PGPLOT library is a
> Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment
> passing is supposed to work.
       Try this module:

               http://httpd.apache.org/docs/current/mod/mod_env.html

Randolf Richardson - randolf@inter-corporate.com<ma...@inter-corporate.com>
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/



Re: difference between PerlSetEnv and $ENV{}= ?

Posted by Charlie Katz <ck...@cfa.harvard.edu>.
I have also tried using SetEnv from mod_env, and neither the Perl nor the
PGPLOT library can see the environment variable set that way.

On Mon, Mar 26, 2012 at 2:54 PM, Randolf Richardson <ra...@modperl.pl>wrote:

> > Hi,
> >
> > My web app uses the PGPLOT module to access PGPLOT, which is a scientific
> > plotting library commonly used in my field.  It is a Fortran library,
> with
> > a C wrapper around it, which is then wrapped in Perl.  This works fine in
> > my test scripts, producing the desired graphics.
> >
> > The library requires that the environment variable PGPLOT_DIR be set so
> it
> > can find some required files.  Running from the command line, I just set
> > this in the shell, and PGPLOT works fine.  Running in Apache, I see
> > different behavior:
> >
> > When I set this in httpd.conf:
> >   PerlSetEnv PGPLOT_DIR /my/pgplot/directory
> > my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT
> > library can't, and my code fails.
> >
> > When I set this in httpd.conf:
> >   <Perl>
> >   $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
> >   </Perl>
> > my Perl programs can't see the value in $ENV, but the PGPLOT library can,
> > and my code works.
> >
> >
> > Can someone help me understand what the difference is between these two
> > cases?
> >
> > Is the situation muddled because the PGPLOT library is a
> > Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment
> > passing is supposed to work.
>
>         Try this module:
>
>                http://httpd.apache.org/docs/current/mod/mod_env.html
>
> Randolf Richardson - randolf@inter-corporate.com
> Inter-Corporate Computer & Network Services, Inc.
> Beautiful British Columbia, Canada
> http://www.inter-corporate.com/
>
>
>

Re: difference between PerlSetEnv and $ENV{}= ?

Posted by Randolf Richardson <ra...@modperl.pl>.
> Hi,
> 
> My web app uses the PGPLOT module to access PGPLOT, which is a scientific
> plotting library commonly used in my field.  It is a Fortran library, with
> a C wrapper around it, which is then wrapped in Perl.  This works fine in
> my test scripts, producing the desired graphics.
> 
> The library requires that the environment variable PGPLOT_DIR be set so it
> can find some required files.  Running from the command line, I just set
> this in the shell, and PGPLOT works fine.  Running in Apache, I see
> different behavior:
> 
> When I set this in httpd.conf:
>   PerlSetEnv PGPLOT_DIR /my/pgplot/directory
> my Perl programs can see the value in $ENV{PGPLOT_DIR}, but the PGPLOT
> library can't, and my code fails.
> 
> When I set this in httpd.conf:
>   <Perl>
>   $ENV{PGPLOT_DIR} = q[/my/pgplot/directory];
>   </Perl>
> my Perl programs can't see the value in $ENV, but the PGPLOT library can,
> and my code works.
> 
> 
> Can someone help me understand what the difference is between these two
> cases?
> 
> Is the situation muddled because the PGPLOT library is a
> Perl-wrapped-C-wrapped-Fortran library?  I'm not sure how the environment
> passing is supposed to work.

	Try this module:

		http://httpd.apache.org/docs/current/mod/mod_env.html

Randolf Richardson - randolf@inter-corporate.com
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/