Changeset 17354

Show
Ignore:
Timestamp:
23.09.2008 15:42:47 (11 years ago)
Author:
ak19
Message:

Added SIGTERM and SIGINT handlers to terminate wget child process either when a Ctrl-C (SIGINT) is send to the perl script run from the command-line, or when the java parent process kills this perl script using Process.destroy (which sends a SIGTERM). This code works on Linux. Need to test on Windows (although something similar did not seem to work before on Windows).

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • gsdl/trunk/perllib/downloaders/WgetDownload.pm

    r17207 r17354  
    7575 
    7676 
     77# Declaring variables related to the wget child process so that the termination 
     78# signal handler for SIGTERM can close the streams and tidy up before ending 
     79# the child process. 
     80my $childpid; 
     81my($chld_out, $chld_in); 
     82 
     83# Handler called when this process is killed or abruptly ends due to receiving 
     84# one of the terminating signals that this handler is registered to deal with. 
     85sub abrupt_end_handler { 
     86    my $termination_signal = shift (@_); 
     87    { 
     88    if(defined $childpid) { 
     89        close($chld_out); 
     90        close($chld_in); 
     91     
     92        # Send TERM signal to child process to terminate it. Sending the INT signal didn't work 
     93        # See http://perldoc.perl.org/perlipc.html#Signals  
     94        # Warning on using kill at http://perldoc.perl.org/perlfork.html 
     95        kill("TERM", $childpid);  
     96    } 
     97    } 
     98    exit(0); 
     99} 
     100 
     101# Registering a handler for when termination signals SIGINT and SIGTERM are received to stop 
     102# the wget child process. SIGTERM--generated by Java's Process.destroy()--is the default kill 
     103# signal (kill -15) on Linux, while SIGINT is generated upon Ctrl-C (also on Windows).  
     104# Note that SIGKILL can't be handled as the handler won't get called for it. More information:  
     105# http://affy.blogspot.com/p5be/ch13.htm 
     106# http://perldoc.perl.org/perlipc.html#Signals 
     107$SIG{'INT'} = \&abrupt_end_handler; 
     108$SIG{'TERM'} = \&abrupt_end_handler; 
     109 
    77110sub new { 
    78111    my ($class) = shift (@_); 
     
    147180    } 
    148181    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget"); 
    149     $command = "\"$wget_file_path\" $cmdWget |"; 
    150  
    151     open(*WIN,$command) || die "wget request failed: $!\n"; 
    152  
    153     while (defined($strLine=<WIN>)) 
     182    #$command = "\"$wget_file_path\" $cmdWget |";    #open(*WIN,$command) || die "wget request failed: $!\n"; 
     183    #open(*WIN,$command) || die "wget request failed: $!\n";     
     184 
     185 
     186    $command = "\"$wget_file_path\" $cmdWget"; 
     187    $childpid = open2($chld_out, $chld_in, $command) || die "wget request failed: $!\n"; 
     188 
     189    while (defined($strLine=<$chld_out>)) # we're reading in from child process' stdout 
    154190    { 
    155191    if($blnShow) 
     
    160196    $strReadIn .= $strLine; 
    161197    } 
    162  
    163     close(WIN); 
     198     
     199    close($chld_in); 
     200    close($chld_out); 
     201     
     202    # Program terminates only when the following line is included  
     203    # http://perldoc.perl.org/IPC/Open2.html explains why this is necessary 
     204    # it prevents the child from turning into a "zombie process". 
     205    # While the wget process terminates without it, this perl script does not:  
     206    # the DOS prompt is not returned without it. 
     207    waitpid $childpid, 0; 
     208 
    164209    if ($changed_dir) { 
    165210    chdir $current_dir; 
     
    182227    } 
    183228    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget"); 
    184     my $command = "\"$wget_file_path\" $cmdWget 2>&1 |"; 
    185  
     229    #my $command = "\"$wget_file_path\" $cmdWget 2>&1 |"; #open(*WIN,$command) || die "wget request failed: $!\n"; 
    186230###    print STDERR "**** wget cmd = $command\n"; 
    187  
    188     open(*WIN,$command) || die "wget request failed: $!\n"; 
     231    #open(*WIN,$command) || die "wget request failed: $!\n"; 
     232 
     233    my $command = "\"$wget_file_path\" $cmdWget"; 
     234    $childpid = open2($chld_out, $chld_in, $command) || die "wget request failed: $!\n"; 
    189235 
    190236    my $full_text = ""; 
     
    193239    my $line; 
    194240 
    195     while (defined($line=<WIN>)) 
     241    while (defined($line=<$chld_out>)) # we're reading in from child process' stdout 
    196242    { 
    197243    if((defined $blnShow) && $blnShow) 
     
    212258    } 
    213259 
    214     close(WIN); 
     260    close($chld_in); 
     261    close($chld_out); 
     262 
     263    # Program terminates only when the following line is included  
     264    # http://perldoc.perl.org/IPC/Open2.html explains why this is necessary 
     265    # it prevents the child from turning into a "zombie process". 
     266    # While the wget process terminates without it, this perl script does not:  
     267    # the DOS prompt is not returned without it. 
     268    waitpid $childpid, 0; 
    215269 
    216270    my $command_status = $?;