Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: ModPerl: ModPerl

difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ?

 

 

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded


ckatz at cfa

Mar 26, 2012, 11:43 AM

Post #1 of 8 (1091 views)
Permalink
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


randolf at modperl

Mar 26, 2012, 11:54 AM

Post #2 of 8 (1039 views)
Permalink
Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

> 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 [at] inter-corporate
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/


Edward.Szekeres at PERKINELMER

Mar 26, 2012, 11:55 AM

Post #3 of 8 (1048 views)
Permalink
RE: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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 [at] gmail [mailto:ckatzcfa [at] gmail] On Behalf Of Charlie Katz
Sent: Monday, March 26, 2012 2:44 PM
To: modperl [at] perl
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


ckatz at cfa

Mar 26, 2012, 12:25 PM

Post #4 of 8 (1044 views)
Permalink
Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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 <randolf [at] modperl>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 [at] inter-corporate
> Inter-Corporate Computer & Network Services, Inc.
> Beautiful British Columbia, Canada
> http://www.inter-corporate.com/
>
>
>


lloyd at protectchildren

Mar 26, 2012, 12:30 PM

Post #5 of 8 (1040 views)
Permalink
RE: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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 [at] gmail [mailto:ckatzcfa [at] gmail] On Behalf Of Charlie Katz
Sent: March-26-12 2:26 PM
To: randolf [at] modperl
Cc: modperl [at] perl
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 <randolf [at] modperl<mailto:randolf [at] modperl>> 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 [at] inter-corporate<mailto:randolf [at] inter-corporate>
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/


ckatz at cfa

Mar 27, 2012, 9:48 AM

Post #6 of 8 (1037 views)
Permalink
Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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
<lloyd [at] protectchildren>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 [at] gmail [mailto:ckatzcfa [at] gmail] *On Behalf Of *Charlie
> Katz
> *Sent:* March-26-12 2:26 PM
> *To:* randolf [at] modperl
> *Cc:* modperl [at] perl
> *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 <randolf [at] modperl>
> 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 [at] inter-corporate
> Inter-Corporate Computer & Network Services, Inc.
> Beautiful British Columbia, Canada
> http://www.inter-corporate.com/
>
> ****
>
> ** **
>


torsten.foertsch at gmx

Mar 27, 2012, 10:53 AM

Post #7 of 8 (1041 views)
Permalink
Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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


ckatz at cfa

Mar 28, 2012, 11:39 AM

Post #8 of 8 (1039 views)
Permalink
Re: difference between PerlSetEnv and <Perl>$ENV{}=</Perl> ? [In reply to]

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
<torsten.foertsch [at] gmx>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
>
>
>

ModPerl modperl RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.