[RFC/PATCH] gitweb: Use list form of 'open "-|"' pipeline

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add output_pipeline subroutine, which allows to use list form of
pipeline; instead of
  open my $fh, "-|", "cmd_1 option | cmd_2 argument"
we can now write
  my $fh = output_pipeline(['cmd_1', 'option'], ['cmd_2', 'argument']);
which allows to avoid troubles with shell quoting, and avoid spawning
shell.  Code is based on snippet http://www.perlmonks.org/?node_id=246397
simplified a bit.

It is then used in git_snapshot subroutine, where we sometimes open
pipeline from git-archive to compressor.

While at it, ensure that snapshot saved as <basename>.<suffix>
uncompresses to <basename>/

NOTE: this commit prepares way for adding syntax highlighting support
using external filter (external tool), like GNU Source-highlight or
Andre Simon's Highlight.

Signed-off-by: Jakub Narebski <jnareb@xxxxxxxxx>
---
This patch is an RFC, and doesn't really meant to be applied.
I'd like opinion on this code from resident Perl experts.  It
should work, though; it was rudimentarly tested.

 gitweb/gitweb.perl |   52 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a5df2fe..ba97a7b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1455,6 +1455,35 @@ sub git_cmd_str {
 	return join(' ', git_cmd());
 }
 
+# my $fh = output_pipeline(['cmd_1', 'option'], ['cmd_2', 'argument']);
+# is equivalent to (is the "list form" of) the following
+# open my $fh, "-|", "cmd_1 option | cmd_2 argument"
+#
+# Based on http://www.perlmonks.org/?node_id=246397
+#
+sub output_pipeline {
+	my @commands_list = @_;
+	exit unless @commands_list;
+
+	my $pid = open(my $fh, "-|");
+	#die "Couldn't fork: $!" unless defined $pid;
+
+	if ($pid) { # parent
+		return $fh;
+	}
+
+	# child
+ COMMAND:
+	while (my $command = pop @commands_list) {
+		my $pid = @commands_list ? open(STDIN, "-|") : -1;
+		#die "Couldn't fork: $!" unless defined $pid;
+
+		next COMMAND unless ($pid); # parent
+		exec @$command;             # child
+		#die "Couldn't exec \"@$command\": $!";
+	}
+}
+
 # get HEAD ref of given project as hash
 sub git_get_head_hash {
 	my $project = shift;
@@ -4545,27 +4574,26 @@ sub git_snapshot {
 		$hash = git_get_head_hash($project);
 	}
 
-	my $git_command = git_cmd_str();
 	my $name = $project;
-	$name =~ s,([^/])/*\.git$,$1,;
+	$name =~ s,([^/])/*\.git$,$1,; # strip '.git' or '/.git'
 	$name = basename($name);
-	my $filename = to_utf8($name);
-	$name =~ s/\047/\047\\\047\047/g;
-	my $cmd;
-	$filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}";
-	$cmd = "$git_command archive " .
-		"--format=$known_snapshot_formats{$format}{'format'} " .
-		"--prefix=\'$name\'/ $hash";
+	$name = to_utf8($name);  # or only for filename, not prefix?
+	$name .= "-$hash";
+
+	my @cmds = ([git_cmd(), "archive",
+		"--format=$known_snapshot_formats{$format}{'format'}",
+		"--prefix=$name/", $hash]);
 	if (exists $known_snapshot_formats{$format}{'compressor'}) {
-		$cmd .= ' | ' . join ' ', @{$known_snapshot_formats{$format}{'compressor'}};
+		push @cmds, $known_snapshot_formats{$format}{'compressor'};
 	}
 
 	print $cgi->header(
 		-type => $known_snapshot_formats{$format}{'type'},
-		-content_disposition => 'inline; filename="' . "$filename" . '"',
+		-content_disposition => 'inline; filename="' .
+			"$filename$known_snapshot_formats{$format}{'suffix'}" . '"',
 		-status => '200 OK');
 
-	open my $fd, "-|", $cmd
+	my $fd = output_pipeline(@cmds)
 		or die_error(undef, "Execute git-archive failed");
 	binmode STDOUT, ':raw';
 	print <$fd>;

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux