User: sits    
  Date: 07/07/02 23:29:39

  Modified:    lib      Codestriker.pm
               lib/Codestriker/Repository Cvs.pm Subversion.pm
  Log:
  Using open3() simply doesn't work under mod_perl. Rework some of the external
  command calling to only use open3() under CGI, otherwise use regular open()
  under mod_perl.  We lose error strings using just open(), but at least it
  works.  Still a work in progress.
  
  
  
  Index: Codestriker.pm
  ===================================================================
  RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker.pm,v
  retrieving revision 1.98
  retrieving revision 1.99
  diff -u -r1.98 -r1.99
  --- Codestriker.pm    20 Aug 2006 07:11:21 -0000      1.98
  +++ Codestriker.pm    3 Jul 2007 06:29:37 -0000       1.99
  @@ -13,6 +13,7 @@
   use Encode;
   
   use Time::Local;
  +use IPC::Open3;
   
   # Export codestriker.conf configuration variables.
   use vars qw ( $mailhost $mailuser $mailpasswd $use_compression
  @@ -522,5 +523,73 @@
       return decode($Codestriker::topic_text_encoding, $string);
   }
   
  +# Function for running an external command, and handles the subtle
  +# issues for different web servers environments.
  +sub execute_command {
  +    my $stdout_fh = shift;
  +    my $stderr_fh = shift;
  +    my $command = shift;
  +    my @args = @_;
  +
  +    # Write error messages to STDERR if the file handle for error messages
  +    # is not defined.
  +    $stderr_fh = \*STDERR unless defined $stderr_fh;
  +
  +    if (exists $ENV{'MOD_PERL'}) {
  +     # The open3() call simply doesn't work under mod_perl/apache2,
  +     # so we need to use open() instead, which is a pain since we lose
  +     # error information.
  +     my $command_line = "\"$command\"";
  +     foreach my $arg (@args) {
  +         $command_line .= " \"$arg\"";
  +     }
  +     my $received_data = 0;
  +     if (open(COMMAND, "$command_line |")) {
  +         while (<COMMAND>) {
  +             print $stdout_fh $_;
  +             $received_data = 1;
  +         }
  +     }
  +     if (!$received_data) {
  +         print $stderr_fh "Command failed: $!\n";
  +         print $stderr_fh "$command_line\n";
  +         print $stderr_fh "Check your webserver error log for more 
information.\n";
  +     }
  +    } else {
  +     my $write_stdin_fh = new FileHandle;
  +     my $read_stdout_fh = new FileHandle;
  +     my $read_stderr_fh = new FileHandle;
  +
  +     # Open3 throws an exception on failure.
  +     eval {
  +         my $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
  +                         $command, @args);
  +
  +         # Ideally, we should use IO::Select, but that is broken on Win32.
  +         # This is not ideal, but read first from stdout.  If that is empty,
  +         # then an error has occurred, and that can be read from stderr.
  +         my $buf = "";
  +         while (read($read_stdout_fh, $buf, 16384)) {
  +             print $stdout_fh $buf;
  +         }
  +         while (read($read_stderr_fh, $buf, 16384)) {
  +             print $stderr_fh $buf;
  +         }
  +         
  +         # Wait for the process to terminate.
  +         waitpid($pid, 0);
  +     };
  +     if ($@) {
  +         print $stderr_fh "Command failed: [EMAIL PROTECTED]";
  +         print $stderr_fh "$command " . join(' ', @args) . "\n";
  +         print $stderr_fh "Check your webserver error log for more 
information.\n";
  +     }
  +    }
  +
  +    # Flush the output file handles.
  +    $stdout_fh->flush;
  +    $stderr_fh->flush;
  +}
  +
   1;
   
  
  
  
  
  
  Index: Cvs.pm
  ===================================================================
  RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Cvs.pm,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Cvs.pm    11 Jun 2006 08:40:38 -0000      1.6
  +++ Cvs.pm    3 Jul 2007 06:29:38 -0000       1.7
  @@ -11,7 +11,6 @@
   
   use strict;
   use FileHandle;
  -use IPC::Open3;
   
   # Factory method for creating a local CVS repository object.
   sub build_local {
  @@ -62,17 +61,30 @@
   
       # Open a pipe to the CVS repository.
       $ENV{'CVS_RSH'} = $Codestriker::ssh if defined $Codestriker::ssh;
  -    open(CVS, "\"$Codestriker::cvs\" -q -d \"" . $self->{url} .
  -      "\" co -p -r $revision \"$filename\" |")
  -     || die "Can't open connection to pserver CVS repository: $!";
   
  -    # Read the data.
  -    for (my $i = 1; <CVS>; $i++) {
  +    my $read_data;
  +    my $read_stdout_fh = new FileHandle;
  +    open($read_stdout_fh, '>', \$read_data) || die "Can't create in-memory 
fh: $!";
  +    my @args = ();
  +    push @args, '-q';
  +    push @args, '-d';
  +    push @args, $self->{url};
  +    push @args, 'co';
  +    push @args, '-p';
  +    push @args, '-r';
  +    push @args, $revision;
  +    push @args, $filename;
  +    Codestriker::execute_command($read_stdout_fh, undef,
  +                              $Codestriker::cvs, @args);
  +
  +    # Process the data for the topic.
  +    open($read_stdout_fh, '<', \$read_data) || die "Can't create in-memory 
fh: $!";
  +    for (my $i = 1; <$read_stdout_fh>; $i++) {
        $_ = Codestriker::decode_topic_text($_);
        chop;
        $$content_array_ref[$i] = $_;
       }
  -    close CVS;
  +    close $read_stdout_fh;
   }
   
   # Retrieve the "root" of this repository.
  @@ -117,33 +129,12 @@
       # Cheat - having two '-u's changes nothing.
       my $extra_options = $default_to_head ? '-u' : '-f';
   
  -    my $write_stdin_fh = new FileHandle;
  -    my $read_stdout_fh = new FileHandle;
  -    my $read_stderr_fh = new FileHandle;
       $ENV{'CVS_RSH'} = $Codestriker::ssh if defined $Codestriker::ssh;
  -    my $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
  -                 $Codestriker::cvs, '-q', '-d', $self->{url},
  -                 'rdiff', $extra_options, '-u', 
  -                 '-r', $start_tag, '-r', $end_tag, $module_name);
  -
  -    # Ideally, we should use IO::Select, but that is broken on Win32.
  -    # With CVS, read first from stdout.  If that is empty, then an
  -    # error has occurred, and that can be read from stderr.
  -    my $buf = "";
  -    while (read($read_stdout_fh, $buf, 16384)) {
  -     print $stdout_fh $buf;
  -    }
  -    while (read($read_stderr_fh, $buf, 16384)) {
  -     print $stderr_fh $buf;
  -    }
  -
  -    # Wait for the process to terminate.
  -    waitpid($pid, 0);
  -
  -    # Flush the output file handles.
  -    $stdout_fh->flush;
  -    $stderr_fh->flush;
   
  +    Codestriker::execute_command($stdout_fh, $stderr_fh, $Codestriker::cvs,
  +                              '-q', '-d', $self->{url}, 'rdiff',
  +                              $extra_options, '-u', '-r', $start_tag,
  +                              '-r', $end_tag, $module_name);
       return $Codestriker::OK;
   }
   
  
  
  
  
  
  Index: Subversion.pm
  ===================================================================
  RCS file: 
/cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Subversion.pm,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Subversion.pm     7 Mar 2007 03:03:40 -0000       1.15
  +++ Subversion.pm     3 Jul 2007 06:29:38 -0000       1.16
  @@ -48,10 +48,9 @@
       # Replace any spaces with %20 uri friendly escapes.
       $filename =~ s/ /%20/g;
   
  -    my $write_stdin_fh = new FileHandle;
  +    my $read_data;
       my $read_stdout_fh = new FileHandle;
  -    my $read_stderr_fh = new FileHandle;
  -
  +    open($read_stdout_fh, '>', \$read_data) || die "Can't create in-memory 
fh: $!";
       my @args = ();
       push @args, 'cat';
       push @args, '--non-interactive';
  @@ -60,28 +59,16 @@
       push @args, '--revision';
       push @args, $revision;
       push @args, $self->{repository_url} . '/' . $filename;
  -    
  -    my $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
  -                 $Codestriker::svn, @args);
  +    Codestriker::execute_command($read_stdout_fh, undef,
  +                              $Codestriker::svn, @args);
   
  -    # Read the data.
  +    # Process the data for the topic.
  +    open($read_stdout_fh, '<', \$read_data) || die "Can't create in-memory 
fh: $!";
       for (my $i = 1; <$read_stdout_fh>; $i++) {
        $_ = Codestriker::decode_topic_text($_);
        chop;
        $$content_array_ref[$i] = $_;
       }
  -
  -    # Log anything on standard error to apache error log.
  -    my $buf;
  -    my $first_lines = 1;
  -    while (read($read_stderr_fh, $buf, 16384)) {
  -        print STDERR "$Codestriker::svn " .
  -         (join @args, ' ') . "\n" if $first_lines;
  -        $first_lines = 0;
  -     print STDERR $buf;
  -     }
  -      
  -    waitpid($pid, 0);
   }
   
   # Retrieve the "root" of this repository.
  @@ -138,6 +125,11 @@
   
       my $directory;
   
  +    # TODO: need a better way of detecting this, since Chinese users
  +    # receive a different output string.  svn info might be better,
  +    # it can tell you if it is a file or directory.
  +    # svn propget svn:mime-type could be a way.
  +
       # If there is an error about it being a directory, then use the
       # module name as a directory.
       while(<$read_stderr_fh>) {
  
  
  

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Codestriker-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/codestriker-commits

Reply via email to