Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Correct way to run a shell command from mod_perl2? (Child process segmentation fault)

by repellent (Priest)
on Jan 03, 2012 at 00:49 UTC ( [id://945987]=note: print w/replies, xml ) Need Help??


in reply to Correct way to run a shell command from mod_perl2? (Child process segmentation fault) -- SOLVED!

Looking at the "Complete Fork Example" (OP bullet 1) outlined in Practical mod_perl, it reminds me of code to daemonize a forked process. You know, set a new session, be a process group leader, close file descriptors, chdir /, yada yada Richard Stevens yada, etc. Perhaps that will cut the umbilical cord of the child from the main Apache process.

Try this example:
my $pid = open(my $FROM_KID, "-|"); die("Failed fork: $!") unless defined($pid); if ($pid) # parent { chomp(my $output = do { local $/; <$FROM_KID> }); waitpid($pid, 0); printf <<'RESULT', $output, $? >> 8; Child output: %s Exit: %d RESULT } else { daemonize_self("", undef); # leave stdout alone exec "date" or die("Failed exec: $!"); }

Now for the code of daemonize_self():
use Cwd (); use POSIX (); use File::Spec; sub daemonize_self { my ($stdout_log, $stderr_log) = @_; # new session & process group leader, and no controlling tty die("daemonize_self: Cannot detach from controlling tty") if POSIX::setsid() < 0; # ignore signals for my $s (qw(INT HUP TTIN TTOU TSTP)) { $SIG{$s} = sub { }; # not "IGNORE", not inherited } $SIG{CHLD} = "IGNORE"; # inherited default to reap kids $SIG{TERM} = "DEFAULT"; # be lenient: redirect stdin, stdout, stderr my $DEVNULL = File::Spec->devnull(); open(*STDIN, "<", $DEVNULL) or die("daemonize_self: Cannot silence STDIN", "\n ", $!); unless (defined($stdout_log) && $stdout_log eq "") { open(*STDOUT, ">>", defined($stdout_log) ? $stdout_log : $DEVN +ULL) or die("daemonize_self: Cannot redirect STDOUT", "\n ", $!) +; } unless (defined($stderr_log) && $stderr_log eq "") { open(*STDERR, ">>", defined($stderr_log) ? $stderr_log : $DEVN +ULL) or die("daemonize_self: Cannot redirect STDERR", "\n ", $!) +; } # close all other file descriptors POSIX::close($_) for 3 .. 1024; # reset file creation mask umask 0; # change current working dir to root chdir(File::Spec->rootdir()); }
  • Comment on Re: Correct way to run a shell command from mod_perl2? (Child process segmentation fault)
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Correct way to run a shell command from mod_perl2? (Child process segmentation fault)
by dbooth (Novice) on Jan 03, 2012 at 03:03 UTC

    I tried something along the lines of #1 and #2 and it still causes an Apache2 child segmentation fault after a few successful requests. Here is the code I used:

    sub RunCommand { my $pgm = shift; my @execargs = @_; $SIG{CHLD} = 'IGNORE'; # This should flush stdout. my $ofh = select(STDOUT);$| = 1;select $ofh; warn "Before first fork $$"; my $kpid = fork; defined($kpid) || die; if ($kpid) { # Parent process my $w = waitpid($kpid, 0); # warn "waitpid returned $w\n"; } else { close STDIN; close STDOUT; close STDERR; setsid() >= 0 or die; my $gpid = fork; defined($gpid) or die; if ($gpid) { my $w = waitpid($gpid, 0); # warn "waitpid returned $w\n"; } else { open(STDIN, "</dev/null") or die; open(STDOUT, ">/dev/null") or die; open(STDERR, ">/dev/null") or die; # Child process exec($pgm, @execargs) or die; } CORE::exit(0); } }

    I invoked that function from within my mod_perl2 response handler as:

    &RunCommand("/home/dbooth/rdf-pipeline/trunk/pid.perl");

    The pid.perl command I ran uses no stdin, stdout or stderr, but merely logs its PID and date to /tmp/pid.txt:

    #! /usr/bin/perl -w # Append the PID and date/time to /tmp/pid.txt # so that we can verify that this ran. use HTTP::Date; my $tmp = "/tmp/pid.txt"; open(my $fh, ">>$tmp") or die; my $t = time2str(time); print $fh "pid: $$ $t\n"; close $fh or die; exit 0;

    P.S. See also the update to my original post, in which I note that this command still runs successfully during the HTTP request in which the Apache2 child process dies from a segmentation fault.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://945987]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-16 05:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found