1 \input texinfo @c -*-texinfo-*-
7 @c Note that although this source file is in texinfo format (more
8 @c or less), it is not yet suitable for turning into an ``info''
9 @c file. Sorry, maybe next time.
11 @c In order to produce hardcopy documentation from a texinfo file,
12 @c run ``tex com_err.texinfo'' which will load in texinfo.tex,
13 @c provided in this distribution. (texinfo.tex is from the Free
14 @c Software Foundation, and is under different copyright restrictions
15 @c from the rest of this package.)
18 @settitle A Common Error Description Library for UNIX
21 @dircategory Development
23 * Com_err: (com_err). A Common Error Description Library for UNIX.
30 @c Mutate section headers...
33 @gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
38 This file documents the use of the Common Error Description library.
40 Copyright (C) 1987, 1988 Student Information Processing Board of the
41 Massachusetts Institute of Technology.
43 Permission to use, copy, modify, and distribute this software and its
44 documentation for any purpose and without fee is hereby granted, provided
45 that the above copyright notice appear in all copies and that both that
46 copyright notice and this permission notice appear in supporting
47 documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
48 used in advertising or publicity pertaining to distribution of the software
49 without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
50 make no representations about the suitability of this software for any
51 purpose. It is provided "as is" without express or implied warranty.
53 Note that the file texinfo.tex, provided with this distribution, is from
54 the Free Software Foundation, and is under different copyright restrictions
55 from the remainder of this package.
58 Permission is granted to process this file through Tex and print the
59 results, provided the printed document carries copying permission
60 notice identical to this one except for the removal of this paragraph
61 (this paragraph not being relevant to the printed manual).
65 @setchapternewpage odd
68 @center @titlefont{A Common Error Description}
69 @center @titlefont{Library for UNIX}
72 @center Bill Sommerfeld
74 @center MIT Student Information Processing Board
76 @center last updated 1 January 1989
77 @center for version 1.2
78 @center ***DRAFT COPY ONLY***
84 UNIX has always had a clean and simple system call interface, with a
85 standard set of error codes passed between the kernel and user
86 programs. Unfortunately, the same cannot be said of many of the
87 libraries layered on top of the primitives provided by the kernel.
88 Typically, each one has used a different style of indicating errors to
89 their callers, leading to a total hodgepodge of error handling, and
90 considerable amounts of work for the programmer. This paper describes
91 a library and associated utilities which allows a more uniform way for
92 libraries to return errors to their callers, and for programs to
93 describe errors and exceptional conditions to their users.
96 @vskip 0pt plus 1filll
98 Copyright @copyright{} 1987, 1988 by the Student Information Processing
99 Board of the Massachusetts Institute of Technology.
101 Permission to use, copy, modify, and distribute this software and its
102 documentation for any purpose and without fee is hereby granted, provided
103 that the above copyright notice appear in all copies and that both that
104 copyright notice and this permission notice appear in supporting
105 documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
106 used in advertising or publicity pertaining to distribution of the software
107 without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
108 make no representations about the suitability of this software for any
109 purpose. It is provided "as is" without express or implied warranty.
111 Note that the file texinfo.tex, provided with this distribution, is from
112 the Free Software Foundation, and is under different copyright restrictions
113 from the remainder of this package.
118 @node Top, Why com_err?, (dir), (dir)
120 @top A Common Error Description Library for UNIX
122 This manual documents the com_err library.
127 * Error table source file::
128 * The error-table compiler::
129 * Run-time support routines::
130 * Coding Conventions::
131 * Building and Installation::
140 @node Why com_err?, Error codes, Top, Top
141 @section Why com_err?
143 In building application software packages, a programmer often has to
144 deal with a number of libraries, each of which can use a different
145 error-reporting mechanism. Sometimes one of two values is returned,
146 indicating simply SUCCESS or FAILURE, with no description of errors
147 encountered. Sometimes it is an index into a table of text strings,
148 where the name of the table used is dependent on the library being
149 used when the error is generated; since each table starts numbering at
150 0 or 1, additional information as to the source of the error code is
151 needed to determine which table to look at. Sometimes no text messages are
152 supplied at all, and the programmer must supply them at any point at which
153 he may wish to report error conditions.
154 Often, a global variable is assigned some value describing the error, but
155 the programmer has to know in each case whether to look at @code{errno},
156 @code{h_errno}, the return value from @code{hes_err()}, or whatever other
157 variables or routines are specified.
158 And what happens if something
160 examining or reporting the error changes the same variable?
162 The package we have developed is an attempt to present a common
163 error-handling mechanism to manipulate the most common form of error code
164 in a fashion that does not have the problems listed above.
166 A list of up to 256 text messages is supplied to a translator we have
167 written, along with the three- to four-character ``name'' of the error
168 table. The library using this error table need only call a routine
169 generated from this error-table source to make the table ``known'' to the
170 com_err library, and any error code the library generates can be converted
171 to the corresponding error message. There is also a default format for
172 error codes accidentally returned before making the table known, which is
173 of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
176 @node Error codes, Error table source file, Why com_err?, Top
179 Error codes themselves are 32 bit (signed) integers, of which the high
180 order 24 bits are an identifier of which error table the error code is
181 from, and the low order 8 bits are a sequential error number within
182 the table. An error code may thus be easily decomposed into its component
183 parts. Only the lowest 32 bits of an error code are considered significant
184 on systems which support wider values.
186 Error table 0 is defined to match the UNIX system call error table
187 (@code{sys_errlist}); this allows @code{errno} values to be used directly
188 in the library (assuming that @code{errno} is of a type with the same width
189 as @t{long}). Other error table numbers are formed by compacting together
190 the first four characters of the error table name. The mapping between
191 characters in the name and numeric values in the error code are defined in
192 a system-independent fashion, so that two systems that can pass integral
193 values between them can reliably pass error codes without loss of meaning;
194 this should work even if the character sets used are not the same.
195 (However, if this is to be done, error table 0 should be avoided, since the
196 local system call error tables may differ.)
198 Any variable which is to contain an error code should be declared @t{long}.
199 The draft proposed American National Standard for C (as of May, 1988)
200 requires that @t{long} variables be at least 32 bits; any system which does
201 not support 32-bit @t{long} values cannot make use of this package (nor
202 much other software that assumes an ANSI-C environment base) without
205 @node Error table source file, The error-table compiler, Error codes, Top
206 @section Error table source file
208 The error table source file begins with the declaration of the table name,
212 error_table @var{tablename}
215 Individual error codes are
219 error_code @var{ERROR_NAME}, @var{"text message"}
222 where @samp{ec} can also be used as a short form of @samp{error_code}. To
223 indicate the end of the table, use @samp{end}. Thus, a (short) sample
224 error table might be:
230 error_code DSC_DUP_MTG_NAME,
231 "Meeting already exists"
234 "A bad meeting pathname was given"
237 "Invalid mode for this access control list"
243 @node The error-table compiler, Run-time support routines, Error table source file, Top
244 @section The error-table compiler
246 The error table compiler is named @code{compile_et}. It takes one
247 argument, the pathname of a file (ending in @samp{.et}, e.g.,
248 @samp{dsc_err.et}) containing an error table source file. It parses the
249 error table, and generates two output files -- a C header file
250 (@samp{discuss_err.h}) which contains definitions of the numerical values
251 of the error codes defined in the error table, and a C source file which
252 should be compiled and linked with the executable. The header file must be
253 included in the source of a module which wishes to reference the error
254 codes defined; the object module generated from the C code may be linked in
255 to a program which wishes to use the printed forms of the error codes.
257 @node Run-time support routines, Coding Conventions, The error-table compiler, Top
258 @section Run-time support routines
260 Any source file which uses the routines supplied with or produced by the
261 com_err package should include the header file @file{<com_err.h>}. It
262 contains declarations and definitions which may be needed on some systems.
263 (Some functions cannot be referenced properly without the return type
264 declarations in this file. Some functions may work properly on most
265 architectures even without the header file, but relying on this is not
268 The run-time support routines and variables provided via this package
269 include the following:
272 void initialize_@var{xxxx}_error_table (void);
275 One of these routines is built by the error compiler for each error table.
276 It makes the @var{xxxx} error table ``known'' to the error reporting
277 system. By convention, this routine should be called in the initialization
278 routine of the @var{xxxx} library. If the library has no initialization
279 routine, some combination of routines which form the core of the library
280 should ensure that this routine is called. It is not advised to leave it
281 the caller to make this call.
283 There is no harm in calling this routine more than once.
286 #define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
289 This symbol contains the value of the first error code entry in the
291 This rarely needs be used by the
294 @deftypefun const char *error_message (long @var{code});
296 This routine returns the character string error message associated
297 with @code{code}; if this is associated with an unknown error table, or
298 if the code is associated with a known error table but the code is not
299 in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
300 returned, where @var{xxxx} is the error table name produced by
301 reversing the compaction performed on the error table number implied
302 by that error code, and @var{nn} is the offset from that base value.
304 Although this routine is available for use when needed, its use should be
305 left to circumstances which render @code{com_err} (below) unusable.
310 void com_err (const char *@var{whoami}, long @var{error_code},
311 const char *@var{format}, ...);
313 This routine provides an alternate way to print error messages to
314 standard error; it allows the error message to be passed in as a
315 parameter, rather than in an external variable. @emph{Provide grammatical
316 context for ``message.''}
318 The module reporting the error should be passed in via @var{whoami}.
319 If @var{format} is @code{(char *)NULL}, the formatted message will not be
320 printed. @var{format} may not be omitted.
325 void com_err_va (const char *@var{whoami}, long @var{error_code}, const char *@var{format}, va_list @var{args});
327 This routine provides an interface, equivalent to @code{com_err} above,
328 which may be used by higher-level variadic functions (functions which
329 accept variable numbers of arguments).
333 @deftypefun void (*set_com_err_hook (void (*@var{proc}) (const char *@var{whoami}, long @var{error_code}, va_list @var{args}))) (const char *@var{whoami}, long @var{error_code}, va_list @var{args});
335 @deftypefunx void reset_com_err_hook ();
337 These two routines allow a routine to be dynamically substituted for
338 @samp{com_err}. After @samp{set_com_err_hook} has been called,
339 calls to @samp{com_err} will turn into calls to the new hook routine.
340 @samp{reset_com_err_hook} turns off this hook. This may intended to
341 be used in daemons (to use a routine which calls @cite{syslog(3)}), or
342 in a window system application (which could pop up a dialogue box).
344 If a program is to be used in an environment in which simply printing
345 messages to the @code{stderr} stream would be inappropriate (such as in a
346 daemon program which runs without a terminal attached),
347 @code{set_com_err_hook} may be used to redirect output from @code{com_err}.
348 The following is an example of an error handler which uses @cite{syslog(3)}
349 as supplied in BSD 4.3:
356 /* extern openlog (const char * name, int logopt, int facility); */
357 /* extern syslog (int priority, char * message, ...); */
359 void hook (const char * whoami, long code,
360 const char * format, va_list args)
363 static int initialized = 0;
366 LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
370 vsprintf (buffer, format, args);
371 syslog (LOG_ERR, "%s %s", error_message (code), buffer);
375 After making the call
376 @code{set_com_err_hook (hook);},
377 any calls to @code{com_err} will result in messages being sent to the
378 @var{syslogd} daemon for logging.
379 The name of the program, @samp{whoami}, is supplied to the
380 @samp{openlog()} call, and the message is formatted into a buffer and
381 passed to @code{syslog}.
383 Note that since the extra arguments to @code{com_err} are passed by
384 reference via the @code{va_list} value @code{args}, the hook routine may
385 place any form of interpretation on them, including ignoring them. For
386 consistency, @code{printf}-style interpretation is suggested, via
387 @code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
392 @node Coding Conventions, Building and Installation, Run-time support routines, Top
393 @section Coding Conventions
395 The following conventions are just some general stylistic conventions
396 to follow when writing robust libraries and programs. Conventions
397 similar to this are generally followed inside the UNIX kernel and most
398 routines in the Multics operating system. In general, a routine
399 either succeeds (returning a zero error code, and doing some side
400 effects in the process), or it fails, doing minimal side effects; in
401 any event, any invariant which the library assumes must be maintained.
403 In general, it is not in the domain of non user-interface library
404 routines to write error messages to the user's terminal, or halt the
405 process. Such forms of ``error handling'' should be reserved for
406 failures of internal invariants and consistancy checks only, as it
407 provides the user of the library no way to clean up for himself in the
408 event of total failure.
410 Library routines which can fail should be set up to return an error
411 code. This should usually be done as the return value of the
412 function; if this is not acceptable, the routine should return a
413 ``null'' value, and put the error code into a parameter passed by
416 Routines which use the first style of interface can be used from
417 user-interface levels of a program as follows:
421 if ((code = initialize_world(getuid(), random())) != 0) @{
422 com_err("demo", code,
423 "when trying to initialize world");
426 if ((database = open_database("my_secrets", &code))==NULL) @{
427 com_err("demo", code,
428 "while opening my_secrets");
434 A caller which fails to check the return status is in error. It is
435 possible to look for code which ignores error returns by using lint;
436 look for error messages of the form ``foobar returns value which is
437 sometimes ignored'' or ``foobar returns value which is always
440 Since libraries may be built out of other libraries, it is often necessary
441 for the success of one routine to depend on another. When a lower level
442 routine returns an error code, the middle level routine has a few possible
443 options. It can simply return the error code to its caller after doing
444 some form of cleanup, it can substitute one of its own, or it can take
445 corrective action of its own and continue normally. For instance, a
446 library routine which makes a ``connect'' system call to make a network
447 connection may reflect the system error code @code{ECONNREFUSED}
448 (Connection refused) to its caller, or it may return a ``server not
449 available, try again later,'' or it may try a different server.
451 Cleanup which is typically necessary may include, but not be limited
452 to, freeing allocated memory which will not be needed any more,
453 unlocking concurrancy locks, dropping reference counts, closing file
454 descriptors, or otherwise undoing anything which the procedure did up
455 to this point. When there are a lot of things which can go wrong, it
456 is generally good to write one block of error-handling code which is
457 branched to, using a goto, in the event of failure. A common source
458 of errors in UNIX programs is failing to close file descriptors on
459 error returns; this leaves a number of ``zombied'' file descriptors
460 open, which eventually causes the process to run out of file
461 descriptors and fall over.
465 FILE *f1=NULL, *f2=NULL, *f3=NULL;
468 if ( (f1 = fopen(FILE1, "r")) == NULL) @{
477 if ( (f2 = fopen(FILE2, "w")) == NULL) @{
482 if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
488 * Do more processing.
503 @node Building and Installation, Bug Reports, Coding Conventions, Top
504 @section Building and Installation
506 The distribution of this package will probably be done as a compressed
507 ``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
508 Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
509 @t{profiled} should be created to hold objects compiled for profiling.
510 Running ``make all'' should then be sufficient to build the library and
511 error-table compiler. The files @samp{libcom_err.a},
512 @samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
513 installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
514 installed as manual pages.
516 @node Bug Reports, Acknowledgements, Building and Installation, Top
519 The principal author of this library is: Ken
520 Raeburn, @t{raeburn@@MIT.EDU}.
522 This version of the com_err library is being maintained by Theodore
523 Ts'o, and so bugs and comments should be sent to @t{tytso@@thunk.org}.
526 @node Acknowledgements, , Bug Reports, Top
527 @section Acknowledgements
529 I would like to thank: Bill Sommerfeld, for his help with some of this
530 documentation, and catching some of the bugs the first time around;
531 Honeywell Information Systems, for not killing off the @emph{Multics}
532 operating system before I had an opportunity to use it; Honeywell's
533 customers, who persuaded them not to do so, for a while; Ted Anderson of
534 CMU, for catching some problems before version 1.2 left the nest; Stan
535 Zanarotti and several others of MIT's Student Information Processing Board,
536 for getting us started with ``discuss,'' for which this package was
537 originally written; and everyone I've talked into --- I mean, asked to read
538 this document and the ``man'' pages.