mod_perl2 STDOUT question

mod_perl2 STDOUT question

am 20.08.2008 17:26:29 von Niels Larsen

Greetings,

I have moved a big collection of modules to mod_perl2 under PerlRun
and can see a great speedup, as hoped. But in some of these modules
programs are run that write something to STDOUT that is then captured
and processed - which doesnt work since STDOUT is tie'ed to Apache.
I saw suggestions to use the $r-> interface, but I prefer to not be
mod_perl specific (write handlers or use the request object etc), at
least not until later. So to "borrow" STDOUT temporarily I did the
attempt below (found in Stas Bekmans 1.0 practical mod_perl), which
opens a temporary STDOUT into a string. Printing to STDOUT works as
hoped, but output from other programs run by system do not appear
in $out_str; instead they appear - most of the time, sometimes not -
in the console where Apache was started (with httpd -X). I can put
the command line to run in backticks and do print `@command`, and
that too works, but would like to use system, Proc::SafeExec, etc.
I use Apache 2.2.9, mod_perl 2.0.4 and Linux. Below the example is
the mod_perl part of httpd.conf.

Any ideas? (I'm sure its something obvious i missed, but it has
become an obstacle for me)

Niels L

------------------------------ test.cgi



#!/usr/bin/env perl

use strict;
use warnings FATAL => qw ( all );

use Symbol;

my ( $out_fh, $out_str );

{
$out_str = "";

$out_fh = Symbol::gensym();
open $out_fh, '>', \$out_str or die "Can't open stdout to string: $!";

$| = 1;

local *STDOUT = $out_fh;

# Print always puts output into always goes into $out_str,
print "hello\n";

# But commands like date, ls etc goes into $out_str sometimes,
# sometimes at console where apache was started with httpd -X
# system( "date" );
# print `date`; # works

close $out_fh;
}

#print "Content-type: text/html\n\n";
print "
\n";
print $out_str;
print "
\n";

print $ENV{"MOD_PERL"} ."
";
print $ENV{"GATEWAY_INTERFACE"} ."
";
print $ENV{"SERVER_PROTOCOL"} ."
";



--------------- httpd.conf

SetEnv TERM "dumb"
PerlSetEnv TERM "dumb"

LoadModule perl_module modules/mod_perl.so
PerlModule ModPerl::PerlRun


SetHandler perl-script
PerlResponseHandler ModPerl::PerlRun
Options SymLinksifOwnerMatch ExecCGI

Re: mod_perl2 STDOUT question

am 20.08.2008 18:15:25 von Jim Brandt

The system call forks a process and that process inherits the STDOUT
from perl. So since your perl is the persistent interpreter in Apache,
it would make sense that that's where most of the STDOUT messages will go.

I'm not sure if there is a way to intercept the STDOUT of the forked
process in this context, but from the perldoc on system:

"The return value is the exit status of the program
as returned by the "wait" call. To get the actual
exit value shift right by eight (see below). See
also "exec". This is _not_ what you want to use to
capture the output from a command, for that you
should use merely backticks or "qx//", as described
in "`STRING`" in perlop."


Niels Larsen wrote:
> Greetings,
>
> I have moved a big collection of modules to mod_perl2 under PerlRun
> and can see a great speedup, as hoped. But in some of these modules
> programs are run that write something to STDOUT that is then captured
> and processed - which doesnt work since STDOUT is tie'ed to Apache.
> I saw suggestions to use the $r-> interface, but I prefer to not be
> mod_perl specific (write handlers or use the request object etc), at
> least not until later. So to "borrow" STDOUT temporarily I did the
> attempt below (found in Stas Bekmans 1.0 practical mod_perl), which
> opens a temporary STDOUT into a string. Printing to STDOUT works as
> hoped, but output from other programs run by system do not appear
> in $out_str; instead they appear - most of the time, sometimes not -
> in the console where Apache was started (with httpd -X). I can put
> the command line to run in backticks and do print `@command`, and
> that too works, but would like to use system, Proc::SafeExec, etc.
> I use Apache 2.2.9, mod_perl 2.0.4 and Linux. Below the example is
> the mod_perl part of httpd.conf.
>
> Any ideas? (I'm sure its something obvious i missed, but it has
> become an obstacle for me)
>
> Niels L
>
> ------------------------------ test.cgi
>


