git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Jakub Narebski <jnareb@gmail.com>
Date
Mar 8, 2008, 16:57 UTC
Message-ID
<20080308165245.15343.62914.stgit@localhost.localdomain>
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@gmail.com>
---
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>;
Next: Charles Bailey
Message 1 of 7 in “gitweb: Use list form of 'open "-|"' pipeline”
  1. gitweb: Use list form of 'open "-|"' pipelineJakub Narebski, Mar 8, 2008
  2. Charles BaileyMar 8, 2008
  3. Jakub NarebskiMar 8, 2008
  4. Frank LichtenheldMar 11, 2008
  5. Jakub NarebskiMar 11, 2008
  6. Frank LichtenheldMar 11, 2008
  7. Jay SoffianMar 12, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.