From bd4ca09d4cddc226ece1bb5b40a74ba281f3e00e Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Thu, 4 Apr 2013 22:41:41 +0200 Subject: [PATCH 1/2] perl: redirect stderr to /dev/null instead of closing On my system, t9100.1 triggers the following warning: ==352== Syscall param write(buf) points to uninitialised byte(s) ==352== at 0x57119C0: __write_nocancel (in /lib64/libc-2.17.so) ==352== by 0x56AC1D2: _IO_file_write@@GLIBC_2.2.5 (in /lib64/libc-2.17.so) ==352== by 0x56AC0B1: new_do_write (in /lib64/libc-2.17.so) ==352== by 0x56AD3B4: _IO_do_write@@GLIBC_2.2.5 (in /lib64/libc-2.17.so) ==352== by 0x56AD6FE: _IO_file_overflow@@GLIBC_2.2.5 (in /lib64/libc-2.17.so) ==352== by 0x56AE3D8: _IO_default_xsputn (in /lib64/libc-2.17.so) ==352== by 0x56ACAA2: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.17.so) ==352== by 0x5682133: buffered_vfprintf (in /lib64/libc-2.17.so) ==352== by 0x567CE9D: vfprintf (in /lib64/libc-2.17.so) ==352== by 0x5687096: fprintf (in /lib64/libc-2.17.so) ==352== by 0x4E7AC5: vreportf (usage.c:15) ==352== by 0x4E7B14: die_builtin (usage.c:38) The actual complaint appears to be a bug in the underlying implementation. What's interesting here is that it is apparently _triggered_ by closing stderr, which results in (from strace) write(2, "fatal: Needed a single revision\n", 32) = -1 EBADF (Bad file descriptor) write(2, "\0", 1) = -1 EBADF (Bad file descriptor) Closing stderr is a bad idea anyway: there is a very real chance that we print fatal error messages to some other file that just happens to be opened on the now-free FD 2. So let's not do that. As pointed out by Eric Wong (thanks), the initial close needs to go: die() would again write nowhere if we close STDERR beforehand. Signed-off-by: Thomas Rast Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- perl/Git.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/perl/Git.pm b/perl/Git.pm index 57a17160f9..4778428830 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -1335,12 +1335,12 @@ sub _command_common_pipe { if (not defined $pid) { throw Error::Simple("open failed: $!"); } elsif ($pid == 0) { - if (defined $opts{STDERR}) { - close STDERR; - } if ($opts{STDERR}) { open (STDERR, '>&', $opts{STDERR}) or die "dup failed: $!"; + } elsif (defined $opts{STDERR}) { + open (STDERR, '>', '/dev/null') + or die "opening /dev/null failed: $!"; } _cmd_exec($self, $cmd, @args); } From a749c0bbef068af339ea1ac8843f8ca307b3dd35 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Thu, 4 Apr 2013 22:41:42 +0200 Subject: [PATCH 2/2] t9700: do not close STDERR Much like the previous patch, this triggered an unrelated bug. Closing STDERR is not worth it anyway, as we risk writing die() and such to random files that happen to be subsequently opened on FD 2. Don't do it. Signed-off-by: Thomas Rast Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- t/t9700/test.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 0d4e366232..1140767b50 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -45,7 +45,8 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color"); # Failure cases for config: # Save and restore STDERR; we will probably extract this into a # "dies_ok" method and possibly move the STDERR handling to Git.pm. -open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR; +open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; +open STDERR, ">", "/dev/null" or die "cannot redirect STDERR to /dev/null"; is($r->config("test.dupstring"), "value2", "config: multivar"); eval { $r->config_bool("test.boolother") }; ok($@, "config_bool: non-boolean values fail");