Hi Ben,
> On Mon, May 03, 2004 at 11:38:05AM +0100, Ian Brockbank wrote:
> >  # Create a temporary directory for svn to work in.
> >  my $temp_dir = $ENV{TMPDIR};
> >  unless (defined $temp_dir and length $temp_dir) {
> > +  # Try the Windows standard environment variable
> > +  $temp_dir = $ENV{TEMP};
> > +}
> > +unless (defined $temp_dir and length $temp_dir) {
> >    $temp_dir = '/tmp';
> >  }
> 
> I'd prefer that we ditch this code entirely and ...
> 
> > +                # Write the value to a temporary file in case it's
> > multi-line
> > +                my ($handle, $tmpfile) = tempfile( DIR => 
> $temp_dir);
> > +                print $handle $property_value;
> > +                close($handle);
> 
> use TMPDIR => 1 instead of DIR => $temp_dir.  Doing this causes
> File::Temp to figure out the temp directory for us using File::Spec.
> Considering that File::Spec contains implementations for a variety of
> platforms not just Windows and Unix, this would end up being 
> a lot more
> portable...
Note that immediately after setting up $temp_dir with the name of the
system temporary directory, we use that in a call to tempdir and assign
the result back to $temp_dir (not particularly clean, but that's the way
the code was):
351: my $temp_template = "$temp_dir/svn_load_dirs_XXXXXXXXXX";
352: $temp_dir         = tempdir($temp_template);
The advantage of doing everything in $temp_dir is that it keeps
everything together and it's easy to clean up again (or not when
debugging).  The package Temp::Delete at the bottom of the file deletes
$temp_dir.
If we use TMPDIR => 1 on the call to tempdir which creates our initial
temporary directory that simplifies the code (I wasn't aware of that
parameter) - we can just do:
# Create a temporary directory for svn to work in.
my $temp_dir = tempdir( "svn_load_dirs_XXXXXXXXXX", TMPDIR => 1 );
Here's an updated patch:
Log message:
Get svn_load_dirs.pl working on Windows.
   * svn_load_dirs.pl.in
     (main code, setting up $temp_dir): Use TMPDIR => 1 in call
     to tempdir to pick up the system temporary directory portably.
     (main code, processing properties): Windows chokes on
     multi-line commands, caused (potentially) by properties.
     Write to a temporary file and use --file instead of passing
     the value.  This also requires use of File::Temp::tempfile().
     (safe_read_from_pipe): open(HANDLE, "-|"); doesn't work on
     Windows.  Replaced it with open(HANDLE, "@commandline |"); on
     Windows.  This also necessitates pre-processing the command
     line to protect it from the Windows shell, and passing
     comments via a temporary file using --file instead of -m.
Patch:
Index:
http://svn.collab.net/repos/svn/trunk/contrib/client-side/svn_load_dirs.
pl.in
===================================================================
---http://svn.collab.net/repos/svn/trunk/contrib/client-side/svn_load_di
rs.pl.in	(revision 9503)
+++http://svn.collab.net/repos/svn/trunk/contrib/client-side/svn_load_di
rs.pl.in	(working copy)
@@ -14,7 +14,7 @@
 use File::Copy   2.03;
 use File::Find;
 use File::Path   1.0404;
-use File::Temp   0.12   qw(tempdir);
+use File::Temp   0.12   qw(tempdir tempfile);
 use Getopt::Long 2.25;
 use Text::Wrap;
 use URI          1.17;
@@ -339,12 +339,7 @@
   }
 
 # Create a temporary directory for svn to work in.
-my $temp_dir = $ENV{TMPDIR};
-unless (defined $temp_dir and length $temp_dir) {
-  $temp_dir = '/tmp';
-}
-my $temp_template = "$temp_dir/svn_load_dirs_XXXXXXXXXX";
-$temp_dir         = tempdir($temp_template);
+my $temp_dir = tempdir( "svn_load_dirs_XXXXXXXXXX", TMPDIR => 1 );
 
 # Put in a signal handler to clean up any temporary directories.
 sub catch_signal {
@@ -1133,11 +1128,17 @@
                   {
                     @diff_ignore_space_changes = ('-b');
                   }
+                
+                # Write the value to a temporary file in case it's
multi-line
+                my ($handle, $tmpfile) = tempfile(DIR => $temp_dir);
+                print $handle $property_value;
+                close($handle);
 
                 read_from_process($svn,
                                   'propset',
                                   $property_name,
-                                  $property_value,
+                                  '--file',
+                                  $tmpfile,
                                   $add_file);
               }
           }
@@ -1411,25 +1412,74 @@
 }
 
 # Start a child process safely without using /bin/sh.
+my $openfork_available = "MSWin32" ne $OSNAME;
 sub safe_read_from_pipe
 {
   unless (@_)
     {
       croak "$0: safe_read_from_pipe $INCORRECT_NUMBER_OF_ARGS";
     }
-  print "Running @_\n";
-  my $pid = open(SAFE_READ, '-|');
-  unless (defined $pid)
+
+  if ($openfork_available)
     {
-      die "$0: cannot fork: $!\n";
+      print "Running @_\n";
+      my $pid = open(SAFE_READ, "-|");
+      unless (defined $pid)
+        {
+          die "$0: cannot fork: $!\n";
+        }
+      unless ($pid)
+        {
+          # child
+          open(STDERR, ">&STDOUT")
+            or die "$0: cannot dup STDOUT: $!\n";
+          exec(@_)
+            or die "$0: cannot exec '@_': $!\n";
+        }
     }
-  unless ($pid)
+  else
     {
-      open(STDERR, ">&STDOUT")
-        or die "$0: cannot dup STDOUT: $!\n";
-      exec(@_)
-        or die "$0: cannot exec '@_': $!\n";
-  }
+      # Redirect the comment into a temp file and use that to work
around
+      # Windoze's (non-)handling of multi-line commands.
+      my @commandline = ();
+      my $command;
+      my $comment;
+        
+      while ($command = shift)
+        {
+          if ("-m" eq $command)
+            {
+              my $comment = shift;
+              my ($handle, $tmpfile) = tempfile( DIR => $temp_dir);
+              print $handle $comment;
+              close($handle);
+                
+              push(@commandline, "--file");
+              push(@commandline, $tmpfile);
+            }
+          else
+            {
+              # Munge the command to protect it from the command line
+              $command =~ s/\"/\\\"/g;
+              if ($command =~ m"\s") { $command = "\"$command\""; }
+              if ($command eq "") { $command = "\"\""; }
+              if ($command =~ m"\n")
+                {
+                  warn "$0: carriage return detected in command - may
not work\n";
+                }
+              push(@commandline, $command);
+            }
+        }
+        
+      print "Running @commandline\n";
+      if ( $comment ) { print $comment; }
+        
+      # Now do the pipe.
+      open(SAFE_READ, "@commandline |")
+        or die "$0: cannot pipe to command: $!\n";
+    }
+    
+  # parent
   my @output;
   while (<SAFE_READ>)
     {
Ian Brockbank
Senior Applications Software Engineer
e: ian.brockbank@wolfsonmicro.com / apps@wolfsonmicro.com
scd: ian@scottishdance.net
t: +44 131 272 7145
f: +44 131 272 7001
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon May 10 13:11:27 2004