subversion-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matthias Buecher / Germany <mad...@maddes.net>
Subject [bug] check-mime-type.pl: Windows Support
Date Sun, 08 Jan 2017 00:57:08 GMT
Dear all,

the hook-script check-mime-type.pl [A] doesn't work on the Windows
platform as Windows does not support openfork.
Additionally files/paths with spaces have to be put in quotes.
Plus getting the temp dir should be left to the related Perl functions.
 [A]
https://svn.apache.org/viewvc/subversion/trunk/contrib/hook-scripts/check-mime-type.pl

I'm using the attached patch for several years now without any issues
(also directly in this mail below).

I want to file this as an issue (patch) and want to make sure that
everything is fine with this and my patch.

[[[
Enhance platform support of hook script check-mime-type.pl for Windows
Adopted from contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
(r1295006) [1]

* contrib/hook-scripts/check-mime-type.pl:
  (tmp_dir) Cross Platform: sane temp dir creation via File::Temp
            function tempdir()
  (sub safe_read_from_pipe) Windows/DOS: does not support openfork and
                            files/paths with spaces have to be put in quotes

Patch by: Matthias B├╝cher <maddes+subversion@maddes.net>

[1]
https://svn.apache.org/viewvc/subversion/trunk/contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
[2] http://perldoc.perl.org/perlport.html#Interprocess-Communication-(IPC)
[3] http://perldoc.perl.org/perlport.html#PLATFORMS

]]]

Kind regards
Maddes


Index: contrib/hook-scripts/check-mime-type.pl
===================================================================
--- contrib/hook-scripts/check-mime-type.pl    (revision 1777854)
+++ contrib/hook-scripts/check-mime-type.pl    (working copy)
@@ -1,18 +1,19 @@
 #!/usr/bin/env perl
 
 # ====================================================================
-# commit-mime-type-check.pl: check that every added file has the
+# check-mime-type.pl: check that every added file has the
 # svn:mime-type property set and every added file with a mime-type
 # matching text/* also has svn:eol-style set. If any file fails this
 # test the user is sent a verbose error message suggesting solutions and
 # the commit is aborted.
 #
-# Usage: commit-mime-type-check.pl REPOS TXN-NAME
+# Usage: check-mime-type.pl REPOS TXN-NAME
 # ====================================================================
-# Most of commit-mime-type-check.pl was taken from
+# Most of check-mime-type.pl was taken from
 # commit-access-control.pl, Revision 9986, 2004-06-14 16:29:22 -0400.
 # ====================================================================
 # Copyright (c) 2000-2004 CollabNet.  All rights reserved.
+# Copyright (c) 2014-2017 Apache Software Foundation (ASF).
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution.  The terms
@@ -25,6 +26,15 @@
 # history and logs, available at http://subversion.tigris.org/.
 # ====================================================================
 
+use strict;
+use Carp;
+use Cwd;
+use File::Temp  qw(tempdir tempfile);
+
+my $old_dir;
+my $os_windows = $^O eq 'MSWin32';
+my $os_dos = $^O eq 'dos';
+
 # Turn on warnings the best way depending on the Perl version.
 BEGIN {
   if ( $] >= 5.006_000)
@@ -31,10 +41,13 @@ BEGIN {
     { require warnings; import warnings; }
   else
     { $^W = 1; }
+
+  $old_dir = getcwd;
 }
 
-use strict;
-use Carp;
+END {
+  chdir($old_dir);
+}
 
 
 ######################################################################
@@ -94,9 +107,9 @@ sub ACCESS_READ_WRITE () { 'read-write' }
 ######################################################################
 # Harvest data using svnlook.
 
-# Change into /tmp so that svnlook diff can create its .svnlook
+# Change into temp dir so that svnlook diff can create its .svnlook
 # directory.
-my $tmp_dir = '/tmp';
+my $tmp_dir = tempdir( TMPDIR => 1, CLEANUP => 1 );
 chdir($tmp_dir)
   or die "$0: cannot chdir `$tmp_dir': $!\n";
 
@@ -211,6 +224,7 @@ sub usage
   die "usage: $0 REPOS TXN-NAME\n";
 }
 
+# Start a child process safely without using a shell
 sub safe_read_from_pipe
 {
   unless (@_)
@@ -217,19 +231,68 @@ sub safe_read_from_pipe
     {
       croak "$0: safe_read_from_pipe passed no arguments.\n";
     }
-  print "Running @_\n";
-  my $pid = open(SAFE_READ, '-|', @_);
-  unless (defined $pid)
-    {
-      die "$0: cannot fork: $!\n";
-    }
-  unless ($pid)
-    {
-      open(STDERR, ">&STDOUT")
-        or die "$0: cannot dup STDOUT: $!\n";
-      exec(@_)
-        or die "$0: cannot exec `@_': $!\n";
-    }
+
+  my $openfork_available = !($os_windows || $os_dos);
+  if ($openfork_available)
+    {
+      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";
+        }
+    }
+  else
+    {
+      # 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)
+            {
+              $comment = shift;
+              my ($handle, $tmpfile) = tempfile( DIR => $tmp_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>)
     {
@@ -255,6 +318,8 @@ sub safe_read_from_pipe
     }
 }
 
+# Use safe_read_from_pipe to start a child process safely and exit the
+# script if the child failed for whatever reason.
 sub read_from_process
   {
   unless (@_)


-- 
http://www.maddes.net/
Home: Milky Way / Solar System 1 / Earth


Mime
View raw message