Solved

cgi script:  background process keeping my script from finishing?

Posted on 2001-08-31
9
470 Views
Last Modified: 2008-03-17
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
Comment
Question by:gmancuso
9 Comments
 

Author Comment

by:gmancuso
ID: 6446748
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
 
LVL 5

Accepted Solution

by:
Droby10 earned 100 total points
ID: 6447537
have you tried forking the script instead of running the process in the background...?
0
 

Author Comment

by:gmancuso
ID: 6454073
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
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 

Author Comment

by:gmancuso
ID: 6464795
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
 
LVL 5

Expert Comment

by:Droby10
ID: 6466789
thanks, glad you got it all working...
0
 

Expert Comment

by:bitsrfr
ID: 6997313
Needed the same functionality and it worked for me too...
0
 

Expert Comment

by:Brimstar
ID: 8766104
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
 

Expert Comment

by:enan0
ID: 8998595
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
 

Expert Comment

by:degao
ID: 9082039
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question