1 Subject: [PATCH] gitweb: send git_cmd() stderr output to /dev/null
3 Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
5 gitweb/gitweb.perl | 134 ++++++++++++++++++++++++++++++++---------------------
6 1 file changed, 80 insertions(+), 54 deletions(-)
8 diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
9 index 896f2ceb..5928ed3f 100755
10 --- a/gitweb/gitweb.perl
11 +++ b/gitweb/gitweb.perl
12 @@ -17,6 +17,7 @@ use Encode;
15 use File::Basename qw(basename);
17 use Time::HiRes qw(gettimeofday tv_interval);
19 use constant GITWEB_CACHE_FORMAT => "Gitweb Cache Format 3";
20 @@ -2783,6 +2784,32 @@ sub git_cmd {
21 return $GIT, '--git-dir='.$git_dir;
24 +# opens a "-|" cmd pipe handle with 2>/dev/null and returns it
27 + # In order to be compatible with FCGI mode we must use POSIX
28 + # and access the STDERR_FILENO file descriptor directly
30 + use POSIX qw(STDERR_FILENO dup dup2);
32 + open(my $null, '>', File::Spec->devnull) or die "couldn't open devnull: $!";
33 + (my $saveerr = dup(STDERR_FILENO)) or die "couldn't dup STDERR: $!";
34 + my $dup2ok = dup2(fileno($null), STDERR_FILENO);
35 + close($null) or !$dup2ok or die "couldn't close NULL: $!";
36 + $dup2ok or POSIX::close($saveerr), die "couldn't dup NULL to STDERR: $!";
37 + my $result = open(my $fd, "-|", @_);
38 + $dup2ok = dup2($saveerr, STDERR_FILENO);
39 + POSIX::close($saveerr) or !$dup2ok or die "couldn't close SAVEERR: $!";
40 + $dup2ok or die "couldn't dup SAVERR to STDERR: $!";
42 + return $result ? $fd : undef;
45 +# opens a "-|" git_cmd pipe handle with 2>/dev/null and returns it
47 + return cmd_pipe git_cmd(), @_;
50 # quote the given arguments for passing them to the shell
51 # quote_command("command", "arg 1", "arg with ' and ! characters")
52 # => "'command' 'arg 1' 'arg with '\'' and '\!' characters'"
53 @@ -2810,8 +2837,8 @@ sub git_get_hash {
54 my $o_git_dir = $git_dir;
56 $git_dir = "$projectroot/$project";
57 - if (open my $fd, '-|', git_cmd(), 'rev-parse',
58 - '--verify', '-q', @options, $hash) {
59 + if (defined(my $fd = git_cmd_pipe 'rev-parse',
60 + '--verify', '-q', @options, $hash)) {
62 chomp $retval if defined $retval;
64 @@ -2826,7 +2853,7 @@ sub git_get_hash {
68 - open my $fd, "-|", git_cmd(), "cat-file", '-t', $hash or return;
69 + defined(my $fd = git_cmd_pipe "cat-file", '-t', $hash) or return;
73 @@ -2859,7 +2886,7 @@ sub git_parse_project_config {
77 - open my $fh, "-|", git_cmd(), "config", '-z', '-l',
78 + defined(my $fh = git_cmd_pipe "config", '-z', '-l')
81 while (my $keyval = <$fh>) {
82 @@ -2974,7 +3001,7 @@ sub git_get_hash_by_path {
86 - open my $fd, "-|", git_cmd(), "ls-tree", $base, "--", $path
87 + defined(my $fd = git_cmd_pipe "ls-tree", $base, "--", $path)
88 or die_error(500, "Open git-ls-tree failed");
90 close $fd or return undef;
91 @@ -3001,7 +3028,7 @@ sub git_get_path_by_hash {
95 - open my $fd, "-|", git_cmd(), "ls-tree", '-r', '-t', '-z', $base
96 + defined(my $fd = git_cmd_pipe "ls-tree", '-r', '-t', '-z', $base)
98 while (my $line = <$fd>) {
100 @@ -3452,7 +3479,7 @@ sub git_get_last_activity {
103 return (undef) if $quick;
104 - open($fd, "-|", git_cmd(), 'for-each-ref',
105 + defined($fd = git_cmd_pipe 'for-each-ref',
106 '--format=%(committer)',
107 '--sort=-committerdate',
109 @@ -3477,7 +3504,7 @@ sub git_get_remotes_list {
113 - open my $fd, '-|' , git_cmd(), 'remote', '-v';
114 + my $fd = git_cmd_pipe 'remote', '-v';
116 while (my $remote = <$fd>) {
118 @@ -3510,8 +3537,8 @@ sub git_get_references {
120 # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11
121 # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{}
122 - open my $fd, "-|", git_cmd(), "show-ref", "--dereference",
123 - ($type ? ("--", "refs/$type") : ()) # use -- <pattern> if $type
124 + defined(my $fd = git_cmd_pipe "show-ref", "--dereference",
125 + ($type ? ("--", "refs/$type") : ())) # use -- <pattern> if $type
128 while (my $line = <$fd>) {
129 @@ -3531,7 +3558,7 @@ sub git_get_references {
130 sub git_get_rev_name_tags {
131 my $hash = shift || return undef;
133 - open my $fd, "-|", git_cmd(), "name-rev", "--tags", $hash
134 + defined(my $fd = git_cmd_pipe "name-rev", "--tags", $hash)
136 my $name_rev = <$fd>;
138 @@ -3586,7 +3613,7 @@ sub parse_tag {
142 - open my $fd, "-|", git_cmd(), "cat-file", "tag", $tag_id or return;
143 + defined(my $fd = git_cmd_pipe "cat-file", "tag", $tag_id) or return;
144 $tag{'id'} = $tag_id;
145 while (my $line = <$fd>) {
147 @@ -3726,12 +3753,12 @@ sub parse_commit {
151 - open my $fd, "-|", git_cmd(), "rev-list",
152 + defined(my $fd = git_cmd_pipe "rev-list",
159 or die_error(500, "Open git-rev-list failed");
160 %co = parse_commit_text(<$fd>, 1);
162 @@ -3748,7 +3775,7 @@ sub parse_commits {
166 - open my $fd, "-|", git_cmd(), "rev-list",
167 + defined(my $fd = git_cmd_pipe "rev-list",
170 ("--max-count=" . $maxcount),
171 @@ -3756,7 +3783,7 @@ sub parse_commits {
175 - ($filename ? ($filename) : ())
176 + ($filename ? ($filename) : ()))
177 or die_error(500, "Open git-rev-list failed");
178 while (my $line = <$fd>) {
179 my %co = parse_commit_text($line);
180 @@ -3910,10 +3937,10 @@ sub git_get_heads_list {
181 my @patterns = map { "refs/$_" } @classes;
184 - open my $fd, '-|', git_cmd(), 'for-each-ref',
185 + defined(my $fd = git_cmd_pipe 'for-each-ref',
186 ($limit ? '--count='.($limit+1) : ()), '--sort=-committerdate',
187 '--format=%(objectname) %(refname) %(subject)%00%(committer)',
191 while (my $line = <$fd>) {
193 @@ -3957,11 +3984,11 @@ sub git_get_tags_list {
194 my $order = shift || $default_refs_order;
195 my $sortkey = $all && $order eq 'name' ? 'refname' : '-creatordate';
197 - open my $fd, '-|', git_cmd(), 'for-each-ref',
198 + defined(my $fd = git_cmd_pipe 'for-each-ref',
199 ($limit ? '--count='.($limit+1) : ()), "--sort=$sortkey",
200 '--format=%(objectname) %(objecttype) %(refname) '.
201 '%(*objectname) %(*objecttype) %(subject)%00%(creator)',
202 - ($all ? 'refs' : 'refs/tags')
203 + ($all ? 'refs' : 'refs/tags'))
205 while (my $line = <$fd>) {
207 @@ -4850,7 +4877,7 @@ sub git_get_link_target {
211 - open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
212 + defined(my $fd = git_cmd_pipe "cat-file", "blob", $hash)
216 @@ -6631,9 +6658,9 @@ sub git_search_changes {
220 - open my $fd, '-|', git_cmd(), '--no-pager', 'log', @diff_opts,
221 + defined(my $fd = git_cmd_pipe '--no-pager', 'log', @diff_opts,
222 '--pretty=format:%H', '--no-abbrev', '--raw', "-S$searchtext",
223 - ($search_use_regexp ? '--pickaxe-regex' : ())
224 + ($search_use_regexp ? '--pickaxe-regex' : ()))
225 or die_error(500, "Open git-log failed");
228 @@ -6714,9 +6741,9 @@ sub git_search_files {
232 - open my $fd, "-|", git_cmd(), 'grep', '-n', '-z',
233 + defined(my $fd = git_cmd_pipe 'grep', '-n', '-z',
234 $search_use_regexp ? ('-E', '-i') : '-F',
235 - $searchtext, $co{'tree'}
236 + $searchtext, $co{'tree'})
237 or die_error(500, "Open git-grep failed");
240 @@ -7153,17 +7180,17 @@ sub git_blame_common {
242 if ($format eq 'incremental') {
243 # get file contents (as base)
244 - open $fd, "-|", git_cmd(), 'cat-file', 'blob', $hash
245 + defined($fd = git_cmd_pipe 'cat-file', 'blob', $hash)
246 or die_error(500, "Open git-cat-file failed");
247 } elsif ($format eq 'data') {
248 # run git-blame --incremental
249 - open $fd, "-|", git_cmd(), "blame", "--incremental",
250 - $hash_base, "--", $file_name
251 + defined($fd = git_cmd_pipe "blame", "--incremental",
252 + $hash_base, "--", $file_name)
253 or die_error(500, "Open git-blame --incremental failed");
255 # run git-blame --porcelain
256 - open $fd, "-|", git_cmd(), "blame", '-p',
257 - $hash_base, '--', $file_name
258 + defined($fd = git_cmd_pipe "blame", '-p',
259 + $hash_base, '--', $file_name)
260 or die_error(500, "Open git-blame --porcelain failed");
262 binmode $fd, ':utf8';
263 @@ -7469,7 +7496,7 @@ sub git_blob_plain {
267 - open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
268 + defined(my $fd = git_cmd_pipe "cat-file", "blob", $hash)
269 or die_error(500, "Open git-cat-file blob '$hash' failed");
271 # content-type (can include charset)
272 @@ -7531,7 +7558,7 @@ sub git_blob {
275 my $have_blame = gitweb_check_feature('blame');
276 - open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
277 + defined(my $fd = git_cmd_pipe "cat-file", "blob", $hash)
278 or die_error(500, "Couldn't cat $file_name, $hash");
279 my $mimetype = blob_mimetype($fd, $file_name);
280 # use 'blob_plain' (aka 'raw') view for files that cannot be displayed
281 @@ -7627,8 +7654,8 @@ sub git_tree {
285 - open my $fd, "-|", git_cmd(), "ls-tree", '-z',
286 - ($show_sizes ? '-l' : ()), @extra_options, $hash
287 + defined(my $fd = git_cmd_pipe "ls-tree", '-z',
288 + ($show_sizes ? '-l' : ()), @extra_options, $hash)
289 or die_error(500, "Open git-ls-tree failed");
290 @entries = map { chomp; $_ } <$fd>;
292 @@ -7846,7 +7873,7 @@ sub git_snapshot {
293 %co ? (-last_modified => $latest_date{'rfc2822'}) : (),
294 -status => '200 OK');
296 - open my $fd, "-|", $cmd
297 + defined(my $fd = cmd_pipe $cmd)
298 or die_error(500, "Execute git-archive failed");
299 binmode STDOUT, ':raw';
301 @@ -7978,10 +8005,10 @@ sub git_commit {
305 - open my $fd, "-|", git_cmd(), "diff-tree", '-r', "--no-commit-id",
306 + defined(my $fd = git_cmd_pipe "diff-tree", '-r', "--no-commit-id",
308 (@$parents <= 1 ? $parent : '-c'),
311 or die_error(500, "Open git-diff-tree failed");
312 @difftree = map { chomp; $_ } <$fd>;
313 close $fd or die_error(404, "Reading git-diff-tree failed");
314 @@ -8060,8 +8087,7 @@ sub git_object {
315 if ($hash || ($hash_base && !defined $file_name)) {
316 my $object_id = $hash || $hash_base;
318 - open my $fd, "-|", quote_command(
319 - git_cmd(), 'cat-file', '-t', $object_id) . ' 2> /dev/null'
320 + defined(my $fd = git_cmd_pipe 'cat-file', '-t', $object_id)
321 or die_error(404, "Object does not exist");
324 @@ -8076,7 +8102,7 @@ sub git_object {
325 or die_error(404, "Base object does not exist");
327 # here errors should not happen
328 - open my $fd, "-|", git_cmd(), "ls-tree", $hash_base, "--", $file_name
329 + defined(my $fd = git_cmd_pipe "ls-tree", $hash_base, "--", $file_name)
330 or die_error(500, "Open git-ls-tree failed");
333 @@ -8111,9 +8137,9 @@ sub git_blobdiff {
334 if (defined $hash_base && defined $hash_parent_base) {
335 if (defined $file_name) {
337 - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
338 + defined($fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
339 $hash_parent_base, $hash_base,
340 - "--", (defined $file_parent ? $file_parent : ()), $file_name
341 + "--", (defined $file_parent ? $file_parent : ()), $file_name)
342 or die_error(500, "Open git-diff-tree failed");
343 @difftree = map { chomp; $_ } <$fd>;
345 @@ -8126,8 +8152,8 @@ sub git_blobdiff {
346 # try to find filename from $hash
348 # read filtered raw output
349 - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
350 - $hash_parent_base, $hash_base, "--"
351 + defined($fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
352 + $hash_parent_base, $hash_base, "--")
353 or die_error(500, "Open git-diff-tree failed");
355 # ':100644 100644 03b21826... 3b93d5e7... M ls-files.c'
356 @@ -8161,10 +8187,10 @@ sub git_blobdiff {
360 - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
361 + defined($fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
362 '-p', ($format eq 'html' ? "--full-index" : ()),
363 $hash_parent_base, $hash_base,
364 - "--", (defined $file_parent ? $file_parent : ()), $file_name
365 + "--", (defined $file_parent ? $file_parent : ()), $file_name)
366 or die_error(500, "Open git-diff-tree failed");
369 @@ -8354,9 +8380,9 @@ sub git_commitdiff {
372 if ($format eq 'html') {
373 - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
374 + defined($fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
375 "--no-commit-id", "--patch-with-raw", "--full-index",
376 - $hash_parent_param, $hash, "--"
377 + $hash_parent_param, $hash, "--")
378 or die_error(500, "Open git-diff-tree failed");
380 while (my $line = <$fd>) {
381 @@ -8367,8 +8393,8 @@ sub git_commitdiff {
384 } elsif ($format eq 'plain') {
385 - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
386 - '-p', $hash_parent_param, $hash, "--"
387 + defined($fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
388 + '-p', $hash_parent_param, $hash, "--")
389 or die_error(500, "Open git-diff-tree failed");
390 } elsif ($format eq 'patch') {
391 # For commit ranges, we limit the output to the number of
392 @@ -8392,8 +8418,8 @@ sub git_commitdiff {
394 push @commit_spec, '--root', $hash;
396 - open $fd, "-|", git_cmd(), "format-patch", @diff_opts,
397 - '--encoding=utf8', '--stdout', @commit_spec
398 + defined($fd = git_cmd_pipe "format-patch", @diff_opts,
399 + '--encoding=utf8', '--stdout', @commit_spec)
400 or die_error(500, "Open git-format-patch failed");
402 die_error(400, "Unknown commitdiff format");
403 @@ -8742,9 +8768,9 @@ XML
404 my %cd = parse_date($co{'author_epoch'}, $co{'author_tz'});
406 # get list of changed files
407 - open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
408 + defined(my $fd = git_cmd_pipe "diff-tree", '-r', @diff_opts,
409 $co{'parent'} || "--root",
410 - $co{'id'}, "--", (defined $file_name ? $file_name : ())
411 + $co{'id'}, "--", (defined $file_name ? $file_name : ()))
413 my @difftree = map { chomp; $_ } <$fd>;