From 68cc555740b3f3f8f82a59cca34b1af247cc3909 Mon Sep 17 00:00:00 2001 From: maddes-b Date: Mon, 7 Sep 2020 20:13:55 +0200 Subject: [PATCH] Enhanced platform support of hook script check-mime-type.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * contrib/hook-scripts/check-mime-type.pl: (svnlook) Cross Platform: sane executable determination Patch by: Matthias Bücher [1] http://perldoc.perl.org/perlport.html#PLATFORMS --- contrib/hook-scripts/check-mime-type.pl | 129 ++++++++++++++++++++---- 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/contrib/hook-scripts/check-mime-type.pl b/contrib/hook-scripts/check-mime-type.pl index 79c37d26eb..716b1a0792 100755 --- a/contrib/hook-scripts/check-mime-type.pl +++ b/contrib/hook-scripts/check-mime-type.pl @@ -28,6 +28,15 @@ use strict; use Carp; +use Config; +use Cwd; +use Env; +use File::Which qw(which); +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 { @@ -35,6 +44,12 @@ BEGIN { { require warnings; import warnings; } else { $^W = 1; } + + $old_dir = getcwd; +} + +END { + chdir($old_dir); } @@ -42,31 +57,58 @@ BEGIN { # Configuration section. # Svnlook path. -my $svnlook = "/usr/bin/svnlook"; +my $svnlook; # Since the path to svnlook depends upon the local installation # preferences, check that the required program exists to insure that # the administrator has set up the script properly. { - my $ok = 1; - foreach my $program ($svnlook) + my $svnlook_exe = 'svnlook' . $Config{_exe}; + my @svnlook_paths; + + if ($os_windows || $os_dos) + { + # On Windows/DOS the environment is available + my $svn_bindir = $ENV{'SVN_BINDIR'}; + if (defined $svn_bindir and length $svn_bindir) + { + $svnlook_paths[++$#svnlook_paths] = "$svn_bindir/$svnlook_exe"; + } + + $svnlook = which($svnlook_exe); + if (defined $svnlook and length $svnlook) + { + $svnlook_paths[++$#svnlook_paths] = $svnlook; + } + undef $svnlook; + } + + # On Unix the environment is empty, define fallback with absolute path + $svnlook_paths[++$#svnlook_paths] = "/usr/bin/$svnlook_exe"; + + foreach my $program (@svnlook_paths) { if (-e $program) { unless (-x $program) { - warn "$0: required program `$program' is not executable, ", - "edit $0.\n"; - $ok = 0; + warn "$0: program `$program' is not executable.\n"; + next; } + $svnlook = $program; + last; } else { - warn "$0: required program `$program' does not exist, edit $0.\n"; - $ok = 0; + warn "$0: program `$program' does not exist.\n"; + next; } } - exit 1 unless $ok; + unless (defined $svnlook and length $svnlook) + { + warn "$0: required program `$svnlook_exe' does not exist or is not executable, maybe have to edit $0.\n"; + exit 1; + } } ###################################################################### @@ -95,9 +137,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"; @@ -220,19 +262,66 @@ 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) + + my $openfork_available = !($os_windows || $os_dos); + 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) + { + 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 + # Windows' (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"; } + my @output; while () { -- 2.24.3 (Apple Git-128)