mod_perl2 STDOUT question - modperl

This is a discussion on mod_perl2 STDOUT question - modperl ; 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 ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: mod_perl2 STDOUT question

  1. mod_perl2 STDOUT question

    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



  2. Re: mod_perl2 STDOUT question

    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


  3. Re: mod_perl2 STDOUT question

    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


  4. RE: mod_perl2 STDOUT question

    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 "ENV1=val1 ENV2=val2 /path/to/prog param1 param2"
    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
    "variable not set" error' on this list last week.

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

    Eric

    > -----Original Message-----
    > From: pharkins@gmail.com [mailtoharkins@gmail.com] On
    > Behalf Of Perrin Harkins
    > Sent: Wednesday, August 20, 2008 12:47 PM
    > To: Niels Larsen
    > Cc: modperl@perl.apache.org
    > Subject: Re: mod_perl2 STDOUT question
    >
    > 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
    >

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    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.


+ Reply to Thread