1*7f2fe78bSCy Schubert\input texinfo @c -*-texinfo-*- 2*7f2fe78bSCy Schubert 3*7f2fe78bSCy Schubert@c util/et/com_err.texinfo 4*7f2fe78bSCy Schubert 5*7f2fe78bSCy Schubert@c Note that although this source file is in texinfo format (more 6*7f2fe78bSCy Schubert@c or less), it is not yet suitable for turning into an ``info'' 7*7f2fe78bSCy Schubert@c file. Sorry, maybe next time. 8*7f2fe78bSCy Schubert@c 9*7f2fe78bSCy Schubert@c In order to produce hardcopy documentation from a texinfo file, 10*7f2fe78bSCy Schubert@c run ``tex com_err.texinfo'' which will load in texinfo.tex, 11*7f2fe78bSCy Schubert@c provided in this distribution. (texinfo.tex is from the Free 12*7f2fe78bSCy Schubert@c Software Foundation, and is under different copyright restrictions 13*7f2fe78bSCy Schubert@c from the rest of this package.) 14*7f2fe78bSCy Schubert 15*7f2fe78bSCy Schubert@ifinfo 16*7f2fe78bSCy Schubert@barfo 17*7f2fe78bSCy Schubert@end ifinfo 18*7f2fe78bSCy Schubert 19*7f2fe78bSCy Schubert@iftex 20*7f2fe78bSCy Schubert@tolerance 10000 21*7f2fe78bSCy Schubert 22*7f2fe78bSCy Schubert@c Mutate section headers... 23*7f2fe78bSCy Schubert@begingroup 24*7f2fe78bSCy Schubert @catcode#=6 25*7f2fe78bSCy Schubert @gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}} 26*7f2fe78bSCy Schubert@endgroup 27*7f2fe78bSCy Schubert@end iftex 28*7f2fe78bSCy Schubert 29*7f2fe78bSCy Schubert@setfilename com_err 30*7f2fe78bSCy Schubert@settitle A Common Error Description Library for UNIX 31*7f2fe78bSCy Schubert 32*7f2fe78bSCy Schubert@ifinfo 33*7f2fe78bSCy SchubertThis file documents the use of the Common Error Description library. 34*7f2fe78bSCy Schubert 35*7f2fe78bSCy SchubertCopyright (C) 1987, 1988 Student Information Processing Board of the 36*7f2fe78bSCy SchubertMassachusetts Institute of Technology. 37*7f2fe78bSCy Schubert 38*7f2fe78bSCy SchubertPermission to use, copy, modify, and distribute this software and its 39*7f2fe78bSCy Schubertdocumentation for any purpose and without fee is hereby granted, provided 40*7f2fe78bSCy Schubertthat the above copyright notice appear in all copies and that both that 41*7f2fe78bSCy Schubertcopyright notice and this permission notice appear in supporting 42*7f2fe78bSCy Schubertdocumentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be 43*7f2fe78bSCy Schubertused in advertising or publicity pertaining to distribution of the software 44*7f2fe78bSCy Schubertwithout specific, written prior permission. Furthermore if you modify this 45*7f2fe78bSCy Schubertsoftware you must label your software as modified software and not 46*7f2fe78bSCy Schubertdistribute it in such a fashion that it might be confused with the 47*7f2fe78bSCy Schubertoriginal M.I.T. software. M.I.T. and the M.I.T. S.I.P.B. 48*7f2fe78bSCy Schubertmake no representations about the suitability of this software for any 49*7f2fe78bSCy Schubertpurpose. It is provided "as is" without express or implied warranty. 50*7f2fe78bSCy Schubert 51*7f2fe78bSCy SchubertNote that the file texinfo.tex, provided with this distribution, is from 52*7f2fe78bSCy Schubertthe Free Software Foundation, and is under different copyright restrictions 53*7f2fe78bSCy Schubertfrom the remainder of this package. 54*7f2fe78bSCy Schubert 55*7f2fe78bSCy Schubert@end ifinfo 56*7f2fe78bSCy Schubert 57*7f2fe78bSCy Schubert@ignore 58*7f2fe78bSCy SchubertPermission is granted to process this file through Tex and print the 59*7f2fe78bSCy Schubertresults, provided the printed document carries copying permission 60*7f2fe78bSCy Schubertnotice identical to this one except for the removal of this paragraph 61*7f2fe78bSCy Schubert(this paragraph not being relevant to the printed manual). 62*7f2fe78bSCy Schubert 63*7f2fe78bSCy Schubert@end ignore 64*7f2fe78bSCy Schubert 65*7f2fe78bSCy Schubert@setchapternewpage odd 66*7f2fe78bSCy Schubert 67*7f2fe78bSCy Schubert@titlepage 68*7f2fe78bSCy Schubert@center @titlefont{A Common Error Description} 69*7f2fe78bSCy Schubert@center @titlefont{Library for UNIX} 70*7f2fe78bSCy Schubert@sp 2 71*7f2fe78bSCy Schubert@center Ken Raeburn 72*7f2fe78bSCy Schubert@center Bill Sommerfeld 73*7f2fe78bSCy Schubert@sp 1 74*7f2fe78bSCy Schubert@center MIT Student Information Processing Board 75*7f2fe78bSCy Schubert@sp 3 76*7f2fe78bSCy Schubert@center last updated 1 January 1989 77*7f2fe78bSCy Schubert@center for version 1.2 78*7f2fe78bSCy Schubert@center ***DRAFT COPY ONLY*** 79*7f2fe78bSCy Schubert 80*7f2fe78bSCy Schubert@vskip 2in 81*7f2fe78bSCy Schubert 82*7f2fe78bSCy Schubert@center @b{Abstract} 83*7f2fe78bSCy Schubert 84*7f2fe78bSCy SchubertUNIX has always had a clean and simple system call interface, with a 85*7f2fe78bSCy Schubertstandard set of error codes passed between the kernel and user 86*7f2fe78bSCy Schubertprograms. Unfortunately, the same cannot be said of many of the 87*7f2fe78bSCy Schubertlibraries layered on top of the primitives provided by the kernel. 88*7f2fe78bSCy SchubertTypically, each one has used a different style of indicating errors to 89*7f2fe78bSCy Schuberttheir callers, leading to a total hodgepodge of error handling, and 90*7f2fe78bSCy Schubertconsiderable amounts of work for the programmer. This paper describes 91*7f2fe78bSCy Schuberta library and associated utilities which allows a more uniform way for 92*7f2fe78bSCy Schubertlibraries to return errors to their callers, and for programs to 93*7f2fe78bSCy Schubertdescribe errors and exceptional conditions to their users. 94*7f2fe78bSCy Schubert 95*7f2fe78bSCy Schubert@page 96*7f2fe78bSCy Schubert@vskip 0pt plus 1filll 97*7f2fe78bSCy Schubert 98*7f2fe78bSCy SchubertCopyright @copyright{} 1987, 1988 by the Student Information Processing 99*7f2fe78bSCy SchubertBoard of the Massachusetts Institute of Technology. 100*7f2fe78bSCy Schubert 101*7f2fe78bSCy SchubertPermission to use, copy, modify, and distribute this software and its 102*7f2fe78bSCy Schubertdocumentation for any purpose and without fee is hereby granted, provided 103*7f2fe78bSCy Schubertthat the above copyright notice appear in all copies and that both that 104*7f2fe78bSCy Schubertcopyright notice and this permission notice appear in supporting 105*7f2fe78bSCy Schubertdocumentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be 106*7f2fe78bSCy Schubertused in advertising or publicity pertaining to distribution of the software 107*7f2fe78bSCy Schubertwithout specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B. 108*7f2fe78bSCy Schubertmake no representations about the suitability of this software for any 109*7f2fe78bSCy Schubertpurpose. It is provided "as is" without express or implied warranty. 110*7f2fe78bSCy Schubert 111*7f2fe78bSCy SchubertNote that the file texinfo.tex, provided with this distribution, is from 112*7f2fe78bSCy Schubertthe Free Software Foundation, and is under different copyright restrictions 113*7f2fe78bSCy Schubertfrom the remainder of this package. 114*7f2fe78bSCy Schubert 115*7f2fe78bSCy Schubert@end titlepage 116*7f2fe78bSCy Schubert 117*7f2fe78bSCy Schubert@ifinfo 118*7f2fe78bSCy Schubert@c should put a menu here someday.... 119*7f2fe78bSCy Schubert@end ifinfo 120*7f2fe78bSCy Schubert 121*7f2fe78bSCy Schubert@page 122*7f2fe78bSCy Schubert 123*7f2fe78bSCy Schubert@section Why com_err? 124*7f2fe78bSCy Schubert 125*7f2fe78bSCy SchubertIn building application software packages, a programmer often has to 126*7f2fe78bSCy Schubertdeal with a number of libraries, each of which can use a different 127*7f2fe78bSCy Schuberterror-reporting mechanism. Sometimes one of two values is returned, 128*7f2fe78bSCy Schubertindicating simply SUCCESS or FAILURE, with no description of errors 129*7f2fe78bSCy Schubertencountered. Sometimes it is an index into a table of text strings, 130*7f2fe78bSCy Schubertwhere the name of the table used is dependent on the library being 131*7f2fe78bSCy Schubertused when the error is generated; since each table starts numbering at 132*7f2fe78bSCy Schubert0 or 1, additional information as to the source of the error code is 133*7f2fe78bSCy Schubertneeded to determine which table to look at. Sometimes no text messages are 134*7f2fe78bSCy Schubertsupplied at all, and the programmer must supply them at any point at which 135*7f2fe78bSCy Schuberthe may wish to report error conditions. 136*7f2fe78bSCy SchubertOften, a global variable is assigned some value describing the error, but 137*7f2fe78bSCy Schubertthe programmer has to know in each case whether to look at @code{errno}, 138*7f2fe78bSCy Schubert@code{h_errno}, the return value from @code{hes_err()}, or whatever other 139*7f2fe78bSCy Schubertvariables or routines are specified. 140*7f2fe78bSCy SchubertAnd what happens if something 141*7f2fe78bSCy Schubertin the procedure of 142*7f2fe78bSCy Schubertexamining or reporting the error changes the same variable? 143*7f2fe78bSCy Schubert 144*7f2fe78bSCy SchubertThe package we have developed is an attempt to present a common 145*7f2fe78bSCy Schuberterror-handling mechanism to manipulate the most common form of error code 146*7f2fe78bSCy Schubertin a fashion that does not have the problems listed above. 147*7f2fe78bSCy Schubert 148*7f2fe78bSCy SchubertA list of up to 256 text messages is supplied to a translator we have 149*7f2fe78bSCy Schubertwritten, along with the three- to four-character ``name'' of the error 150*7f2fe78bSCy Schuberttable. The library using this error table need only call a routine 151*7f2fe78bSCy Schubertgenerated from this error-table source to make the table ``known'' to the 152*7f2fe78bSCy Schubertcom_err library, and any error code the library generates can be converted 153*7f2fe78bSCy Schubertto the corresponding error message. There is also a default format for 154*7f2fe78bSCy Schuberterror codes accidentally returned before making the table known, which is 155*7f2fe78bSCy Schubertof the form @samp{unknown code foo 32}, where @samp{foo} would be the name 156*7f2fe78bSCy Schubertof the table. 157*7f2fe78bSCy Schubert 158*7f2fe78bSCy Schubert@section Error codes 159*7f2fe78bSCy Schubert 160*7f2fe78bSCy SchubertError codes themselves are 32 bit (signed) integers, of which the high 161*7f2fe78bSCy Schubertorder 24 bits are an identifier of which error table the error code is 162*7f2fe78bSCy Schubertfrom, and the low order 8 bits are a sequential error number within 163*7f2fe78bSCy Schubertthe table. An error code may thus be easily decomposed into its component 164*7f2fe78bSCy Schubertparts. Only the lowest 32 bits of an error code are considered significant 165*7f2fe78bSCy Schuberton systems which support wider values. 166*7f2fe78bSCy Schubert 167*7f2fe78bSCy SchubertError table 0 is defined to match the UNIX system call error table 168*7f2fe78bSCy Schubert(@code{sys_errlist}); this allows @code{errno} values to be used directly 169*7f2fe78bSCy Schubertin the library (assuming that @code{errno} is of a type with the same width 170*7f2fe78bSCy Schubertas @t{long}). Other error table numbers are formed by compacting together 171*7f2fe78bSCy Schubertthe first four characters of the error table name. The mapping between 172*7f2fe78bSCy Schubertcharacters in the name and numeric values in the error code are defined in 173*7f2fe78bSCy Schuberta system-independent fashion, so that two systems that can pass integral 174*7f2fe78bSCy Schubertvalues between them can reliably pass error codes without loss of meaning; 175*7f2fe78bSCy Schubertthis should work even if the character sets used are not the same. 176*7f2fe78bSCy Schubert(However, if this is to be done, error table 0 should be avoided, since the 177*7f2fe78bSCy Schubertlocal system call error tables may differ.) 178*7f2fe78bSCy Schubert 179*7f2fe78bSCy SchubertAny variable which is to contain an error code should be declared @t{long}. 180*7f2fe78bSCy SchubertThe draft proposed American National Standard for C (as of May, 1988) 181*7f2fe78bSCy Schubertrequires that @t{long} variables be at least 32 bits; any system which does 182*7f2fe78bSCy Schubertnot support 32-bit @t{long} values cannot make use of this package (nor 183*7f2fe78bSCy Schubertmuch other software that assumes an ANSI-C environment base) without 184*7f2fe78bSCy Schubertsignificant effort. 185*7f2fe78bSCy Schubert 186*7f2fe78bSCy Schubert@section Error table source file 187*7f2fe78bSCy Schubert 188*7f2fe78bSCy SchubertThe error table source file begins with the declaration of the table name, 189*7f2fe78bSCy Schubertas 190*7f2fe78bSCy Schubert 191*7f2fe78bSCy Schubert@example 192*7f2fe78bSCy Schuberterror_table @var{tablename} 193*7f2fe78bSCy Schubert@end example 194*7f2fe78bSCy Schubert 195*7f2fe78bSCy SchubertIndividual error codes are 196*7f2fe78bSCy Schubertspecified with 197*7f2fe78bSCy Schubert 198*7f2fe78bSCy Schubert@example 199*7f2fe78bSCy Schuberterror_code @var{ERROR_NAME}, @var{"text message"} 200*7f2fe78bSCy Schubert@end example 201*7f2fe78bSCy Schubert 202*7f2fe78bSCy Schubertwhere @samp{ec} can also be used as a short form of @samp{error_code}. To 203*7f2fe78bSCy Schubertindicate the end of the table, use @samp{end}. Thus, a (short) sample 204*7f2fe78bSCy Schuberterror table might be: 205*7f2fe78bSCy Schubert 206*7f2fe78bSCy Schubert@example 207*7f2fe78bSCy Schubert 208*7f2fe78bSCy Schubert error_table dsc 209*7f2fe78bSCy Schubert 210*7f2fe78bSCy Schubert error_code DSC_DUP_MTG_NAME, 211*7f2fe78bSCy Schubert "Meeting already exists" 212*7f2fe78bSCy Schubert 213*7f2fe78bSCy Schubert ec DSC_BAD_PATH, 214*7f2fe78bSCy Schubert "A bad meeting pathname was given" 215*7f2fe78bSCy Schubert 216*7f2fe78bSCy Schubert ec DSC_BAD_MODES, 217*7f2fe78bSCy Schubert "Invalid mode for this access control list" 218*7f2fe78bSCy Schubert 219*7f2fe78bSCy Schubert end 220*7f2fe78bSCy Schubert 221*7f2fe78bSCy Schubert@end example 222*7f2fe78bSCy Schubert 223*7f2fe78bSCy Schubert@section The error-table compiler 224*7f2fe78bSCy Schubert 225*7f2fe78bSCy SchubertThe error table compiler is named @code{compile_et}. It takes one 226*7f2fe78bSCy Schubertargument, the pathname of a file (ending in @samp{.et}, e.g., 227*7f2fe78bSCy Schubert@samp{dsc_err.et}) containing an error table source file. It parses the 228*7f2fe78bSCy Schuberterror table, and generates two output files -- a C header file 229*7f2fe78bSCy Schubert(@samp{discuss_err.h}) which contains definitions of the numerical values 230*7f2fe78bSCy Schubertof the error codes defined in the error table, and a C source file which 231*7f2fe78bSCy Schubertshould be compiled and linked with the executable. The header file must be 232*7f2fe78bSCy Schubertincluded in the source of a module which wishes to reference the error 233*7f2fe78bSCy Schubertcodes defined; the object module generated from the C code may be linked in 234*7f2fe78bSCy Schubertto a program which wishes to use the printed forms of the error codes. 235*7f2fe78bSCy Schubert 236*7f2fe78bSCy SchubertThis translator accepts a @kbd{-language @var{lang}} argument, which 237*7f2fe78bSCy Schubertdetermines for which language (or language variant) the output should be 238*7f2fe78bSCy Schubertwritten. At the moment, @var{lang} is currently limited to @kbd{ANSI-C} 239*7f2fe78bSCy Schubertand @kbd{K&R-C}, and some abbreviated forms of each. Eventually, this will 240*7f2fe78bSCy Schubertbe extended to include some support for C++. The default is currently 241*7f2fe78bSCy Schubert@kbd{K&R-C}, though the generated sources will have ANSI-C code 242*7f2fe78bSCy Schubertconditionalized on the symbol @t{__STDC__}. 243*7f2fe78bSCy Schubert 244*7f2fe78bSCy Schubert@section Run-time support routines 245*7f2fe78bSCy Schubert 246*7f2fe78bSCy SchubertAny source file which uses the routines supplied with or produced by the 247*7f2fe78bSCy Schubertcom_err package should include the header file @file{<com_err.h>}. It 248*7f2fe78bSCy Schubertcontains declarations and definitions which may be needed on some systems. 249*7f2fe78bSCy Schubert(Some functions cannot be referenced properly without the return type 250*7f2fe78bSCy Schubertdeclarations in this file. Some functions may work properly on most 251*7f2fe78bSCy Schubertarchitectures even without the header file, but relying on this is not 252*7f2fe78bSCy Schubertrecommended.) 253*7f2fe78bSCy Schubert 254*7f2fe78bSCy SchubertThe run-time support routines and variables provided via this package 255*7f2fe78bSCy Schubertinclude the following: 256*7f2fe78bSCy Schubert 257*7f2fe78bSCy Schubert@example 258*7f2fe78bSCy Schubertvoid initialize_@var{xxxx}_error_table (void); 259*7f2fe78bSCy Schubert@end example 260*7f2fe78bSCy Schubert 261*7f2fe78bSCy SchubertOne of these routines is built by the error compiler for each error table. 262*7f2fe78bSCy SchubertIt makes the @var{xxxx} error table ``known'' to the error reporting 263*7f2fe78bSCy Schubertsystem. By convention, this routine should be called in the initialization 264*7f2fe78bSCy Schubertroutine of the @var{xxxx} library. If the library has no initialization 265*7f2fe78bSCy Schubertroutine, some combination of routines which form the core of the library 266*7f2fe78bSCy Schubertshould ensure that this routine is called. It is not advised to leave it 267*7f2fe78bSCy Schubertthe caller to make this call. 268*7f2fe78bSCy Schubert 269*7f2fe78bSCy SchubertThere is no harm in calling this routine more than once. 270*7f2fe78bSCy Schubert 271*7f2fe78bSCy Schubert@example 272*7f2fe78bSCy Schubert#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L 273*7f2fe78bSCy Schubert@end example 274*7f2fe78bSCy Schubert 275*7f2fe78bSCy SchubertThis symbol contains the value of the first error code entry in the 276*7f2fe78bSCy Schubertspecified table. 277*7f2fe78bSCy SchubertThis rarely needs be used by the 278*7f2fe78bSCy Schubertprogrammer. 279*7f2fe78bSCy Schubert 280*7f2fe78bSCy Schubert@example 281*7f2fe78bSCy Schubertconst char *error_message (long code); 282*7f2fe78bSCy Schubert@end example 283*7f2fe78bSCy Schubert 284*7f2fe78bSCy SchubertThis routine returns the character string error message associated 285*7f2fe78bSCy Schubertwith @code{code}; if this is associated with an unknown error table, or 286*7f2fe78bSCy Schubertif the code is associated with a known error table but the code is not 287*7f2fe78bSCy Schubertin the table, a string of the form @samp{Unknown code @var{xxxx nn}} is 288*7f2fe78bSCy Schubertreturned, where @var{xxxx} is the error table name produced by 289*7f2fe78bSCy Schubertreversing the compaction performed on the error table number implied 290*7f2fe78bSCy Schubertby that error code, and @var{nn} is the offset from that base value. 291*7f2fe78bSCy Schubert 292*7f2fe78bSCy SchubertAlthough this routine is available for use when needed, its use should be 293*7f2fe78bSCy Schubertleft to circumstances which render @code{com_err} (below) unusable. 294*7f2fe78bSCy Schubert 295*7f2fe78bSCy Schubert@example 296*7f2fe78bSCy Schubertvoid com_err (const char *whoami, /* module reporting error */ 297*7f2fe78bSCy Schubert long code, /* error code */ 298*7f2fe78bSCy Schubert const char *format, /* format for additional detail */ 299*7f2fe78bSCy Schubert ...); /* (extra parameters) */ 300*7f2fe78bSCy Schubert@end example 301*7f2fe78bSCy Schubert 302*7f2fe78bSCy SchubertThis routine provides an alternate way to print error messages to 303*7f2fe78bSCy Schubertstandard error; it allows the error message to be passed in as a 304*7f2fe78bSCy Schubertparameter, rather than in an external variable. @emph{Provide grammatical 305*7f2fe78bSCy Schubertcontext for ``message.''} 306*7f2fe78bSCy Schubert 307*7f2fe78bSCy SchubertIf @var{format} is @code{(char *)NULL}, the formatted message will not be 308*7f2fe78bSCy Schubertprinted. @var{format} may not be omitted. 309*7f2fe78bSCy Schubert 310*7f2fe78bSCy Schubert@example 311*7f2fe78bSCy Schubert#include <stdarg.h> 312*7f2fe78bSCy Schubert 313*7f2fe78bSCy Schubertvoid com_err_va (const char *whoami, 314*7f2fe78bSCy Schubert long code, 315*7f2fe78bSCy Schubert const char *format, 316*7f2fe78bSCy Schubert va_list args); 317*7f2fe78bSCy Schubert@end example 318*7f2fe78bSCy Schubert 319*7f2fe78bSCy SchubertThis routine provides an interface, equivalent to @code{com_err} above, 320*7f2fe78bSCy Schubertwhich may be used by higher-level variadic functions (functions which 321*7f2fe78bSCy Schubertaccept variable numbers of arguments). 322*7f2fe78bSCy Schubert 323*7f2fe78bSCy Schubert@example 324*7f2fe78bSCy Schubert#include <stdarg.h> 325*7f2fe78bSCy Schubert 326*7f2fe78bSCy Schubertvoid (*set_com_err_hook (void (*proc) ())) (); 327*7f2fe78bSCy Schubert 328*7f2fe78bSCy Schubertvoid (*@var{proc}) (const char *whoami, long code, va_list args); 329*7f2fe78bSCy Schubert 330*7f2fe78bSCy Schubertvoid reset_com_err_hook (); 331*7f2fe78bSCy Schubert@end example 332*7f2fe78bSCy Schubert 333*7f2fe78bSCy SchubertThese two routines allow a routine to be dynamically substituted for 334*7f2fe78bSCy Schubert@samp{com_err}. After @samp{set_com_err_hook} has been called, 335*7f2fe78bSCy Schubertcalls to @samp{com_err} will turn into calls to the new hook routine. 336*7f2fe78bSCy Schubert@samp{reset_com_err_hook} turns off this hook. This may intended to 337*7f2fe78bSCy Schubertbe used in daemons (to use a routine which calls @var{syslog(3)}), or 338*7f2fe78bSCy Schubertin a window system application (which could pop up a dialogue box). 339*7f2fe78bSCy Schubert 340*7f2fe78bSCy SchubertIf a program is to be used in an environment in which simply printing 341*7f2fe78bSCy Schubertmessages to the @code{stderr} stream would be inappropriate (such as in a 342*7f2fe78bSCy Schubertdaemon program which runs without a terminal attached), 343*7f2fe78bSCy Schubert@code{set_com_err_hook} may be used to redirect output from @code{com_err}. 344*7f2fe78bSCy SchubertThe following is an example of an error handler which uses @var{syslog(3)} 345*7f2fe78bSCy Schubertas supplied in BSD 4.3: 346*7f2fe78bSCy Schubert 347*7f2fe78bSCy Schubert@example 348*7f2fe78bSCy Schubert#include <stdio.h> 349*7f2fe78bSCy Schubert#include <stdarg.h> 350*7f2fe78bSCy Schubert#include <syslog.h> 351*7f2fe78bSCy Schubert 352*7f2fe78bSCy Schubert/* extern openlog (const char * name, int logopt, int facility); */ 353*7f2fe78bSCy Schubert/* extern syslog (int priority, char * message, ...); */ 354*7f2fe78bSCy Schubert 355*7f2fe78bSCy Schubertvoid hook (const char * whoami, long code, 356*7f2fe78bSCy Schubert const char * format, va_list args) 357*7f2fe78bSCy Schubert@{ 358*7f2fe78bSCy Schubert char buffer[BUFSIZ]; 359*7f2fe78bSCy Schubert static int initialized = 0; 360*7f2fe78bSCy Schubert if (!initialized) @{ 361*7f2fe78bSCy Schubert openlog (whoami, 362*7f2fe78bSCy Schubert LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY, 363*7f2fe78bSCy Schubert LOG_DAEMON); 364*7f2fe78bSCy Schubert initialized = 1; 365*7f2fe78bSCy Schubert @} 366*7f2fe78bSCy Schubert vsprintf (buffer, format, args); 367*7f2fe78bSCy Schubert syslog (LOG_ERR, "%s %s", error_message (code), buffer); 368*7f2fe78bSCy Schubert@} 369*7f2fe78bSCy Schubert@end example 370*7f2fe78bSCy Schubert 371*7f2fe78bSCy SchubertAfter making the call 372*7f2fe78bSCy Schubert@code{set_com_err_hook (hook);}, 373*7f2fe78bSCy Schubertany calls to @code{com_err} will result in messages being sent to the 374*7f2fe78bSCy Schubert@var{syslogd} daemon for logging. 375*7f2fe78bSCy SchubertThe name of the program, @samp{whoami}, is supplied to the 376*7f2fe78bSCy Schubert@samp{openlog()} call, and the message is formatted into a buffer and 377*7f2fe78bSCy Schubertpassed to @code{syslog}. 378*7f2fe78bSCy Schubert 379*7f2fe78bSCy SchubertNote that since the extra arguments to @code{com_err} are passed by 380*7f2fe78bSCy Schubertreference via the @code{va_list} value @code{args}, the hook routine may 381*7f2fe78bSCy Schubertplace any form of interpretation on them, including ignoring them. For 382*7f2fe78bSCy Schubertconsistency, @code{printf}-style interpretation is suggested, via 383*7f2fe78bSCy Schubert@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for 384*7f2fe78bSCy Schubertthe ANSI C library). 385*7f2fe78bSCy Schubert 386*7f2fe78bSCy Schubert@section Coding Conventions 387*7f2fe78bSCy Schubert 388*7f2fe78bSCy SchubertThe following conventions are just some general stylistic conventions 389*7f2fe78bSCy Schubertto follow when writing robust libraries and programs. Conventions 390*7f2fe78bSCy Schubertsimilar to this are generally followed inside the UNIX kernel and most 391*7f2fe78bSCy Schubertroutines in the Multics operating system. In general, a routine 392*7f2fe78bSCy Schuberteither succeeds (returning a zero error code, and doing some side 393*7f2fe78bSCy Schuberteffects in the process), or it fails, doing minimal side effects; in 394*7f2fe78bSCy Schubertany event, any invariant which the library assumes must be maintained. 395*7f2fe78bSCy Schubert 396*7f2fe78bSCy SchubertIn general, it is not in the domain of non user-interface library 397*7f2fe78bSCy Schubertroutines to write error messages to the user's terminal, or halt the 398*7f2fe78bSCy Schubertprocess. Such forms of ``error handling'' should be reserved for 399*7f2fe78bSCy Schubertfailures of internal invariants and consistency checks only, as it 400*7f2fe78bSCy Schubertprovides the user of the library no way to clean up for himself in the 401*7f2fe78bSCy Schubertevent of total failure. 402*7f2fe78bSCy Schubert 403*7f2fe78bSCy SchubertLibrary routines which can fail should be set up to return an error 404*7f2fe78bSCy Schubertcode. This should usually be done as the return value of the 405*7f2fe78bSCy Schubertfunction; if this is not acceptable, the routine should return a 406*7f2fe78bSCy Schubert``null'' value, and put the error code into a parameter passed by 407*7f2fe78bSCy Schubertreference. 408*7f2fe78bSCy Schubert 409*7f2fe78bSCy SchubertRoutines which use the first style of interface can be used from 410*7f2fe78bSCy Schubertuser-interface levels of a program as follows: 411*7f2fe78bSCy Schubert 412*7f2fe78bSCy Schubert@example 413*7f2fe78bSCy Schubert@{ 414*7f2fe78bSCy Schubert if ((code = initialize_world(getuid(), random())) != 0) @{ 415*7f2fe78bSCy Schubert com_err("demo", code, 416*7f2fe78bSCy Schubert "when trying to initialize world"); 417*7f2fe78bSCy Schubert exit(1); 418*7f2fe78bSCy Schubert @} 419*7f2fe78bSCy Schubert if ((database = open_database("my_secrets", &code))==NULL) @{ 420*7f2fe78bSCy Schubert com_err("demo", code, 421*7f2fe78bSCy Schubert "while opening my_secrets"); 422*7f2fe78bSCy Schubert exit(1); 423*7f2fe78bSCy Schubert @} 424*7f2fe78bSCy Schubert@} 425*7f2fe78bSCy Schubert@end example 426*7f2fe78bSCy Schubert 427*7f2fe78bSCy SchubertA caller which fails to check the return status is in error. It is 428*7f2fe78bSCy Schubertpossible to look for code which ignores error returns by using lint; 429*7f2fe78bSCy Schubertlook for error messages of the form ``foobar returns value which is 430*7f2fe78bSCy Schubertsometimes ignored'' or ``foobar returns value which is always 431*7f2fe78bSCy Schubertignored.'' 432*7f2fe78bSCy Schubert 433*7f2fe78bSCy SchubertSince libraries may be built out of other libraries, it is often necessary 434*7f2fe78bSCy Schubertfor the success of one routine to depend on another. When a lower level 435*7f2fe78bSCy Schubertroutine returns an error code, the middle level routine has a few possible 436*7f2fe78bSCy Schubertoptions. It can simply return the error code to its caller after doing 437*7f2fe78bSCy Schubertsome form of cleanup, it can substitute one of its own, or it can take 438*7f2fe78bSCy Schubertcorrective action of its own and continue normally. For instance, a 439*7f2fe78bSCy Schubertlibrary routine which makes a ``connect'' system call to make a network 440*7f2fe78bSCy Schubertconnection may reflect the system error code @code{ECONNREFUSED} 441*7f2fe78bSCy Schubert(Connection refused) to its caller, or it may return a ``server not 442*7f2fe78bSCy Schubertavailable, try again later,'' or it may try a different server. 443*7f2fe78bSCy Schubert 444*7f2fe78bSCy SchubertCleanup which is typically necessary may include, but not be limited 445*7f2fe78bSCy Schubertto, freeing allocated memory which will not be needed any more, 446*7f2fe78bSCy Schubertunlocking concurrancy locks, dropping reference counts, closing file 447*7f2fe78bSCy Schubertdescriptors, or otherwise undoing anything which the procedure did up 448*7f2fe78bSCy Schubertto this point. When there are a lot of things which can go wrong, it 449*7f2fe78bSCy Schubertis generally good to write one block of error-handling code which is 450*7f2fe78bSCy Schubertbranched to, using a goto, in the event of failure. A common source 451*7f2fe78bSCy Schubertof errors in UNIX programs is failing to close file descriptors on 452*7f2fe78bSCy Schuberterror returns; this leaves a number of ``zombied'' file descriptors 453*7f2fe78bSCy Schubertopen, which eventually causes the process to run out of file 454*7f2fe78bSCy Schubertdescriptors and fall over. 455*7f2fe78bSCy Schubert 456*7f2fe78bSCy Schubert@example 457*7f2fe78bSCy Schubert@{ 458*7f2fe78bSCy Schubert FILE *f1=NULL, *f2=NULL, *f3=NULL; 459*7f2fe78bSCy Schubert int status = 0; 460*7f2fe78bSCy Schubert 461*7f2fe78bSCy Schubert if ( (f1 = fopen(FILE1, "r")) == NULL) @{ 462*7f2fe78bSCy Schubert status = errno; 463*7f2fe78bSCy Schubert goto error; 464*7f2fe78bSCy Schubert @} 465*7f2fe78bSCy Schubert 466*7f2fe78bSCy Schubert /* 467*7f2fe78bSCy Schubert * Crunch for a while 468*7f2fe78bSCy Schubert */ 469*7f2fe78bSCy Schubert 470*7f2fe78bSCy Schubert if ( (f2 = fopen(FILE2, "w")) == NULL) @{ 471*7f2fe78bSCy Schubert status = errno; 472*7f2fe78bSCy Schubert goto error; 473*7f2fe78bSCy Schubert @} 474*7f2fe78bSCy Schubert 475*7f2fe78bSCy Schubert if ( (f3 = fopen(FILE3, "a+")) == NULL) @{ 476*7f2fe78bSCy Schubert status = errno; 477*7f2fe78bSCy Schubert goto error; 478*7f2fe78bSCy Schubert @} 479*7f2fe78bSCy Schubert 480*7f2fe78bSCy Schubert /* 481*7f2fe78bSCy Schubert * Do more processing. 482*7f2fe78bSCy Schubert */ 483*7f2fe78bSCy Schubert fclose(f1); 484*7f2fe78bSCy Schubert fclose(f2); 485*7f2fe78bSCy Schubert fclose(f3); 486*7f2fe78bSCy Schubert return 0; 487*7f2fe78bSCy Schubert 488*7f2fe78bSCy Schuberterror: 489*7f2fe78bSCy Schubert if (f1) fclose(f1); 490*7f2fe78bSCy Schubert if (f2) fclose(f2); 491*7f2fe78bSCy Schubert if (f3) fclose(f3); 492*7f2fe78bSCy Schubert return status; 493*7f2fe78bSCy Schubert@} 494*7f2fe78bSCy Schubert@end example 495*7f2fe78bSCy Schubert 496*7f2fe78bSCy Schubert@section Building and Installation 497*7f2fe78bSCy Schubert 498*7f2fe78bSCy SchubertThe distribution of this package will probably be done as a compressed 499*7f2fe78bSCy Schubert``tar''-format file available via anonymous FTP from SIPB.MIT.EDU. 500*7f2fe78bSCy SchubertRetrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory 501*7f2fe78bSCy Schubert@t{profiled} should be created to hold objects compiled for profiling. 502*7f2fe78bSCy SchubertRunning ``make all'' should then be sufficient to build the library and 503*7f2fe78bSCy Schuberterror-table compiler. The files @samp{libcom_err.a}, 504*7f2fe78bSCy Schubert@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be 505*7f2fe78bSCy Schubertinstalled for use; @samp{com_err.3} and @samp{compile_et.1} can also be 506*7f2fe78bSCy Schubertinstalled as manual pages. 507*7f2fe78bSCy Schubert 508*7f2fe78bSCy SchubertPotential problems: 509*7f2fe78bSCy Schubert 510*7f2fe78bSCy Schubert@itemize @bullet 511*7f2fe78bSCy Schubert 512*7f2fe78bSCy Schubert@item Use of @code{strcasecmp}, a routine provided in BSD for 513*7f2fe78bSCy Schubertcase-insensitive string comparisons. If an equivalent routine is 514*7f2fe78bSCy Schubertavailable, you can modify @code{CFLAGS} in the makefile to define 515*7f2fe78bSCy Schubert@code{strcasecmp} to the name of that routine. 516*7f2fe78bSCy Schubert 517*7f2fe78bSCy Schubert@item Compilers that defined @code{__STDC__} without providing the header 518*7f2fe78bSCy Schubertfile @code{<stdarg.h>}. One such example is Metaware's High ``C'' 519*7f2fe78bSCy Schubertcompiler, as provided at Project Athena on the IBM RT/PC workstation; if 520*7f2fe78bSCy Schubert@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not 521*7f2fe78bSCy Schubertavailable, and therefore @code{<varargs.h>} must be used. If the symbol 522*7f2fe78bSCy Schubert@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will 523*7f2fe78bSCy Schubertbe used. 524*7f2fe78bSCy Schubert 525*7f2fe78bSCy Schubert@item If your linker rejects symbols that are simultaneously defined in two 526*7f2fe78bSCy Schubertlibrary files, edit @samp{Makefile} to remove @samp{perror.c} from the 527*7f2fe78bSCy Schubertlibrary. This file contains a version of @var{perror(3)} which calls 528*7f2fe78bSCy Schubert@code{com_err} instead of calling @code{write} directly. 529*7f2fe78bSCy Schubert 530*7f2fe78bSCy Schubert@end itemize 531*7f2fe78bSCy Schubert 532*7f2fe78bSCy SchubertAs I do not have access to non-BSD systems, there are probably 533*7f2fe78bSCy Schubertbugs present that may interfere with building or using this package on 534*7f2fe78bSCy Schubertother systems. If they are reported to me, they can probably be fixed for 535*7f2fe78bSCy Schubertthe next version. 536*7f2fe78bSCy Schubert 537*7f2fe78bSCy Schubert@section Bug Reports 538*7f2fe78bSCy Schubert 539*7f2fe78bSCy SchubertPlease send any comments or bug reports to the principal author: Ken 540*7f2fe78bSCy SchubertRaeburn, @t{Raeburn@@Athena.MIT.EDU}. 541*7f2fe78bSCy Schubert 542*7f2fe78bSCy Schubert@section Acknowledgements 543*7f2fe78bSCy Schubert 544*7f2fe78bSCy SchubertI would like to thank: Bill Sommerfeld, for his help with some of this 545*7f2fe78bSCy Schubertdocumentation, and catching some of the bugs the first time around; 546*7f2fe78bSCy SchubertHoneywell Information Systems, for not killing off the @emph{Multics} 547*7f2fe78bSCy Schubertoperating system before I had an opportunity to use it; Honeywell's 548*7f2fe78bSCy Schubertcustomers, who persuaded them not to do so, for a while; Ted Anderson of 549*7f2fe78bSCy SchubertCMU, for catching some problems before version 1.2 left the nest; Stan 550*7f2fe78bSCy SchubertZanarotti and several others of MIT's Student Information Processing Board, 551*7f2fe78bSCy Schubertfor getting us started with ``discuss,'' for which this package was 552*7f2fe78bSCy Schubertoriginally written; and everyone I've talked into --- I mean, asked to read 553*7f2fe78bSCy Schubertthis document and the ``man'' pages. 554*7f2fe78bSCy Schubert 555*7f2fe78bSCy Schubert@bye 556