stas 2003/12/14 19:13:36
Modified: src/modules/perl modperl_mgv.c . Changes Log: Prevent a problem where an autovivified package (stash) prevents from modperl_mgv to load the file with that package (until now it was checking whether the stash existed already and skipped the loading if that was the case). Now checking %INC and attempting to load the module. Reporting the failure only if the module has failed to load and the stash is not defined (so that it's possible to autovivify packages without loading them from an external file). Revision Changes Path 1.28 +56 -12 modperl-2.0/src/modules/perl/modperl_mgv.c Index: modperl_mgv.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -u -r1.27 -r1.28 --- modperl_mgv.c 18 Sep 2003 07:58:46 -0000 1.27 +++ modperl_mgv.c 15 Dec 2003 03:13:36 -0000 1.28 @@ -181,6 +181,31 @@ } #endif + +static void package2filename(apr_pool_t *p, const char *package, + char **filename, int *len) +{ + *filename = apr_palloc(p, (strlen(package)+4)*sizeof(char)); + const char *s; + char *d; + + for (s = package, d = *filename; *s; s++, d++) { + if (*s == ':' && s[1] == ':') { + *d = '/'; + s++; + } + else { + *d = *s; + } + } + *d++ = '.'; + *d++ = 'p'; + *d++ = 'm'; + *d = '\0'; + + *len = d - *filename; +} + /* currently used for complex filters attributes parsing */ /* XXX: may want to generalize it for any handlers */ #define MODPERL_MGV_DEEP_RESOLVE(handler, p) \ @@ -259,23 +284,42 @@ } } - if (!(stash || (stash = gv_stashpv(name, FALSE))) && - MpHandlerAUTOLOAD(handler)) { - MP_TRACE_h(MP_FUNC, - "package %s not defined, attempting to load\n", name); - - if (modperl_require_module(aTHX_ name, FALSE)) { - MP_TRACE_h(MP_FUNC, "loaded %s package\n", name); - if (!(stash = gv_stashpv(name, FALSE))) { - MP_TRACE_h(MP_FUNC, "%s package still does not exist\n", - name); + if (!stash && MpHandlerAUTOLOAD(handler)) { + int len; + char *filename; + SV **svp; + + package2filename(p, name, &filename, &len); + svp = hv_fetch(GvHVn(PL_incgv), filename, len, 0); + + if (!(svp && *svp != &PL_sv_undef)) { /* not in %INC */ + MP_TRACE_h(MP_FUNC, + "package %s not in %INC, attempting to load '%s'\n", + name, filename); + + if (modperl_require_module(aTHX_ name, FALSE)) { + MP_TRACE_h(MP_FUNC, "loaded %s package\n", name); + } + else { + MP_TRACE_h(MP_FUNC, "failed to load %s package\n", name); return 0; } } else { - MP_TRACE_h(MP_FUNC, "failed to load %s package\n", name); - return 0; + MP_TRACE_h(MP_FUNC, "package %s seems to be loaded\n" + " $INC{%s)='%s';\n", + name, filename, SvPV_nolen(*svp)); } + } + + /* try to lookup the stash only after loading the module, to avoid + * the case where a stash is autovivified by a user before the + * module was loaded, preventing from loading the module + */ + if (!(stash || (stash = gv_stashpv(name, FALSE)))) { + MP_TRACE_h(MP_FUNC, "package %s seems to be loaded, " + "but can't find its stash\n", name); + return 0; } if ((gv = gv_fetchmethod(stash, handler_name)) && (cv = GvCV(gv))) { 1.281 +8 -0 modperl-2.0/Changes Index: Changes =================================================================== RCS file: /home/cvs/modperl-2.0/Changes,v retrieving revision 1.280 retrieving revision 1.281 diff -u -u -r1.280 -r1.281 --- Changes 15 Dec 2003 02:50:22 -0000 1.280 +++ Changes 15 Dec 2003 03:13:36 -0000 1.281 @@ -12,6 +12,14 @@ =item 1.99_12-dev +Prevent a problem where an autovivified package (stash) prevents from +modperl_mgv to load the file with that package (until now it was +checking whether the stash existed already and skipped the loading if +that was the case). Now checking %INC and attempting to load the +module. Reporting the failure only if the module has failed to load +and the stash is not defined (so that it's possible to autovivify +packages without loading them from an external file). [Stas] + MaxClients is now overridable from the t/TEST -maxclients command line option (it was hardcoded before). [Stas]