For Programmers: Free Programming Magazines  


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.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com