Home > Archive > PERL Miscellaneous > February 2005 > CGI System Call in perl
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
CGI System Call in perl
|
|
| ganchrow 2005-02-16, 4:00 pm |
| I have a CGI script written Perl, the only function of which, is to
start a Perl Daemon. My OS is Red Hat. Here's the pseudo code:
---------------------------------------
#!/usr/local/bin/perl
# run under Red Hat
print "Content-Type: text/html\n\n<body>";
print "BEGIN PAGE<BR>\n";
if (system("perl $CMD_WHICH_STARTS_OTHER_PERL_SCRIPT &")) {
print "Program not started: $!<BR>\n";
} else {
print "Program started.<BR>\n";
}
print "END PAGE<BR>\n";
print "</body>";
---------------------------------------
Now the problem is that even though the new process succesfully starts
in the background, the CGI does not terminate -- the page still shows
as "loading" in the web browser and running "ps -x" at a command prompt
shows that the cgi process is running as a zombie process.
Any idea what I can so that once the final line of the CGI script is
reached the program terminates (with the spawned process continuing
until it dies of its own natural causes)?
Many Thanks,
GANCH.
| |
| Brian McCauley 2005-02-16, 4:00 pm |
|
ganchrow wrote:
> I have a CGI script written Perl, the only function of which, is to
> start a Perl Daemon. My OS is Red Hat. Here's the pseudo code:
>
> ---------------------------------------
> #!/usr/local/bin/perl
>
> # run under Red Hat
> print "Content-Type: text/html\n\n<body>";
> print "BEGIN PAGE<BR>\n";
> if (system("perl $CMD_WHICH_STARTS_OTHER_PERL_SCRIPT &")) {
> print "Program not started: $!<BR>\n";
> } else {
> print "Program started.<BR>\n";
> }
> print "END PAGE<BR>\n";
> print "</body>";
> ---------------------------------------
>
> Now the problem is that even though the new process succesfully starts
> in the background, the CGI does not terminate -- the page still shows
> as "loading" in the web browser and running "ps -x" at a command prompt
> shows that the cgi process is running as a zombie process.
When a web server lauches a CGI subprocess it directs the CGI process's
STDOUT to a pipe and reads from that pipe until it gets an EOF condition.
If the CGI process want's to fork-off-and-die so that it can continue in
the background it needs to close or reopen STDOUT in the child.
This, of course, has nothing to do with Perl.
| |
| ganchrow 2005-02-16, 4:00 pm |
| Yeah, I was kind of afraid this wasn't at heart really a Perl question.
Thanks for your help, though.
| |
| Gregory Toomey 2005-02-16, 4:00 pm |
| ganchrow wrote:
> I have a CGI script written Perl, the only function of which, is to
> start a Perl Daemon. My OS is Red Hat. Here's the pseudo code:
>
> ---------------------------------------
> #!/usr/local/bin/perl
>
> # run under Red Hat
> print "Content-Type: text/html\n\n<body>";
> print "BEGIN PAGE<BR>\n";
> if (system("perl $CMD_WHICH_STARTS_OTHER_PERL_SCRIPT &")) {
> print "Program not started: $!<BR>\n";
> } else {
> print "Program started.<BR>\n";
> }
> print "END PAGE<BR>\n";
> print "</body>";
> ---------------------------------------
>
> Now the problem is that even though the new process succesfully starts
> in the background, the CGI does not terminate -- the page still shows
> as "loading" in the web browser and running "ps -x" at a command prompt
> shows that the cgi process is running as a zombie process.
>
> Any idea what I can so that once the final line of the CGI script is
> reached the program terminates (with the spawned process continuing
> until it dies of its own natural causes)?
>
> Many Thanks,
> GANCH.
You need to completely separate parent from child. Call the following at
start of child (works with Redhat 9).
use POSIX 'setsid';
sub daemonize {
# 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: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
}
gtoomey
| |
| Ganchrow Harris Peck 2005-02-28, 3:58 pm |
| Thanks for your reply, Greg. For my purposes the following BEGIN block
added to my child process worked just fine:
# start code sample
BEGIN {
if ( (defined $ARGV[0]) and ($ARGV[0] =~ m/-?cgi$/i) ) {
# program was called from cgi script
# so close out out buffer to let cgi script terminate
close STDOUT;
}
}
# end code sample
Of course this necessitated both being able to call the child from the
parent with the -cgi switch as the first arg and furthermore not caring
that any data sent to STDOUT by the child would be discarded.
Worked fine even if inelegantly.
GHP.
|
|
|
|
|