You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Matthew Smith <ma...@yahoo.com> on 2006/06/28 22:07:17 UTC

use of STDERR in forked children

Hi, 

I originally posted this to the embperl listserv, but
I haven't gotten any responses.  So maybe somebody
here can help me. I hope!

I'm working on a mechanism to fork a a long running
child process.  I've followed the standard mod_perl
forking wisdom in
http://modperlbook.org/html/ch10_02.html.

My issue is that warn() doesn't work in the child
process, though printing directly to STDERR does.

Also, I want STDERR to go to the apache log like it
normally would, but I don't know how to determine what
the path to the log is. I can't hard code it since it
changes depending on the environment (dev vs. qa vs.
prod).

I haven't tried this using Apache::Registry (since we
don't run it) but I thought it might be and Embperl
thing since I couldn't find anything on the mod_perl
lists...

I'm using Apache 1.3 and Embperl 1.36

Your help is greatly appreciated.

Here's the code:
[# SNIP #]
[!
    use POSIX 'setsid';
    use Apache;
!]
[-
    my $childPid = undef;
    $SIG{CHLD} = 'IGNORE';

    if ($childPid = fork) {
        $output =  "Parent $$ has finished, kid's PID:
$childPid\n";
    }
    else {
        warn "starting child $$\n";
        $req_rec->cleanup_for_exec( ); # untie the
socket
        chdir '/'                 or die "Can't chdir
to /: $!";
        open STDIN, '/dev/null'   or die "Can't read
/dev/null: $!";
        open STDOUT, '>/dev/null' or die "Can't write
to /dev/null: $!";
        open STDERR, '>>/tmp/log'  or die "Can't write
to /tmp/log: $!";
        setsid                    or die "Can't start
a new session: $!";

        my $oldfh = select STDERR;
        local $| = 1;
        select $oldfh;

        # ends up in /tmp/log
        print STDERR "Where do the children [$$]
play?\n";

        # ends up nowhere
        warn "Where do the children [$$] play?\n";

        # do something time-consuming
        for (1..20) {
            sleep 1;
            warn "$_\n";
        }
        warn "completed $$\n";

        CORE::exit(0); # terminate the process
    }
-]
[-  $dbgLogLink = 0; -]
<html><head><body>
<xmp>[+ $output +]</xmp>
</body></html>
[# ENDSNIP #]


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Re: use of STDERR in forked children

Posted by "Andrew C. Stayart III" <ga...@theinventingmachines.com>.
I always keep separate logs for forked processes because i have no  
idea how to make that work flawlessly. but if you are really  
desperate, you could do something as bizarre as POSTing your log  
messages-from the forked process-to an apache process that simply  
echos the posted data to the apache error log.

you still end up eating an apache process (if you have keep alive on,  
if not, you take little bites out of all of them), but if your goal  
is simply to return the request to the user quickly and not bloat  
your apache memory footprint.....

c
a



On Jun 28, 2006, at 3:07 PM, Matthew Smith wrote:

> Hi,
>
> I originally posted this to the embperl listserv, but
> I haven't gotten any responses.  So maybe somebody
> here can help me. I hope!
>
> I'm working on a mechanism to fork a a long running
> child process.  I've followed the standard mod_perl
> forking wisdom in
> http://modperlbook.org/html/ch10_02.html.
>
> My issue is that warn() doesn't work in the child
> process, though printing directly to STDERR does.
>
> Also, I want STDERR to go to the apache log like it
> normally would, but I don't know how to determine what
> the path to the log is. I can't hard code it since it
> changes depending on the environment (dev vs. qa vs.
> prod).
>
> I haven't tried this using Apache::Registry (since we
> don't run it) but I thought it might be and Embperl
> thing since I couldn't find anything on the mod_perl
> lists...
>
> I'm using Apache 1.3 and Embperl 1.36
>
> Your help is greatly appreciated.
>
> Here's the code:
> [# SNIP #]
> [!
>     use POSIX 'setsid';
>     use Apache;
> !]
> [-
>     my $childPid = undef;
>     $SIG{CHLD} = 'IGNORE';
>
>     if ($childPid = fork) {
>         $output =  "Parent $$ has finished, kid's PID:
> $childPid\n";
>     }
>     else {
>         warn "starting child $$\n";
>         $req_rec->cleanup_for_exec( ); # untie the
> socket
>         chdir '/'                 or die "Can't chdir
> to /: $!";
>         open STDIN, '/dev/null'   or die "Can't read
> /dev/null: $!";
>         open STDOUT, '>/dev/null' or die "Can't write
> to /dev/null: $!";
>         open STDERR, '>>/tmp/log'  or die "Can't write
> to /tmp/log: $!";
>         setsid                    or die "Can't start
> a new session: $!";
>
>         my $oldfh = select STDERR;
>         local $| = 1;
>         select $oldfh;
>
>         # ends up in /tmp/log
>         print STDERR "Where do the children [$$]
> play?\n";
>
>         # ends up nowhere
>         warn "Where do the children [$$] play?\n";
>
>         # do something time-consuming
>         for (1..20) {
>             sleep 1;
>             warn "$_\n";
>         }
>         warn "completed $$\n";
>
>         CORE::exit(0); # terminate the process
>     }
> -]
> [-  $dbgLogLink = 0; -]
> <html><head><body>
> <xmp>[+ $output +]</xmp>
> </body></html>
> [# ENDSNIP #]
>
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com

-----------------------
"Yet, through the cryptic phrases and often mysterious arguments,  
there shines a love of knowledge and a passionate search for answers  
to questions that still preplex humanity"