Changeset 17840 for gsdl/trunk


Ignore:
Timestamp:
2008-11-12T16:18:25+13:00 (15 years ago)
Author:
ak19
Message:

Terminating Wget: Removed last commit's temporary fix. Now this code has gone back to using open3 since that works on both Linux and Windows, avoids the use of 2>&1 (since that launches a subshell on Linux which becomes the perl script's subprocess rather than the wget we're monitoring in order to terminate it). Wget's output is to STDERR which is what we need to monitor and we do that with open3--although the wget output when using open3 comes into its stdout handle instead. But since we are only using one of the two outputstreams of wget, we use the same handle for both and this means the need for extra stream handle variables and the need to close them is now gone.

File:
1 edited

Legend:

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

    r17800 r17840  
    3535use strict;
    3636use Cwd;
    37 use IPC::Open2;
     37use IPC::Open3;
    3838use IO::Select;
    3939use IO::Socket;
     
    199199}
    200200
    201 sub get_childpid {
    202     my ($self, $pid) = @_;
    203     my $os = $^O;
    204     # for windows, we do nothing special
    205     if ($os =~ m/mswin/i) {
    206     return $pid;
    207     }
    208    
    209     # else $os is macos or linux
    210     # This means the wget child process may have been spawned from a subshell
    211     # (the real child) that was launched by this perl script. However, we want
    212     # the pid of the wget process, since that is what we want to terminate.
    213 
    214     sleep(2); # give it some time to start up, else we'd have finished searching beforehand
    215 
    216     # Look through any processes spawned immediately/soon after the subshell.
    217     # Look for any pid greater than the subshell's, but within a certain limit (10)
    218     my $child = $pid;
    219     for(my $i = 1; $i <= 10; $i++) {
    220     $child = $child+$i;
    221     if(kill(0, $child)) { # this process exists
    222         return $child;
    223     }
    224     }
    225    
    226     return $pid; # could not find any process within limit, so return the original process id?
    227 }
    228201
    229202sub useWget
     
    266239
    267240    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
    268     $command = "\"$wget_file_path\" $cmdWget 2>&1";
    269     # print STDERR "Command is: $command\n";
    270     $childpid = open2($chld_out, $chld_in, $command) || die "wget request failed: $!\n";
    271    
    272     # for linux the wget process starts off as achild of a subshell launched as the child of
    273     # this perl script. We want the pid of the wget process, not that of the subshell.
    274     $childpid = $self->get_childpid($childpid);
     241    $command = "\"$wget_file_path\" $cmdWget";
     242    #print STDOUT "Command is: $command\n";
     243
     244    # Wget's output needs to be monitored to find out when it has naturally termianted.
     245    # Wget's output is sent to its STDERR so we can't use open2 without doing 2>&1.
     246    # On linux, 2>&1 launches a subshell which then launches wget, meaning that killing
     247    # the childpid does not kill wget on Linux but the subshell that launched it instead.
     248    # Therefore, we use open3. Though the child process wget sends output only to its stdout,
     249    # using open3 says chld_err is undefined and the output of wget only comes in chld_out(!)
     250    # However that may be, it works with open3. But to avoid the confusion of managing and
     251    # closing an extra unused handle, a single handle is used instead for both the child's
     252    # stderr and stdout.
     253
     254    # Both open2 and open3 don't return on failure, but raise an exception. The handling
     255    # of the exception is described on p.568 of the Perl Cookbook
     256    eval {
     257    $childpid = open3($chld_in, $chld_out, $chld_out, $command);
     258    };
     259    if ($@) {
     260    if($@ =~ m/^open3/) {
     261        die "open3 failed in $0: $!\n$@\n";     
     262    }
     263    die "Tried to launch open3 in $0, got unexpected exception: $@";
     264    }
    275265
    276266    my $loop = 1;
     
    341331                close($rh);             #close($serverSocket);
    342332                print $client "Perl terminated wget and is about to exit\n";
     333                last;                           # out of inner for loop
    343334            }
    344335            else { # the process may just be starting up, wait
    345336                sleep(1);
    346337            }
    347             last;                           # out of inner for loop
    348338            }
    349339            last;                               # out of foreach loop
     
    398388
    399389    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
    400     #my $command = "\"$wget_file_path\" $cmdWget 2>&1 |"; #open(*WIN,$command) || die "wget request failed: $!\n";
    401     my $command = "\"$wget_file_path\" $cmdWget 2>&1";
    402     # print STDERR "Command is: $command\n";
    403     $childpid = open2($chld_out, $chld_in, $command) || die "wget request failed: $!\n";
    404 
    405     # for linux the wget process starts off as achild of a subshell launched as the child of
    406     # this perl script. We want the pid of the wget process, not that of the subshell.
    407     $childpid = $self->get_childpid($childpid);
     390    my $command = "\"$wget_file_path\" $cmdWget";
     391    #print STDOUT "Command is: $command\n";
     392
     393    eval {     # see p.568 of Perl Cookbook
     394    $childpid = open3($chld_in, $chld_out, $chld_out, $command);
     395    };
     396    if ($@) {
     397    if($@ =~ m/^open3/) {
     398        die "open3 failed in $0: $!\n$@\n";     
     399    }
     400    die "Tried to launch open3 in $0, got unexpected exception: $@";
     401    }
    408402
    409403    my $full_text = "";
     
    495489                close($rh);             #close($serverSocket);
    496490                print $client "Perl terminated wget and is about to exit\n";
     491                last;                           # out of inner for loop
    497492            }
    498493            else { # the process may just be starting up, wait
    499494                sleep(1);
    500495            }
    501             last;                           # out of inner for loop
    502496            }
    503497            last;                               # out of foreach loop
Note: See TracChangeset for help on using the changeset viewer.