Sunteți pe pagina 1din 3

#!

/usr/bin/sh
#
# errno - quick lookup into /usr/include/sys/errno.h
# and crossreference to man page errno(2) for a fuller explanation
#
# usage: errno [ NUMBER | Emessage | -f ]
# where: NUMBER is errno number,
# Emessage is case-insensitive (eg: efault or EAGAIN)
#
# The script is smart enough to determine if an error number or
# the error name was used and to match only on the correct field
# in errno.h

set -u
PATH=/usr/bin
ERRNOFILE=/usr/include/sys/errno.h
MYNAME=${0##*/}

function AllNumbers
{

# Usage: AllNumbers string


# returns zero if all chars are numbers
# non-zero if no string, string is null or non-numeric chars found

[[ $# -eq 0 ]] && return 1


STRING=$1
LEN=${#STRING}
CHAR=1
while [ $CHAR -le $LEN ]
do
MYCHAR=$(echo $STRING | cut -c $CHAR)
[[ $MYCHAR < "0" ]] && return 2
[[ $MYCHAR > "9" ]] && return 3
let CHAR=$CHAR+1
done
return 0
}

if [ $# -lt 1 ]
then
echo "Usage:"
echo " $MYNAME [ NUMBER | Emessage ]"
echo " where: NUMBER is errno number such as 12 or"
echo " Emessage is the text version such as ENOMEM"
echo " NOTE: Emessage can be lower or UPPER case"
exit 1
fi

# Is the error text all numbers? If so, look in the


# errno field of the defines. Otherwise, look in
# the errno text section. This eliminates simple
# line greps that get false matches. Translate
# the errno text into UPPERCASE for awk

typeset -u ERRTEXT=$1
AllNumbers $ERRTEXT
if [ $? -eq 0 ]
then
CHECKFIELD=3
else
CHECKFIELD=2
fi

# To make the search string dynamic, we'll let the shell expand
# the variable before awk sees it (AWK book pg 256)

ERRLINE=$(grep "^#define" $ERRNOFILE \


| awk -v ITEM=$CHECKFIELD '$ITEM ~ /'"$ERRTEXT"'/')

if [ "$ERRLINE" = "" ]
then
echo "\n$MYNAME: nothing matched in $ERRNOFILE\n"
exit 0
fi

# Use typeset to line up the fields better than tabs (some fields > 8)

typeset -L12 EMESSAGE


typeset -R3 ENUMTEXT

# Search for Emessage or error number depending on whether


# the argument was all numbers or not

if [ $( echo "$ERRLINE" | wc -l ) -gt 1 ]


then
echo "\n$MYNAME: found multiple matches for $ERRTEXT"
echo "$ERRLINE" | while read DEFINE EMESSAGE ENUMTEXT REPLY
do
print " $EMESSAGE $ENUMTEXT $REPLY"
done
print "\n(pick the unique Emessage from above list and run again)\n"
exit 0
fi

# At this point, we have one unique error number or Emessage


# and can search through the man page to display the contents.

EMESG=$(echo $ERRLINE|awk '{print $2}')


print "\nfrom $ERRNOFILE:"
print " $ERRLINE"

# Cross ref to man page. This incantation:


# removes formatting (col -b)
# reduces all sequential blank lines to 1
# removes HP page footer
# removes the errno(2) page header
# shows the EMESG paragraph (at least until a blank line shows up)
#
# The only difficulty is with header/footer pages that may insert
# a blank line in the middle of a paragraph.

# To Do: extract the actual paragraph and ignore header/footers

print "\nfrom man 2 errno:"


echo "$(man - 2 errno 2>/dev/null \
| col -b)" \
| ssp \
| grep -v "^ Hewlett-Packard" \
| grep -v "^ errno(2)" \
| sed -n "/$EMESG/,/^$/p"
exit 0

S-ar putea să vă placă și