Re: modify url in web log via PerlLogHandler

2001-05-30 Thread Richard Chen

I did not get any responses so I consulted the sources
of both apache and mod_perl. It turned out that apache uses 
the_request method to get data for the log entries. 
The eagle book documented this the_request as
a read-only method. Fortunately in the recent versions of mod_perl
this is not the case any more and one can set a new value
via this method.

So modifying url in web log via PerlLogHandler is indeed possible.
Just modify the_request value instead of the uri value.

HTH for other people.

Thanks

Richard

On Sat, May 26, 2001 at 09:23:17AM -0400, Richard Chen wrote:
> Is it possible to modify the logged url in the usual
> modperl weblog via PerlLogHandler? I have tried this and
> it does not seem to work:
> 
> $ cat Apache/MyLog.pm
> package Apache::MyLog;
> use Apache::Constants qw(:common);
> sub handler {
> my $r = shift;
> my $uri=$r->uri;
>   return DECLINED if ($r->filename !~ /foobar/);
> print STDERR "in MyLog handler, \$uri=$uri, modify it now\n";
> $r->uri('/foobar_changed');
> return OK;
> }
> 1;
> 
> When this is installed like this:
> 
> 
> PerlLogHandler Apache::MyLog
> 
> 
> I can see the debugging message in error_log but the url logged 
> in the weblog is still the same as before.
> 
> Thanks for any info.
> 
> Richard



modify url in web log via PerlLogHandler

2001-05-26 Thread Richard Chen

Is it possible to modify the logged url in the usual
modperl weblog via PerlLogHandler? I have tried this and
it does not seem to work:

$ cat Apache/MyLog.pm
package Apache::MyLog;
use Apache::Constants qw(:common);
sub handler {
my $r = shift;
my $uri=$r->uri;
return DECLINED if ($r->filename !~ /foobar/);
print STDERR "in MyLog handler, \$uri=$uri, modify it now\n";
$r->uri('/foobar_changed');
return OK;
}
1;

When this is installed like this:


PerlLogHandler Apache::MyLog


I can see the debugging message in error_log but the url logged 
in the weblog is still the same as before.

Thanks for any info.

Richard



Re: modify Server header via a handler

2001-05-02 Thread Richard Chen

