Changeset 17354


Ignore:
Timestamp:
2008-09-23T15:42:47+12:00 (16 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).

File:
1 edited

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 = $?;
Note: See TracChangeset for help on using the changeset viewer.