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+subvers...@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
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 (@_)