On Wed, May 02, 2001 at 03:22:51PM +0100, Matt Sergeant wrote:
> On Wed, 2 May 2001, Mark Maunder wrote:
> 
> > You can get the server string in the header down to a minimum (Just 'Apache')
> > by putting
> > ServerTokens ProductOnly
> > on your httpd.conf. (Only supported after 1.3.12)
> > You can then use ap_add_version_component (C API) to add stuff after that.
> 
> Right, but the problem is you can't do this after module initialization
> (which is where mod_perl adds it's bits), but the PerlModule's are loaded
> after that time, so you can't do it from Perl, at least not without a
> major re-design of the mod_perl internals. You can't even do it from XS
> loaded from Perl, because of that reason.
> 

That is right, modperl cannot do this. I guess we have
to live with certain limitations of modperl. However, I just
found out that it is trivial to change this Server header to
whatever you want by changing just a single line in the apache
source file http_main.c:

API_EXPORT(const char *) ap_get_server_version(void)
{
return (server_version ? server_version : SERVER_BASEVERSION);
}

Just replace the return statement above with

return "My Customized Web Server";

and rebuild your new httpd. I have even tried this on the
old stronghold server running apache 1.3.6 and it worked.
Since the apache source is always available, this customization
is not a big deal.

The reason I wanted to do this was not to let people find out
(not easily that is) what we are running so that they cannot 
exploit known security holes of the past version.

Richard Chen



modify Server header via a handler

2001-05-01 Thread Richard Chen

I would like to customize or suppress the Server header
from the modperl server responses such as this:

Server: Apache/1.3.19 (Unix) mod_perl/1.25 mod_ssl/2.8.1 OpenSSL/0.9.6

I thought I could simply set up a Fixup handler to do this:

package NoServerInfo;
use Apache::Constants qw(:common);
sub handler {
my $r=shift;
$r->header_out(Server => 'Foo Bar');
return OK;
}
1;

But this does not seem to work. Is there some kind of restriction
about this particular header in modperl? Without modifying 
the source code, is there a way to customize this Server header field?

Thanks for any info

Richard



Re: signal delivered to a different process?

2001-03-10 Thread Richard Chen

On Sat, Mar 10, 2001 at 12:41:25PM +0800, Stas Bekman wrote:
> On Fri, 9 Mar 2001, Richard Chen wrote:
> 
> > This is pretty weird situation. I have installed a signal
> > handler in startup.pl which showed that the signal is
> > delivered to a different process!
> >
> > Here are the demo files:
> >
> > $ cat conf/startup.pl
> > #!/usr/local/bin/perl
> > use lib '/usr/local/apache/modules';
> > $SIG{USR2}=sub {
> > print STDERR "Received USR2 signal:\n";
> > print STDERR "In SIG, pid=$$, ppid=".getppid()."\n";
> > };
> >
> > # cat /usr/local/apache/modules/Apache/ChildInit.pm
> > package Apache::ChildInit;
> > sub handler {
> > print STDERR "In ChildInit, pid=$$, ppid=".getppid()."\n";
> > return;
> > }
> > 1;
> >
> > In httpd.conf I have these 2 lines added:
> > PerlRequire conf/startup.pl
> > PerlChildInitHandler Apache::ChildInit
> >
> > After launching the modperl process we have:
> >
> > $ ps -ef|grep http|grep root
> > root  5964 1  0 16:17 ?00:00:00 /usr/local/apache/bin/httpd
> >
> > $ tail -1 error_log
> > In ChildInit, pid=5965, ppid=5964
> >
> > So the modperl parent process has pid 5964.
> > After sending USR2 signal to the modperl parent process,
> > these lines appear in the error_log file:
> > Received USR2 signal:
> > In SIG, pid=5963, ppid=1
> >
> > So the signal is delivered to the process 5963 instead of the correct 5964.
> >
> > Has anyone seen this before?
> > Is this a bug in modperl or if the procedure for installing the handler
> > is incorrect?
> 
> I think that it has nothing to with mod_perl, it's the OS that handles
> pizza^H^H^H^H^Hsignal deliveries.
> 

> BTW, what kind of process 5963 was? How come that if it wasn't the httpd
> process you have installed the signal handler in, it knew to print the
> stuff to the error_log which it has never opened? looks like you are not
> getting the parent process pid correctly.
> 
> You also didn't tell, how did you send the signal.
> 

I think the problem is with the procedure of installing the handler.
I did not know what kind of process 5963 was because it did not
show up in the ps command even within the sig handler. But now
I caught it by modifying the startup.pl routine to show the pid
when the sig handler is defined:

$ cat startup.pl
#!/usr/local/bin/perl  
use lib '/usr/local/apache/modules';
print STDERR "In startup, pid=$$\n";
$SIG{USR2}=sub {
print STDERR "Received USR2 signal\n";
print STDERR "In SIG, pid=$$, ppid=".getppid()."\n";
};

Now here are the steps to show the problem

Start up the modperl server:

# ../bin/httpd -d /usr/local/apache
In startup, pid=11525

This means that at the time when the sig handler is defined, pid=11525.
However, the ps command shows a different pid for modperl:

# ps -ef|grep http|grep root
root 11526 1  1 08:28 ?00:00:00 ../bin/httpd -d /usr/local/apach

# tail -1 ../logs/error_log  
In ChildInit, pid=11527, ppid=11526

The above clearly shows that the httpd server has pid 11526,
not 11525. This means that process 11525 started by the startup
procedure immediately exits after forking the real httpd process 11526.

Now we send signal to the httpd server:

# kill -USR2 11526

And here are the lines recorded in error_log:

# tail -2 ../logs/error_log
Received USR2 signal
In SIG, pid=11525, ppid=1

So clearly the signal handler still remembers that at
the time when it was defined, the pid was 11525, not 11526
for httpd.

Apparently modperl did some preparatory work before forking out
the real httpd. This is something new to me.

I wonder if there is another way to install the sig handler so
that it is defined inside the final httpd root process.

Thanks for your help.

Richard



signal delivered to a different process?

2001-03-09 Thread Richard Chen

This is pretty weird situation. I have installed a signal
handler in startup.pl which showed that the signal is
delivered to a different process!

Here are the demo files:

$ cat conf/startup.pl
#!/usr/local/bin/perl
use lib '/usr/local/apache/modules';
$SIG{USR2}=sub {
print STDERR "Received USR2 signal:\n";
print STDERR "In SIG, pid=$$, ppid=".getppid()."\n";
};

# cat /usr/local/apache/modules/Apache/ChildInit.pm
package Apache::ChildInit;
sub handler {
print STDERR "In ChildInit, pid=$$, ppid=".getppid()."\n";
return;
}
1;

In httpd.conf I have these 2 lines added:
PerlRequire conf/startup.pl
PerlChildInitHandler Apache::ChildInit

After launching the modperl process we have:

$ ps -ef|grep http|grep root
root  5964 1  0 16:17 ?00:00:00 /usr/local/apache/bin/httpd

$ tail -1 error_log
In ChildInit, pid=5965, ppid=5964

So the modperl parent process has pid 5964.
After sending USR2 signal to the modperl parent process, 
these lines appear in the error_log file:
Received USR2 signal:
In SIG, pid=5963, ppid=1

So the signal is delivered to the process 5963 instead of the correct 5964.

Has anyone seen this before?
Is this a bug in modperl or if the procedure for installing the handler 
is incorrect?

I used 
Apache/1.3.17 (Unix) mod_perl/1.25 mod_ssl/2.8.0 OpenSSL/0.9.6
on a linux 6.1 box.

Thanks for any info.

Richard



sending USR2 signal to refresh cached data?

2001-03-09 Thread Richard Chen

I am testing the following idea to refresh sporadically
changed read-only data cache. 

The parent modperl process first cache a data hash %foo.
Now all the child modperl processes will inherit this data hash.
We install a signal handler in the parent process to reload the
hash when a USR2 signal is received.

To refresh the cached data %foo. First I obtain a list of
child processes. Then I send a USR2 signal to the parent
process to reload the data. Then I send USR1 signal to the
list of child processes already recorded to make them gracefully exit.
At this point, all the memory about the old data should be gone.

So now the parent modperl process has newly freshed data. 
The future children should inherit this changed data. But I
found this not to be the case. The data in the parent process
is indeed changed. But the newly spawned children still retains the
old data hash. At least that is what my preliminary testing shows.

My question is where does the logic break in the above scenario?
I tried this on a solaris box.

Thanks for any info.

Richard



Re: problem installing multiple versions of modperl

2000-11-07 Thread Richard Chen

On Wed, Nov 08, 2000 at 01:58:41AM +, G.W. Haywood wrote:
> Hi there,
> 
> On Tue, 7 Nov 2000, Richard Chen wrote:
> 
> > when I do 'make install', make detects that I already have an older
> > version of modperl and tried to rm them:
> 
> Don't use it then!  Install the files where you want them manually.
> Make yourself familiar with an ordinary layout before you try to
> set up a complex one.  Make sure that the several Apaches aren't
> going to conflict by trying to share files they shouldn't share.
> 
> It's in the Guide.
> 
> 73,
> Ged.

I read the guide before I posted :-)

