xref: /freebsd/crypto/krb5/src/util/et/com_err.texinfo (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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