The following is a tentative patch, just to check whether I'm on the right
direction. It implements:
- PerlPassEnv (server wide)
? should it be in .htaccess as well?
- PerlSetEnv (server wide and dir)
- .htaccess is missing.
+ a simple test
I'm not sure how to test PerlPassEnv, since I cannot rely on any known env
var set ahead. Where would it be a good place to set it, before the server
starts? (has to be done like ulimit setting, but this should be specific
for mod_perl and not hardcoded in Apache-Test.
Comments are welcome
I also have a question regarding apr_table_t. When creating the table with
apr_table_make one has to specify nelts. But then it grows automatically
as required (right?), so what's the point of nelts then? pre-alloc? In any
case what netls should I use for env vars table? I've used 2.
Index: Apache-Test/lib/Apache/TestConfig.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
retrieving revision 1.50
diff -u -r1.50 TestConfig.pm
--- Apache-Test/lib/Apache/TestConfig.pm 2001/08/28 16:02:56 1.50
+++ Apache-Test/lib/Apache/TestConfig.pm 2001/09/04 11:10:42
@@ -983,3 +983,6 @@
#and some big ones
Alias /getfiles-binary-httpd @httpd@
Alias /getfiles-binary-perl @perl@
+
+PerlPassEnv HOME PERL5LIB
+
Index: src/modules/perl/mod_perl.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v
retrieving revision 1.63
diff -u -r1.63 mod_perl.c
--- src/modules/perl/mod_perl.c 2001/08/30 05:15:51 1.63
+++ src/modules/perl/mod_perl.c 2001/09/04 11:10:42
@@ -81,6 +81,10 @@
exit(1);
}
+ modperl_config_apply_PerlPassEnv(s, scfg, perl, p);
+ modperl_config_apply_PerlSetEnv(s, scfg, perl, p);
+
+
#ifndef USE_ITHREADS
cdata = modperl_cleanup_data_new(p, (void*)perl);
apr_pool_cleanup_register(p, cdata,
@@ -140,6 +144,9 @@
exit(1);
}
+ modperl_config_apply_PerlPassEnv(s, scfg, perl, p);
+ modperl_config_apply_PerlSetEnv(s, scfg, perl, p);
+
#ifdef USE_ITHREADS
if (!MpSrvENABLED(scfg)) {
@@ -369,9 +376,10 @@
static const command_rec modperl_cmds[] = {
MP_CMD_SRV_ITERATE("PerlSwitches", switches, "Perl Switches"),
- MP_CMD_SRV_ITERATE("PerlModule", modules, "PerlModule"),
- MP_CMD_SRV_ITERATE("PerlRequire", requires, "PerlRequire"),
- MP_CMD_DIR_ITERATE("PerlOptions", options, "Perl Options"),
+ MP_CMD_SRV_ITERATE("PerlModule", modules, "PerlModule"),
+ MP_CMD_SRV_ITERATE("PerlRequire", requires, "PerlRequire"),
+ MP_CMD_SRV_ITERATE("PerlPassEnv", passenv, "PerlPassEnv"),
+ MP_CMD_DIR_ITERATE("PerlOptions", options, "Perl Options"),
#ifdef MP_TRACE
MP_CMD_SRV_TAKE1("PerlTrace", trace, "Trace level"),
#endif
@@ -389,6 +397,7 @@
MP_CMD_DIR_TAKE1("PerlInterpScope", interp_scope,
"Scope of a Perl interpreter"),
#endif
+ MP_CMD_DIR_TAKE2("PerlSetEnv", setenv, "PerlSetEnv"),
MP_CMD_ENTRIES,
{ NULL },
};
Index: src/modules/perl/modperl_cmd.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.c,v
retrieving revision 1.6
diff -u -r1.6 modperl_cmd.c
--- src/modules/perl/modperl_cmd.c 2001/08/08 16:20:31 1.6
+++ src/modules/perl/modperl_cmd.c 2001/09/04 11:10:42
@@ -60,6 +60,32 @@
return NULL;
}
+MP_CMD_SRV_DECLARE(passenv)
+{
+ MP_dSCFG(parms->server);
+ *(const char **)apr_array_push(scfg->PassEnv) = arg;
+ MP_TRACE_d(MP_FUNC, "arg = %s\n", arg);
+ return NULL;
+}
+
+MP_CMD_SRV_DECLARE2(setenv)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)dummy;
+ int is_per_dir = parms->path ? 1 : 0;
+
+ if (is_per_dir) {
+ apr_table_set(scfg->SetEnv, arg1, arg2);
+ }
+ else {
+ apr_table_set(dcfg->SetEnv, arg1, arg2);
+ }
+ MP_TRACE_d(MP_FUNC, "arg1 = %s, arg2 = %s\n", arg1, arg2);
+ return NULL;
+}
+
+
+
MP_CMD_SRV_DECLARE(options)
{
MP_dSCFG(parms->server);
Index: src/modules/perl/modperl_cmd.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.h,v
retrieving revision 1.5
diff -u -r1.5 modperl_cmd.h
--- src/modules/perl/modperl_cmd.h 2001/08/08 07:02:41 1.5
+++ src/modules/perl/modperl_cmd.h 2001/09/04 11:10:42
@@ -8,10 +8,15 @@
#define MP_CMD_SRV_DECLARE(item) \
const char *modperl_cmd_##item(cmd_parms *parms, \
void *dummy, const char *arg)
+#define MP_CMD_SRV_DECLARE2(item) \
+const char *modperl_cmd_##item(cmd_parms *parms, \
+ void *dummy, const char *arg1, const char *arg2)
MP_CMD_SRV_DECLARE(trace);
MP_CMD_SRV_DECLARE(switches);
MP_CMD_SRV_DECLARE(modules);
MP_CMD_SRV_DECLARE(requires);
+MP_CMD_SRV_DECLARE(passenv);
+MP_CMD_SRV_DECLARE2(setenv);
MP_CMD_SRV_DECLARE(options);
#ifdef USE_ITHREADS
@@ -43,12 +48,20 @@
AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \
RSRC_CONF, desc )
+#define MP_CMD_SRV_TAKE2(name, item, desc) \
+ AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \
+ RSRC_CONF, desc )
+
#define MP_CMD_SRV_ITERATE(name, item, desc) \
AP_INIT_ITERATE( name, modperl_cmd_##item, NULL, \
RSRC_CONF, desc )
#define MP_CMD_DIR_TAKE1(name, item, desc) \
AP_INIT_TAKE1( name, modperl_cmd_##item, NULL, \
+ OR_ALL, desc )
+
+#define MP_CMD_DIR_TAKE2(name, item, desc) \
+ AP_INIT_TAKE2( name, modperl_cmd_##item, NULL, \
OR_ALL, desc )
#define MP_CMD_DIR_ITERATE(name, item, desc) \
Index: src/modules/perl/modperl_config.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_config.c,v
retrieving revision 1.35
diff -u -r1.35 modperl_config.c
--- src/modules/perl/modperl_config.c 2001/08/10 23:37:33 1.35
+++ src/modules/perl/modperl_config.c 2001/09/04 11:10:42
@@ -73,8 +73,10 @@
scfg->PerlModule = apr_array_make(p, 2, sizeof(char *));
scfg->PerlRequire = apr_array_make(p, 2, sizeof(char *));
+ scfg->PassEnv = apr_array_make(p, 2, sizeof(char *));
+ scfg->argv = apr_array_make(p, 2, sizeof(char *));
- scfg->argv = apr_array_make(p, 2, sizeof(char *));
+ scfg->SetEnv = apr_table_make(p, 2);
modperl_config_srv_argv_push((char *)ap_server_argv0);
@@ -90,6 +92,8 @@
dcfg->flags = modperl_options_new(p, MpDirType);
+ dcfg->SetEnv = apr_table_make(p, 2);
+
MP_TRACE_d(MP_FUNC, "0x%lx\n", (unsigned long)dcfg);
return dcfg;
@@ -157,6 +161,8 @@
merge_item(PerlModule);
merge_item(PerlRequire);
+ merge_item(PassEnv);
+ merge_item(SetEnv);
merge_item(threaded_mpm);
@@ -235,6 +241,44 @@
entries[i], modperl_server_desc(s,p));
return FALSE;
}
+ }
+
+ return TRUE;
+}
+
+int modperl_config_apply_PerlPassEnv(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p)
+{
+ char **entries;
+ int i;
+ dTHXa(perl);
+
+ entries = (char **)scfg->PassEnv->elts;
+ for (i = 0; i < scfg->PassEnv->nelts; i++){
+ char *val = getenv(entries[i]);
+ mp_magic_setenv(aTHX_ entries[i], val?val:"");
+ MP_TRACE_d(MP_FUNC, "Passed ENV: %s=%s for server %s\n",
+ entries[i], val, modperl_server_desc(s,p));
+ }
+
+ return TRUE;
+}
+
+int modperl_config_apply_PerlSetEnv(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p)
+{
+ dTHXa(perl);
+ apr_array_header_t *arr = apr_table_elts(scfg->SetEnv);
+ apr_table_entry_t *entries = (apr_table_entry_t *)arr->elts;
+ int i;
+
+ for (i = 0; i < arr->nelts; ++i) {
+ char *val = (const char *)apr_table_get(scfg->SetEnv, entries[i].key);
+ mp_magic_setenv(aTHX_ entries[i].key, val?val:"");
+ MP_TRACE_d(MP_FUNC, "Set ENV: %s=%s for server %s\n",
+ entries[i], val, modperl_server_desc(s,p));
}
return TRUE;
Index: src/modules/perl/modperl_config.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_config.h,v
retrieving revision 1.27
diff -u -r1.27 modperl_config.h
--- src/modules/perl/modperl_config.h 2001/08/08 16:20:31 1.27
+++ src/modules/perl/modperl_config.h 2001/09/04 11:10:42
@@ -67,4 +67,12 @@
modperl_config_srv_t *scfg,
PerlInterpreter *perl, apr_pool_t *p);
+int modperl_config_apply_PerlPassEnv(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p);
+
+int modperl_config_apply_PerlSetEnv(server_rec *s,
+ modperl_config_srv_t *scfg,
+ PerlInterpreter *perl, apr_pool_t *p);
+
#endif /* MODPERL_CONFIG_H */
Index: src/modules/perl/modperl_env.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_env.c,v
retrieving revision 1.3
diff -u -r1.3 modperl_env.c
--- src/modules/perl/modperl_env.c 2001/06/27 05:35:55 1.3
+++ src/modules/perl/modperl_env.c 2001/09/04 11:10:42
@@ -36,6 +36,17 @@
{ NULL }
};
+void mp_magic_setenv(pTHX_ char *key, char *val)
+{
+ int klen = strlen(key);
+ SV **ptr = hv_fetch(GvHV(PL_envgv), key, klen, TRUE);
+ if (ptr) {
+ SvSetMagicSV(*ptr, newSVpv(val,0));
+
+ SvTAINTED_on(*ptr);
+ }
+}
+
static void mp_env_request_populate(pTHX_ request_rec *r)
{
HV *hv = GvHV(PL_envgv);
Index: src/modules/perl/modperl_env.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_env.h,v
retrieving revision 1.1
diff -u -r1.1 modperl_env.h
--- src/modules/perl/modperl_env.h 2001/05/08 04:10:41 1.1
+++ src/modules/perl/modperl_env.h 2001/09/04 11:10:42
@@ -8,6 +8,8 @@
#define modperl_env_tie(mg_flags) \
SvFLAGS((SV*)GvHV(PL_envgv)) |= mg_flags
+void mp_magic_setenv(pTHX_ char *key, char *val);
+
void modperl_env_request_tie(pTHX_ request_rec *r);
void modperl_env_request_untie(pTHX_ request_rec *r);
Index: src/modules/perl/modperl_types.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_types.h,v
retrieving revision 1.46
diff -u -r1.46 modperl_types.h
--- src/modules/perl/modperl_types.h 2001/08/30 05:15:51 1.46
+++ src/modules/perl/modperl_types.h 2001/09/04 11:10:42
@@ -110,6 +110,7 @@
} modperl_interp_scope_e;
typedef struct {
+ MpHV *SetEnv;
MpHV *SetVars;
MpAV *PassEnv;
MpAV *PerlRequire, *PerlModule;
--- /dev/null Sat Apr 14 19:06:21 2001
+++ t/response/TestDirective/perlsetenv.pm Tue Sep 4 19:07:04 2001
@@ -0,0 +1,21 @@
+package TestDirective::perlsetenv;
+
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+
+sub handler {
+ my $r = shift;
+ $r->content_type('text/plain');
+
+ plan $r, tests => 1;
+
+ ok (exists $ENV{NEWHOME} && $ENV{NEWHOME} eq '/home/foo');
+
+ Apache::OK;
+}
+
+1;
+__END__
+PerlSetEnv NEWHOME /home/foo
+
_____________________________________________________________________
Stas Bekman JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide http://perl.apache.org/guide
mailto:[EMAIL PROTECTED] http://apachetoday.com http://eXtropia.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]