Well, it only happens on solaris. On linux, the same procedure
goes through without a hitch. From the linux output I actually
find the correct next command to use on solaris:
(cd ../apache_1.3.14 && make install)

That worked like a charm on solaris too and built both apache and modperl
successfully in my home dir.

Richard



problem installing multiple versions of modperl

2000-11-07 Thread Richard Chen

Hi,
I already have an older version of modperl installed 
in the standard location. I would like to try out the
newer version of apache/modperl without disturbing those
in production. So I did this:

/export/home/chenri/mod_perl-1.24_01$ perl Makefile.PL PREFIX=/export/home/chenri 
EVERYTHING=1  USE_APACI=1  DO_HTTPD=1 APACHE_SRC=../apache_1.3.14/src 
APACI_ARGS="--prefix=/export/home/chenri/apache,--activate-module=src/modules/perl/libperl.a,--enable-module=info,--enable-module=headers,--enable-module=rewrite"

/export/home/chenri/mod_perl-1.24_01$ make
/export/home/chenri/mod_perl-1.24_01$ make test

That is fine. However, when I do 'make install', make detects
that I already have an older version of modperl and tried to
rm them:

...
## Differing version of auto/Apache/include/regex/regex2.h found. You might like to
rm /usr/local/lib/perl5/site_perl/5.005/sun4-solaris/auto/Apache/include/regex/regex2.h
## Running 'make install UNINST=1' will unlink all those files for you.
*** Error code 13
make: Fatal error: Command failed for target `pure_site_install'

Have you encountered this and how to get around it?

Thanks for any info.

Richard



Re: open(FH,'|qmail-inject') fails

2000-09-09 Thread Richard Chen

On Sat, Sep 09, 2000 at 12:29:36PM -0700, Bill Moseley wrote:
> At 11:15 PM 09/08/00 +0200, Stas Bekman wrote:
> >On Fri, 8 Sep 2000, Bill Moseley wrote:
> >> I just looked at my old mail sending module a few days ago that uses
> >> sendmail and would fallback to Net::SMTP if sendmail wasn't available (it
> >> was running on Win at one point, argh!).  I just removed the Net::SMTP
> >> part.  Are you saying that I removed the wrong code?
> 
> >> At 10:31 AM 09/08/00 +0200, Stas Bekman wrote:
> >
> >As Perrin has suggested, benchmark it an see what's faster. It's so
> >simple.
> 
> 
> 
> Benchmark: timing 1 iterations of SMTP, Sendmail...
> SMTP: 60 wallclock secs ( 0.03 usr +  0.00 sys =  0.03 CPU) @ 33.33/s
> (n=1)
>  (warning: too few iterations for a reliable count)
> Sendmail:  0 wallclock secs ( 0.00 usr  0.00 sys +  0.01 cusr  0.01 csys =
>  0.02 CPU)
>  (warning: too few iterations for a reliable count)
> 
> I guess it isn't a fair test ;)  I had my DNS servers unplugged and used
> -odd with sendmail.  And I guess if I set a timeout of 60 seconds on
> Net::SMTP I better be ready to wait that long.
> 
> 
> 
> Seriously, though, I can't imagine how to benchmark such a complicated
> thing as sending mail.  I can do it on my machine, I guess, but that
> doesn't tell me how it will work on the live machine that's also sending
> out a mailing list or running a faulty nscd on Solaris that hangs DNS
> requests, or mailing to [EMAIL PROTECTED] and DNS is hopping from DNS to
> DNS to do the lookup.  
> 
> The nscd thing is the reason I moved from using Net::SMTP; SMTP worked
> great most of the time, but really messed things up when the DNS was not
> working.  Forking may or may not be slower, but it like more of a sure bet.
> 
> Have fun,
> 
> 
> 
> 
> Bill Moseley
> mailto:[EMAIL PROTECTED]

All your objections about smtp will be gone if you set up a
dedicated local account just for processing emails from modperl.
Since the account is local, Net::SMTP will get done instantly
and the modperl can get back doing what it is supposed to be doing
instead of waiting for dns resolution, nscd and what not.

So in modperl, you write the real email as the body of email
to the local account, giving it a special subject line such
as "send out the body text". Then you set up procmail or .forward
for that local account so that it will do "sendmail -oi -t" or
whatever to actually send the body of text. It can take as much time
as it wants without interfering the website service.

Richard



Re: setting LD_LIBRARY_PATH via PerlSetEnv does not work

2000-08-21 Thread Richard Chen

It worked like a charm! If PerlSetEnv could not do it, I think
this should be documented in the guide. I could not find any mention 
about ldconfig in the modperl guide. May be I missed it somehow.

The procedure on linux is very simple:
# echo $ORACLE_HOME/lib >> /etc/ld.so.conf
# ldconfig

Thanks

Richard

On Sun, Aug 20, 2000 at 08:11:50PM -0700, Yann Ramin wrote:
> As far as FreeBSD goes, LD_LIBRARY_PATH is not searched for setuid
> programs (aka, Apache). This isn't a problem for CGIs since they don't
> do a setuid (and are forked off), but Apache does, and mod_perl is in
> Apache.  I think thats right anyway :)
> 
> You could solve this globaly by running ldconfig (I assume Linux has it,
> FreeBSD does).  You'd be looking for:
> 
> ldconfig -m 
> 
> Hope that helps.
> 
> Yann
> 
> Richard Chen wrote:
> > 
> > This is a redhat linux 6.2 box with perl 5.005_03, Apache 1.3.12,
> > mod_perl 1.24, DBD::Oracle 1.06, DBI 1.14 and oracle 8.1.6.
> > For some odd reason, in order to use DBI, I have to set
> > LD_LIBRARY_PATH first. I don't think I needed to do this when I
> > used oracle 7. This is fine on the command line because
> > I can set it in the shell environment. For cgi scripts,
> > the problem is also solved by using apache SetEnv directive. However,
> > this trick does not work under modperl. I had tried PerlSetEnv
> > to no avail. The message is the same as if the LD_LIBRARY_PATH is not set:
> > 
> > install_driver(Oracle) failed: Can't load
> > '/usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/Oracle/Oracle.so' for module 
>DBD::Oracle:
> > libclntsh.so.8.0: cannot open shared object file: No such file or directory at
> > /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169. at (eval 27) line 3 
>Perhaps a required shared
> > library or dll isn't installed where expected at /usr/local/apache/perl/tmp.pl 
>line 11
> > 
> > Here is the section defining LD_LIBRARY_PATH under Apache::Registry:
> > 
> > PerlModule Apache::Registry
> > Alias /perl/ /usr/local/apache/perl/
> > 
> >   PerlSetEnv LD_LIBRARY_PATH /u01/app/oracle/product/8.1.6/lib
> >   SetHandler perl-script
> >   PerlHandler Apache::Registry
> >   Options ExecCGI
> >   PerlSendHeader On
> >   allow from all
> > 
> > 
> > Does anyone know why PerlSetEnv does not work in this case?
> > How come SetEnv works for cgi scripts? What is the work around?
> > 
> > Thanks for any info.
> > 
> > Richard
> 
> -- 
> 
> 
> Yann Ramin[EMAIL PROTECTED]
> Atrus Trivalie Productionswww.redshift.com/~yramin
> Monterey High IT  www.montereyhigh.com
> ICQ   46805627
> AIM   oddatrus
> Marina, CA
> 
> IRM Developer   Network Toaster Developer
> SNTS Developer  KLevel Developer
> 
> (yes, this .signature is way too big)
> 
> "All cats die.  Socrates is dead.  Therefore Socrates is a cat."
>   - The Logician
> 
>   THE STORY OF CREATION
> 
> In the beginning there was data.  The data was without form and null,
> and darkness was upon the face of the console; and the Spirit of IBM
> was moving over the face of the market.  And DEC said, "Let there be
> registers"; and there were registers.  And DEC saw that they carried;
> and DEC seperated the data from the instructions.  DEC called the data
> Stack, and the instructions they called Code.  And there was evening
> and there was a maorning, one interrupt...
>   -- Rico Tudor
> 
> William Safire's Rules for Writers:
> 
> Remembe



setting LD_LIBRARY_PATH via PerlSetEnv does not work

2000-08-20 Thread Richard Chen

This is a redhat linux 6.2 box with perl 5.005_03, Apache 1.3.12,
mod_perl 1.24, DBD::Oracle 1.06, DBI 1.14 and oracle 8.1.6. 
For some odd reason, in order to use DBI, I have to set 
LD_LIBRARY_PATH first. I don't think I needed to do this when I
used oracle 7. This is fine on the command line because 
I can set it in the shell environment. For cgi scripts, 
the problem is also solved by using apache SetEnv directive. However, 
this trick does not work under modperl. I had tried PerlSetEnv
to no avail. The message is the same as if the LD_LIBRARY_PATH is not set:

install_driver(Oracle) failed: Can't load
'/usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/Oracle/Oracle.so' for module 
DBD::Oracle:
libclntsh.so.8.0: cannot open shared object file: No such file or directory at
/usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169. at (eval 27) line 3 Perhaps 
a required shared
library or dll isn't installed where expected at /usr/local/apache/perl/tmp.pl line 11 

Here is the section defining LD_LIBRARY_PATH under Apache::Registry:

PerlModule Apache::Registry
Alias /perl/ /usr/local/apache/perl/

  PerlSetEnv LD_LIBRARY_PATH /u01/app/oracle/product/8.1.6/lib
  SetHandler perl-script
  PerlHandler Apache::Registry
  Options ExecCGI
  PerlSendHeader On
  allow from all


Does anyone know why PerlSetEnv does not work in this case?
How come SetEnv works for cgi scripts? What is the work around?

Thanks for any info.

Richard



Re: Apache::Registry and clearing package name space

2000-05-07 Thread Richard Chen

I found that a modified version of scrub_package
(written by Mark-Jason Dominus and described in perlfaq7)
works correctly and more efficiently than
Apache::PerlRun->flush_namespace

Here is the original scrub_package subroutine:

 sub scrub_package {
 no strict 'refs';
 my $pack = shift;
 die "Shouldn't delete main package"
 if $pack eq "" || $pack eq "main";
 my $stash = *{$pack . '::'}{HASH};
 my $name;
 foreach $name (keys %$stash) {
 my $fullname = $pack . '::' . $name;
 # Get rid of everything with that name.
 undef $$fullname;
 undef @$fullname;
 undef %$fullname;
 undef &$fullname;
 undef *$fullname;
 }
 }

Instead of the line
  undef &$fullname;
which undef's the source subroutine, one should use
  *{$fullname}=sub {};
This fix is obvious because that is the way how a code alias is
generated in the first place. In order to undef this alias,
just let it point to an anonymous subroutine which does nothing.

Since this does not involve B.pm, it is more efficient than

Apache::PerlRun->flush_namespace

Also, I never got Apache::PerlRun->flush_namespace to work in
my case. Looking at the source used:

sub undef_cv_if_owner {
return unless $INC{'B.pm'};
my($package, $cv) = @_;
my $obj= B::svref_2object($cv);
my $stash  = $obj->GV->STASH->NAME;
return unless $package eq $stash;
undef &$cv;
}

For one thing $package never equals $stash. Further, I believe that
the last line
undef &$cv;
suffers from the same bug found in the original version of scrub_package.
I.e., it undef's the source subroutine!

Thanks for your attention.

Richard Chen

Richard Chen wrote:
> 
> Unfortunately, the crucial part about clearing/removing
> subroutine alias does not work when using
> Apache::PerlRun->flush_namespace('Q')
> I suspect this is a bug in PerlRun. Here is the demo program
> (It can be run from the command line)
> 
> $ cat tmp.pl
> #!/usr/bin/perl -w
> use strict;
> use Apache::PerlRun;
> print "Content-type: text/plain\n\n";
> %Q::in=();
> $Q::in{first_name}='first_name';
> *Q::hello=\&hello;
> print "here is the symbol table\n";
> print join("\n", map { "\$Q::{$_}=$Q::{$_}" } keys %Q::),"\n";
> print "\nbefore clear name space, \%Q::in is\n";
> print join("\n", map { "\$Q::in{$_}=$Q::in{$_}" } keys %Q::in),"\n";
> print "\nbefore clear name space, calling \&Q::hello yields\n";
> &Q::hello();
> print "-Now clear package name space-\n";
> Apache::PerlRun->flush_namespace('Q');
> print "here is the symbol table\n";
> print join("\n", map { "\$Q::{$_}=$Q::{$_}" } keys %Q::),"\n";
> print "\nafter name space, \%Q::in is\n";
> print join("\n",map { "\$Q::in{$_}=$Q::in{$_}" } keys %Q::in),"\n";
> print "\nafter clear name space, calling \&Q::hello yields\n";
> &Q::hello();
> sub hello { print "hello\n"; }
> 
> $ ./tmp.pl
> here is the symbol table
> $Q::{hello}=*Q::hello
> $Q::{in}=*Q::in
> 
> before clear name space, %Q::in is
> $Q::in{first_name}=first_name
> 
> before clear name space, calling &Q::hello yields
> hello
> -Now clear package name space-
> Odd number of elements in hash assignment at 
>/usr/lib/perl5/site_perl/5.005/i586-linux/Apache/PerlRun.pm line 310.
> Use of uninitialized value at 
>/usr/lib/perl5/site_perl/5.005/i586-linux/Apache/PerlRun.pm line 310.
> here is the symbol table
> $Q::{hello}=*Q::hello
> $Q::{in}=*Q::in
> 
> after name space, %Q::in is
> Use of uninitialized value at ./bar.cgi line 19.
> $Q::in{}=
> 
> after clear name space, calling &Q::hello yields
> hello
> 
> Note in particular that the value for &Q::hello still exists.
> Since you have pointed out that symbol table is constructed at
> compile time, at least the clean up of name space should make this
> value undefed.
> 
> Doug MacEachern wrote:
> >
> > On Mon, 1 May 2000, Richard Chen wrote:
> >
> > > Hello,
> > >   I am having a problem clearing variables and aliases
> > > in a temporary package name space. The source of the problem
> > > is in making legend cgi scripts work under Apache::Registry.
&g

Re: Apache::Registry and clearing package name space

2000-05-04 Thread Richard Chen

Unfortunately, the crucial part about clearing/removing
subroutine alias does not work when using
Apache::PerlRun->flush_namespace('Q')
I suspect this is a bug in PerlRun. Here is the demo program
(It can be run from the command line)

$ cat tmp.pl
#!/usr/bin/perl -w
use strict;
use Apache::PerlRun;
print "Content-type: text/plain\n\n";
%Q::in=();
$Q::in{first_name}='first_name';
*Q::hello=\&hello;
print "here is the symbol table\n";
print join("\n", map { "\$Q::{$_}=$Q::{$_}" } keys %Q::),"\n";
print "\nbefore clear name space, \%Q::in is\n";
print join("\n", map { "\$Q::in{$_}=$Q::in{$_}" } keys %Q::in),"\n";
print "\nbefore clear name space, calling \&Q::hello yields\n";
&Q::hello();
print "-Now clear package name space-\n";
Apache::PerlRun->flush_namespace('Q');
print "here is the symbol table\n";
print join("\n", map { "\$Q::{$_}=$Q::{$_}" } keys %Q::),"\n";
print "\nafter name space, \%Q::in is\n";
print join("\n",map { "\$Q::in{$_}=$Q::in{$_}" } keys %Q::in),"\n";
print "\nafter clear name space, calling \&Q::hello yields\n"; 
&Q::hello();
sub hello { print "hello\n"; }

$ ./tmp.pl
here is the symbol table
$Q::{hello}=*Q::hello
$Q::{in}=*Q::in

before clear name space, %Q::in is
$Q::in{first_name}=first_name

before clear name space, calling &Q::hello yields
hello
-Now clear package name space-
Odd number of elements in hash assignment at 
/usr/lib/perl5/site_perl/5.005/i586-linux/Apache/PerlRun.pm line 310.
Use of uninitialized value at 
/usr/lib/perl5/site_perl/5.005/i586-linux/Apache/PerlRun.pm line 310.
here is the symbol table
$Q::{hello}=*Q::hello
$Q::{in}=*Q::in

after name space, %Q::in is
Use of uninitialized value at ./bar.cgi line 19.
$Q::in{}=

after clear name space, calling &Q::hello yields
hello


Note in particular that the value for &Q::hello still exists.
Since you have pointed out that symbol table is constructed at
compile time, at least the clean up of name space should make this
value undefed.


Doug MacEachern wrote:
> 
> On Mon, 1 May 2000, Richard Chen wrote:
> 
> > Hello,
> >   I am having a problem clearing variables and aliases
> > in a temporary package name space. The source of the problem
> > is in making legend cgi scripts work under Apache::Registry.
> > But the problem can be isolated and shown by the following
> > demo program:
> >
> > $ cat foo.cgi
> > #!/usr/bin/perl -w
> > use strict;
> > use Symbol qw(delete_package);
> > print "Content-type: text/plain\n\n";
> > %Q::userdata=();
> > $Q::userdata{first_name}='first_name';
> > $Q::userdata{last_name}='last_name';
> > *Q::hello=\&hello;
> > print "here is the symbol table\n";
> > while (my($k,$v)=each %Q::) {
> > print "$k => $v\n";
> > }
> > delete_package('Q');
> > sub hello {
> > print "hi\n";
> > }
> >
> > The first time it runs, it yields:
> >
> > here is the symbol table
> > userdata => *Q::userdata
> > hello => *Q::hello
> >
> > But there after, modperl shows emtpy symbol table.
> 
> the problem is that Perl creates symbol table references at compile time,
> Symbol::delete_package() wipes those references out of existence.
> try using Apache::PerlRun->flush_namespace('Q'), which clears just
> the values, and leaves the references in tact.



Apache::Registry and clearing package name space

2000-05-01 Thread Richard Chen

Hello,
I am having a problem clearing variables and aliases
in a temporary package name space. The source of the problem
is in making legend cgi scripts work under Apache::Registry.
But the problem can be isolated and shown by the following
demo program:

$ cat foo.cgi
#!/usr/bin/perl -w
use strict;
use Symbol qw(delete_package);
print "Content-type: text/plain\n\n";
%Q::userdata=();
$Q::userdata{first_name}='first_name';
$Q::userdata{last_name}='last_name';
*Q::hello=\&hello;
print "here is the symbol table\n";
while (my($k,$v)=each %Q::) {
print "$k => $v\n";
}
delete_package('Q');
sub hello {
print "hi\n";
}

The first time it runs, it yields:

here is the symbol table
userdata => *Q::userdata
hello => *Q::hello

But there after, modperl shows emtpy symbol table.

In my actual implementation, delete_package is used
inside a PerlCleanupHandler. But the behavior is the
same: the symbol table is completely gone even if
I reinitialize the variables and aliases at the start
again.

Does anyone know a way around this? In perlfaq7
another method using scrub_package is mentioned.
But that one is not appropriate because if a subroutine
is aliased, that scrub_package will make the original
subroutine undefined, causing havoc all over the place.

Thanks for any info.

Richard