>
> #!/usr/bin/env perl
>
> use strict;
> use warnings FATAL => qw ( all );
>
> use Symbol;
>
> my ( $out_fh, $out_str );
>
> {
> $out_str = "";
>
> $out_fh = Symbol::gensym();
> open $out_fh, '>', \$out_str or die "Can't open stdout to string: $!";
>
> $| = 1;
>
> local *STDOUT = $out_fh;
>
> # Print always puts output into always goes into $out_str,
> print "hello\n";
>
> # But commands like date, ls etc goes into $out_str sometimes,
> # sometimes at console where apache was started with httpd -X
> # system( "date" );
> # print `date`; # works
>
> close $out_fh;
> }
>
> #print "Content-type: text/html\n\n";
> print "
\n";
> print $out_str;
> print "
\n";
>
> print $ENV{"MOD_PERL"} ."
";
> print $ENV{"GATEWAY_INTERFACE"} ."
";
> print $ENV{"SERVER_PROTOCOL"} ."
";
>
>

>
> --------------- httpd.conf
>
> SetEnv TERM "dumb"
> PerlSetEnv TERM "dumb"
>
> LoadModule perl_module modules/mod_perl.so
> PerlModule ModPerl::PerlRun
>
>
> SetHandler perl-script
> PerlResponseHandler ModPerl::PerlRun
> Options SymLinksifOwnerMatch ExecCGI
>

>

--
Jim Brandt
Administrative Computing Services
University at Buffalo

Re: mod_perl2 STDOUT question

am 20.08.2008 18:46:37 von Perrin Harkins

On Wed, Aug 20, 2008 at 11:26 AM, Niels Larsen wrote:
> I can put
> the command line to run in backticks and do print `@command`, and
> that too works, but would like to use system, Proc::SafeExec, etc.

To fork and capture output without backticks, you have to do something
with pipes, like the IPC::Open* modules do. This isn't
mod_perl-specific and I think you can find some good examples in the
perl documentation. Maybe perlopentut would be a good starting place?

- Perrin

RE: mod_perl2 STDOUT question

am 20.08.2008 23:15:35 von eric.berg

I use IPC::Run3 quite a bit, and it's a good option for retrieving STDIN
and STDOUT from a forked process.

Be aware that with mod_perl2, subprocesses which are forked using system
and backticks (IPC::Run3 uses system) DO NOT INHERIT THE ENVIRONMENT OF
THE PROCESS FROM WHICH THEY ARE FORKED.

You can get around this by explicitly setting them with Env::C, on the
command line using the =22ENV1=3Dval1 ENV2=3Dval2 /path/to/prog param1 =
param2=22
syntax, though I don't think that's available to you using
IPC::Run3...don't hold me to that.

Alternatively, you can use the native Apache2 forking code, which is
available in Apache2::SubProcess.

BTW, thanks to Torsten Foertsch who helped me understand this problem in
a thread entitled 'mp2, IPC::Run3 && Environment Variables giving
=22variable not set=22 error' on this list last week.

Not sure that these solutions will work for a threaded MPM either.

Eric

> -----Original Message-----
> From: pharkins=40gmail.com =5Bmailto:pharkins=40gmail.com=5D On=20
> Behalf Of Perrin Harkins
> Sent: Wednesday, August 20, 2008 12:47 PM
> To: Niels Larsen
> Cc: modperl=40perl.apache.org
> Subject: Re: mod_perl2 STDOUT question
>=20
> On Wed, Aug 20, 2008 at 11:26 AM, Niels Larsen=20
> wrote:
> > I can put
> > the command line to run in backticks and do print `@command=60, and
> > that too works, but would like to use system, Proc::SafeExec, etc.
>=20
> To fork and capture output without backticks, you have to do something
> with pipes, like the IPC::Open* modules do. This isn't
> mod_perl-specific and I think you can find some good examples in the
> perl documentation. Maybe perlopentut would be a good starting place?
>=20
> - Perrin
>=20
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - =
- - - - - - -

This message is intended only for the personal and confidential use of the =
designated recipient(s) named above. If you are not the intended =
recipient of this message you are hereby notified that any review, =
dissemination, distribution or copying of this message is strictly =
prohibited. This communication is for information purposes only and =
should not be regarded as an offer to sell or as a solicitation of an =
offer to buy any financial product, an official confirmation of any =
transaction, or as an official statement of Lehman Brothers. Email =
transmission cannot be guaranteed to be secure or error-free. Therefore, =
we do not represent that this information is complete or accurate and it =
should not be relied upon as such. All information is subject to change =
without notice.

--------
IRS Circular 230 Disclosure:
Please be advised that any discussion of U.S. tax matters contained within =
this communication (including any attachments) is not intended or written =
to be used and cannot be used for the purpose of (i) avoiding U.S. tax =
related penalties or (ii) promoting, marketing or recommending to another =
party any transaction or matter addressed herein.