Solved

cgi script:  background process keeping my script from finishing?

Posted on 2001-08-31
9
466 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
 

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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

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…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

747 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now