I've been trying get this patch working. The basic idea behind the patch is :
1. Populate %ENV on occurrence of PerlPassEnv & PerlSetEnv.
2. After every <Perl>..</Perl>, PerlRequire, PerlModule &
PerlLoadModule - sync server tables - scfg->SetEnv & scfg->PassEnv -
with %ENV.
I believe it's failing because I am not checking if perl is
initialized or not before calling modperl_env_hv_populate(). But I
couldn't figure out how exactly the context switching ( use of
MP_PERL_CONTEXT_STORE_OVERRIDE ) is done to make it work. I tried to
use modperl_is_running(), but it still failed.
I have added one test in this patch, which is failing on latest mp2
cvs snapshot.
I am just able to compile this patch. But "make test" is failing.
Please Help.
Thanks,
Pratik
diff -ruN /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_cmd.c
modperl-2.0/src/modules/perl/modperl_cmd.c
--- /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_cmd.c
2004-12-22
21:38:28.000000000 -0800
+++ modperl-2.0/src/modules/perl/modperl_cmd.c 2004-12-28
09:13:13.000000000 -0800
@@ -186,6 +186,9 @@
if (!modperl_require_module(aTHX_ arg, FALSE)) {
error = SvPVX(ERRSV);
}
+ else {
+ modperl_env_sync_server(aTHX_ parms->pool, parms->server);
+ }
MP_PERL_CONTEXT_RESTORE;
return error;
@@ -219,6 +222,9 @@
if (!modperl_require_file(aTHX_ arg, FALSE)) {
error = SvPVX(ERRSV);
}
+ else {
+ modperl_env_sync_server(aTHX_ parms->pool, parms->server);
+ }
MP_PERL_CONTEXT_RESTORE;
return error;
@@ -331,6 +337,7 @@
if (!parms->path) {
/* will be propagated to environ */
apr_table_setn(scfg->SetEnv, arg1, arg2);
+ modperl_env_hv_populate(aTHX_ parms->pool, parms->server, arg1, arg2);
}
apr_table_setn(dcfg->SetEnv, arg1, arg2);
@@ -353,6 +360,7 @@
if (val) {
apr_table_setn(scfg->PassEnv, arg, apr_pstrdup(parms->pool, val));
+ modperl_env_hv_populate(aTHX_ parms->pool, parms->server, arg, val);
MP_TRACE_d(MP_FUNC, "arg = %s, val = %s\n", arg, val);
}
else {
@@ -541,6 +549,7 @@
save_scalar(gv); /* local $0 */
sv_setpv_mg(GvSV(gv), directive->filename);
eval_pv(arg, FALSE);
+ modperl_env_sync_server(aTHX_ p, s);
FREETMPS;LEAVE;
}
@@ -636,6 +645,7 @@
if ((errmsg = modperl_cmd_modules(parms, mconfig, arg))) {
return errmsg;
}
+ modperl_env_sync_server(aTHX_ parms->pool, parms->server);
return NULL;
}
diff -ruN /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_env.c
modperl-2.0/src/modules/perl/modperl_env.c
--- /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_env.c
2004-12-20
21:43:11.000000000 -0800
+++ modperl-2.0/src/modules/perl/modperl_env.c 2004-12-28
09:13:13.000000000 -0800
@@ -47,6 +47,30 @@
SvTAINTED_on(*svp);
}
+void modperl_env_hv_populate(pTHX_ apr_pool_t *p,
+ server_rec *s,
+ char *key,
+ char *val)
+{
+ MP_dSCFG(s);
+
+ HV *hv = ENVHV;
+ I32 klen = strlen(key);
+ SV **svp = hv_fetch(hv, key, klen, FALSE);
+
+ if (svp) {
+ sv_setpv(*svp, val);
+ }
+ else {
+ SV *sv = newSVpv(val, 0);
+ hv_store(hv, key, klen, sv, FALSE);
+ modperl_envelem_tie(sv, key, klen);
+ svp = &sv;
+ }
+
+ SvTAINTED_on(*svp);
+}
+
static MP_INLINE
void modperl_env_hv_delete(pTHX_ HV *hv, char *key)
{
@@ -153,6 +177,45 @@
"PATH", "TZ", NULL
};
+static void modperl_env_sync_table(pTHX_ apr_table_t *table)
+{
+ HV *hv = ENVHV;
+ U32 mg_flags;
+ int i;
+ const apr_array_header_t *array;
+ apr_table_entry_t *elts;
+
+ modperl_env_untie(mg_flags);
+
+ array = apr_table_elts(table);
+ elts = (apr_table_entry_t *)array->elts;
+
+ for (i = 0; i < array->nelts; i++) {
+ char *val;
+
+ if (!elts[i].key || !elts[i].val) {
+ continue;
+ }
+ val = getenv(elts[i].key);
+ if (!apr_strnatcmp(elts[i].val, val)) {
+ apr_table_set(table, elts[i].key, val);
+ }
+ }
+
+ modperl_env_tie(mg_flags);
+}
+
+void modperl_env_sync_server(pTHX_ apr_pool_t *p, server_rec *s)
+{
+ MP_dSCFG(s);
+
+ /* Make per-server PerlSetEnv and PerlPassEnv in sync with %ENV
+ * at config time
+ */
+ modperl_env_sync_table(aTHX_ scfg->SetEnv);
+ modperl_env_sync_table(aTHX_ scfg->PassEnv);
+}
+
void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s)
{
MP_dSCFG(s);
diff -ruN /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_env.h
modperl-2.0/src/modules/perl/modperl_env.h
--- /home/pvnaik/lab/mp2src/modperl-2.0/src/modules/perl/modperl_env.h
2004-12-01
01:20:06.000000000 -0800
+++ modperl-2.0/src/modules/perl/modperl_env.h 2004-12-28
09:13:13.000000000 -0800
@@ -33,6 +33,13 @@
void modperl_env_clear(pTHX);
+void modperl_env_hv_populate(pTHX_ apr_pool_t *p,
+ server_rec *s,
+ char *key,
+ char *val);
+
+void modperl_env_sync_server(pTHX_ apr_pool_t *p, server_rec *s);
+
void modperl_env_configure_server(pTHX_ apr_pool_t *p, server_rec *s);
void modperl_env_configure_request_srv(pTHX_ request_rec *r);
diff -ruN /home/pvnaik/lab/mp2src/modperl-2.0/t/directive/setupenv2.t
modperl-2.0/t/directive/setupenv2.t
--- /home/pvnaik/lab/mp2src/modperl-2.0/t/directive/setupenv2.t 1969-12-31
16:00:00.000000000 -0800
+++ modperl-2.0/t/directive/setupenv2.t 2004-12-28 05:06:49.000000000 -0800
@@ -0,0 +1,17 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+
+my $url = "/TestDirective__setupenv2";
+
+plan tests => 1;
+
+{
+ my $location = "$url";
+ my $expected = "srv: one two";
+ my $received = GET_BODY $location;
+ ok t_cmp($received, $expected, "access env variable");
+}
diff -ruN
/home/pvnaik/lab/mp2src/modperl-2.0/t/response/TestDirective/setupenv2.pm
modperl-2.0/t/response/TestDirective/setupenv2.pm
--- /home/pvnaik/lab/mp2src/modperl-2.0/t/response/TestDirective/setupenv2.pm
1969-12-31
16:00:00.000000000 -0800
+++ modperl-2.0/t/response/TestDirective/setupenv2.pm 2004-12-28
08:36:22.000000000 -0800
@@ -0,0 +1,68 @@
+package TestDirective::setupenv2;
+
+# This is test for checking PerlSetEnv in conf section
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Const -compile => qw(OK OR_ALL TAKE1);
+
+use Apache::CmdParms ();
+use Apache::Module ();
+
+my @directives = (
+ {
+ name => 'MyEnvTest',
+ func => __PACKAGE__ . '::MyEnvTest',
+ req_override => Apache::OR_ALL,
+ args_how => Apache::TAKE1,
+ errmsg => 'Env that will be stored.',
+ },
+);
+
+Apache::Module::add(__PACKAGE__, [EMAIL PROTECTED]);
+
+sub MyEnvTest {
+ my($self, $parms, $arg) = @_;
+ #warn "MyEnvTest: @{[$parms->path||'']}\n\t$arg\n";
+ push @{ $self->{MyEnvTest} }, $ENV{$arg};
+
+ # store the top level srv values in the server struct as well
+ unless ($parms->path) {
+ my $srv_cfg = $self->get_config($parms->server);
+ push @{ $srv_cfg->{MyEnvTest} }, $ENV{$arg};
+ }
+}
+
+sub get_config {
+ my($self, $s) = (shift, shift);
+ Apache::Module::get_config($self, $s, @_);
+}
+
+sub handler : method {
+ my($self, $r) = @_;
+
+ $r->content_type('text/plain');
+
+ my $s = $r->server;
+ my $srv_cfg = $self->get_config($s);
+ $r->print("srv: @{ $srv_cfg->{MyEnvTest}||[] }");
+
+ return Apache::OK;
+}
+
+1;
+__END__
+
+# APACHE_TEST_CONFIG_ORDER 950
+
+<Base>
+ PerlLoadModule TestDirective::setupenv2
+ PerlSetEnv FooEnv "one"
+ MyEnvTest "FooEnv"
+ <Perl>
+ 1;
+ </Perl>
+ PerlSetEnv BarEnv "two"
+ MyEnvTest "BarEnv"
+</Base>
--
http://pratik.syslock.org
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]