• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 477
  • Last Modified:

cgi script: background process keeping my script from finishing?

Hi all

I'm writing a "web power switch" for a set of applications, such that authorized users can visit a web page, and start or stop the application without having to log in to the server.  

However, the application takes a long time to start up, (so long, in fact, that a web query will time out if you wait for process to finish) so I tried to run it in the background:

system("mybigslowapp 2>&1 >/tmp/logfile  &");

This appears to allow my script to continue, but the page never seems to "finish" (The browser seems to be "waiting" for something, then eventually spits out an error message, saying the request timed out.  (The app _does_ start up correctly, its just the web page I'm having trouble with)  I also have this same script kill the app, and it works fine.

Am I correct in assuming that, in my current config,  "bigslowapp" will have to finish before my perl script will finish up?  How can I do this so it just spawns bigslowapp, and doesn't wait?

...If the points seem low for this question, speak up, I've got more :)
0
gmancuso
Asked:
gmancuso
1 Solution
 
gmancusoAuthor Commented:
other potentially relevant info:

I'm using CGI::standard for most of the html on the page
On submit, the script calls itself, and performs actions based on the existence of parameters
running on a solaris server, 2.6
0
 
Droby10Commented:
have you tried forking the script instead of running the process in the background...?
0
 
gmancusoAuthor Commented:
OK.. that's closer.. I changed the call to:

    unless(fork) {
      $SIG{INT} = 'IGNORE';  # c 'turn undead' zombies
       exec(" mybigslowapp 2>&1 > /tmp/log.web ");
       exit;  # This block only executes if we're the child, so exit when we're done.
    }

This works great from the command line, but the web page still won't finish.  I guess that means my problem may  not be with the background process, but with the buffers, maybe?  

Previously, the script (when called from command line) would wait until the system call was finished, then exit.  Now, the script returns immediately (this is good).  However, I'm still getting the same behavior from my web page (it's a little better, but still takes a minute or more to return.  I have tried changing $| =1; still the same results.  The script is actually making it to the end of the html page (I put a print() directly before the print end_html; line and it gets printed).  Why would I get different behavior from the web?  I test-run these scripts in the same environment, as the "web server user"
0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
gmancusoAuthor Commented:
I figured it out... a combination of cgi technicalities, and a typing mistake had me stumped.  The correct calling sequence is as follows:

    $SIG{INT} = 'IGNORE';  # c 'turn undead' zombies
    unless(fork) {
       open STDIN,  "</dev/null";
       open STDOUT, ">/dev/null";
       exec(" $startcmd > /tmp/log.web &");
       exit;  # This block only executes if we're the child, so exit when we're done.
    }


Points of interest:  

Not setting stdin & stdout to /dev/null caused most of my problems, as that actually created an error when the browser got tired of waiting for input it would never receive.   (Thanks to a Randal Swartz article in Web Techniques for pointing this out to me:   http://www.stonehenge.com/merlyn/WebTechniques/col20.html)

Even though I'm forking off a second process, I had to run the start command in the background (note the added &).  

I was incorrectly setting the SIGINT handler to ignore only in the child process.

Also during my search for answers I found that I'm probably using exec insecurely, and I should pass the parameters in separately (as a list? I can't remember now).  But that's a journey for another day.

Thanks to Droby10 for pointing me in the right direction...  I'm giving you a B for having the right answer, but leaving out a lot of details.

Thanks -G
0
 
Droby10Commented:
thanks, glad you got it all working...
0
 
bitsrfrCommented:
Needed the same functionality and it worked for me too...
0
 
BrimstarCommented:
It looks like this thread has helped at least three people.  Was just trying to implement the same thing and it's working quite nicely.  Thanks for the help!
0
 
enan0Commented:
Ok... I tryed but id didn't work for me. Anyway I make it work so I'm posting just if someone happen the same as me.
This was my code according to this article:

$::SIG{INT} = 'IGNORE';
unless(fork) {
  open STDIN,  "</dev/null";
  open STDOUT, ">/dev/null";
  exec("$script $dynparameter 2 > /tmp/ouch.log &");
  exit;  # This block only executes if we're the child, so exit when we're done.
}

And it didn't work. Then I try to play and look around newsgroups and i found some otherguy code, which just one difference with the one you have.... It has one extra line to redirect STDERR output also to /dev/null

so after: OPEN STDOUT, ">/dev/null";
it should go: OPEN STDERR, ">/dev/null";

at least  for me... now it works as wanted. Otherwise cgi keeps waiting for child to finish.
I'm using perl 5.8.0 under Redhat Linux 9.0.

c ya!

enan0
P.d: Anyone in hamburg? I'm quite bored and I don't know the language!
0
 
degaoCommented:
i got it to work... heres what i have..



#####################################

      $SIG{INT} = 'IGNORE';  # c 'turn undead' zombies
 
      if( !defined( $kidpid =fork()))
      {
        die "can't fork";
     
      }
      elsif( $kidpid == 0 )
      {

print << "EOD";
        <table width="640" border="0" bgcolor="#FFFFFF">
          <tr align="center" bgcolor="#FFFFFF">
            <td colspan="3">
              <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="center"><b><font face="Arial, Helvetica, sans-serif" size="5" color="#000000">Application
                    Listing by Registered Attorney</font><font face="Arial, Helvetica, sans-serif" size="4" color="#000000"><br>
                    Spreadsheet Generator</font></b></td>
                  <td width="150" align="right"><img src="ebc.gif" width="150" height="75"></td>
                </tr>
           
              </table> </td> </tr>
              <tr>
                <td>
                  Request is being Processed.  Please check your e-mail in few minutes.
                </td>
              </tr>
         </table>
EOD
 print $query->end_html;
   
    }
    else
    {
        open STDIN,  "</dev/null";
        open STDOUT, ">/dev/null";
        open STDERR, ">/dev/null";
        exec("perl $scriptName &");
        exit;  # This block only executes if we're the child, so exit when we're done.
       
   }


########################
0

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now