Subject: | [PATCH] Better handling of failures when invoking dmidecode |
Date: | Wed, 24 Feb 2010 17:15:20 -0500 |
To: | bug-parse-dmidecode [...] rt.cpan.org |
From: | "Dave O'Neill" <dmo [...] roaringpenguin.com> |
This patch better handles the cases where dmidecode exits in error. Common
cases for the error exit are:
- you are not root
- you are root, but cannot read /dev/mem (common on paravirtualized Linux systems)
Without this patch, failures give you error output like:
/dev/mem: Permission denied
Unable to close file handle for command '/usr/sbin/dmidecode': at -e line 1
and with it:
Command '/usr/sbin/dmidecode' exited with exit code 1 at -e line 1
which is a bit more palatable (and doesn't spew to the caller's stdout).
diff --git a/lib/Parse/DMIDecode.pm b/lib/Parse/DMIDecode.pm
index 6258031..441bff1 100644
--- a/lib/Parse/DMIDecode.pm
+++ b/lib/Parse/DMIDecode.pm
@@ -89,11 +89,48 @@ sub probe {
my $fh;
local %ENV = %ENV;
delete @ENV{qw(IFS CDPATH ENV BASH_ENV PATH)};
- open($fh,'-|',$cmd) || croak "Unable to open file handle for command '$cmd': $!";
- while (local $_ = <$fh>) {
- $stor->{raw} .= $_;
+
+ my $pid = open($fh, '-|');
+
+ if( ! defined $pid ) {
+ die("Could not fork: $!");
+ }
+
+ if( $pid == 0 ) {
+ # in child
+
+ # Throw away stderr
+ open(STDERR, '>/dev/null');
+
+ # new scope to silence Perl warning about code after an
+ # exec... see 'perldoc exec' for details
+ {
+ # Also suppress warnings about exec problems; we'll get
+ # them below from $! if they actually matter (like
+ # file not found, etc)
+ no warnings 'exec';
+ exec $cmd;
+ }
+ die qq{Could not exec $cmd: $!};
}
- close($fh) || carp "Unable to close file handle for command '$cmd': $!";
+
+ if( ! $fh ) {
+ croak "No filehandle opened for command '$cmd'";
+ }
+
+ # Slurp in entire output
+ $stor->{raw} = do { local $/; <$fh> };
+
+ my $rc = close($fh);
+
+ if( ! $rc ) {
+ my $exitcode = $? >> 8;
+ my $signal = $? & 127;
+ carp "Error closing pipe from command '$cmd': $!" if $!;
+ carp "Command '$cmd' exited due to signal $signal" if ($signal != 0);
+ carp "Command '$cmd' exited with exit code $exitcode" if ($exitcode != 0);
+ }
+
return $self->parse($stor->{raw});
}
--
Dave O'Neill <dmo@roaringpenguin.com> Roaring Penguin Software Inc.
+1 (613) 231-6599 http://www.roaringpenguin.com/
For CanIt technical support, please mail: support@roaringpenguin.com