#!/usr/bin/env perl # perror --- show system error messages from symbolic or numeric errno values # Author: Noah Friedman # Created: 2002-03-16 # Public domain # $Id: perror,v 1.6 2012/11/30 02:33:21 friedman Exp $ # Commentary: # Code: $^W = 1; # enable warnings use Errno; use strict; my @errno_data; my %errno_data; my $emaxlen = 0; sub init { for my $errname (@Errno::EXPORT_OK) { # In newer versions of perl, the number is just a scalar. # In older versions, each was a subroutine. my $errnum = ${$Errno::{$errname}} || &{$Errno::{$errname}}; next unless defined $errnum; local $! = $errnum; my $errmsg = $! . ""; (my $altname = $errname) =~ s/^E//o; my $data = [$errname, $errnum, $errmsg]; push @errno_data, $data; $errno_data{$errnum} = $data; $errno_data{$errname} = $data; $errno_data{lc $errname} = $data; $errno_data{$errmsg} = $data; $errno_data{lc $errmsg} = $data; $errno_data{$altname} = $data; $errno_data{lc $altname} = $data; my $l = length $errname; $emaxlen = $l if $l > $emaxlen; } } sub printmatches { my $data = shift; map { printf "%-${emaxlen}s %3d %s\n", @$_ } sort { $a->[1] <=> $b->[1] } @$data; } sub main { init (); unless (@_) { printmatches (\@errno_data); exit (0); } my %match; for my $arg (@_) { if ($arg =~ m|^/(.*?)/$|o) { my $pat = $1; map { $match{$_} = $_ if ($_->[0] =~ /$pat/i || $_->[1] =~ /$pat/i || $_->[2] =~ /$pat/i); } @errno_data; } else { my $data = $errno_data{$arg}; $match{$data} = $data if defined $data; } } printmatches ([values %match]) if %match; } main (@ARGV); # perror ends here