Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Long Process through CGI and issue with $PATH

by sara2005 (Scribe)
on Jul 15, 2006 at 00:24 UTC ( [id://561374] : perlquestion . print w/replies, xml ) Need Help??

sara2005 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

Sometime back, I had posted a query regarding Issue with executing long process through CGI and had asked for help.

I was clueless then as to why the browser was going blank or exiting with a success status immediately (without executing the exec command in the script!!!) but now I have figured out that the PATH env variable is the one that is causing the issue.

i.e. If $PATH is set properly, then the script executes the command and returns the results.

But, if $PATH is not correct, then the script sets

$data->[0] (line no 61)

and enters the loop

if (my $session = param('session')) (line no 7)

immediately and stalls (or exits )

I set some softlinks and then define the PATH during runtime for the script. Hence, this has become an issue if one of the links is not set properly.

Although I can somehow manage this issue by making sure that the proper links are set in the first place, I am curious as to why this is happening. Unfortunately, I don't know how to proceed further to find the rootcause of this problem.

Looking forward for some help to check this further

Replies are listed 'Best First'.
Re: Long Process through CGI and issue with $PATH
by chromatic (Archbishop) on Jul 15, 2006 at 00:56 UTC

    It's difficult to say without seeing the shell script you're running, but may I guess that it uses relative paths to binaries that should be in $PATH normally? Without the right values in that environment variable, the shell will not be able to find the commands.

      To simplify the issue, I have removed the shell script and replaced it with a sleep command, which would be my long process. Below is the updated code that executes a 'sleep' command.

      0 $ENV{PATH} = "/bin:"; 1 use CGI qw(:all delete_all escapeHTML); 2 3 my $redirect_page = "display_page.cgi"; 4 5 # The execution enters this loop in the first pass whereas 6 it shou +ld not!!! 7 if (my $session = param('session')) { # returning to pick 8 up sessi +on data 9 my $cache = get_cache_handle(); 10 my $data = $cache->get($session); 11 unless ($data and ref $data eq "ARRAY") { # something is wrong 12 show_form(); 13 exit 0; 14 } 15 print header; 16 if ( $data->[0] ){ 17 print start_html(-title=>'Sleep Results Done',-bgcolor=>'white'); 18 # Checking.... print $session and $data->[0] to screen 20 print h2("$session"); 21 print h2("$data->[0]"); 22 # End of checking 23 print start_form(-name=>'data',-action=>$redirect_page); 24 print end_form(); 25 print script("setTimeout(\";\",2000);"); 26 } 27 else{ 28 print start_html(-title => "Sleep Results", 29 ($data->[0] ? () : 30 (-head => ["<meta http-equiv=refresh content=5>" +]))); 31 print h1("Sleep Results"); 32 print pre(escapeHTML($data->[0])); 33 print pre(escapeHTML($data->[1])); 34 print p(i("... continuing ...")) unless $data->[0]; 35 36 } 37 print end_html; 38 } 39 elsif ( (my $slp = param('sleep')) eq 'sleep') { 40 my $session = get_session_id(); 41 my $cache = get_cache_handle(); 42 $cache->set($session, [0, ""]); # no data yet 43 44 if (my $pid = fork) { # parent does 45 delete_all(); # clear parameters 46 param('session', $session); 47 print redirect(self_url()); 48 } 49 elsif (defined $pid) { # child does 50 close STDOUT; # so parent can go on 51 unless (open F, "-|") { 52 open STDERR, ">&=1"; 53 exec "sleep","120"; 54 die "Cannot execute Sleep: $!"; 55 } 56 my $buf = ""; 57 while (<F>) { 58 $buf .= $_; 59 $cache->set($session, [0, $buf]); 60 } 61 $cache->set($session, [1, $buf]); 62 exit 0; 63 } 64 else { 65 die "Cannot fork: $!"; 66 } 67 } 68 else { # display form 69 show_form(); 70 } 71 72 exit 0; sub show_form { print header, start_html("Sleep"), h1("Sleep"); print start_form; #print submit('traceroute to this host:'), " ", textfield('host'); print submit('Run Sleep Process:'), " ", textfield('sleep'); print end_form, end_html; } sub get_cache_handle { require Cache::FileCache; Cache::FileCache->new ({ namespace => 'sleep', username => 'sara2005', default_expires_in => '30 minutes', auto_purge_interval => '4 hours', }); } sub get_session_id { require Digest::MD5; Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().$$)); }

      If $ENV{PATH} is defined (line 0) in the perl script, the code works fine but if $ENV{PATH} is removed, everything goes weird. All the browser returns is a blank screen!!!!!

      Any thoughts?

        I have encountered a similar problem and attribute itto some manner of locking or race issue between the two processes using Cache::FileCache. Preliminary investigation indicates that CGI::Session may manage the situation better. It is certinally easier to use because it generates the session ID for you.

        It is importnt to call flush () whenever you want to push data from the long running process back to the monitoring process however.

        How poking at PATH could alter things I have no idea however!

        DWIM is Perl's answer to Gödel