blob: 748c7e23feec8fe5591ac30544602e0730b5f43d [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001\input texinfo @c -*-texinfo-*-
2
3@c $Header$
4@c $Source$
5@c $Locker$
6
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.
10@c
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.)
16
Theodore Ts'occfedb12013-01-02 10:06:09 -050017@setfilename com_err.info
Theodore Ts'o541d1732002-02-23 21:23:26 -050018@settitle A Common Error Description Library for UNIX
19
Theodore Ts'o3839e651997-04-26 13:21:57 +000020@ifinfo
Theodore Ts'o541d1732002-02-23 21:23:26 -050021@dircategory Development
Dmitry V. Levin710bac82007-10-20 22:09:13 +040022@direntry
Theodore Ts'o0d8b6732007-06-24 16:59:36 -040023* Com_err: (com_err). A Common Error Description Library for UNIX.
Dmitry V. Levin710bac82007-10-20 22:09:13 +040024@end direntry
Theodore Ts'o3839e651997-04-26 13:21:57 +000025@end ifinfo
26
Theodore Ts'occfedb12013-01-02 10:06:09 -050027@c smallbook
Theodore Ts'o3839e651997-04-26 13:21:57 +000028
Theodore Ts'occfedb12013-01-02 10:06:09 -050029@iftex
30@finalout
Theodore Ts'o3839e651997-04-26 13:21:57 +000031@end iftex
32
Theodore Ts'o3839e651997-04-26 13:21:57 +000033@ifinfo
34This file documents the use of the Common Error Description library.
35
36Copyright (C) 1987, 1988 Student Information Processing Board of the
37Massachusetts Institute of Technology.
38
39Permission to use, copy, modify, and distribute this software and its
40documentation for any purpose and without fee is hereby granted, provided
41that the above copyright notice appear in all copies and that both that
42copyright notice and this permission notice appear in supporting
43documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
44used in advertising or publicity pertaining to distribution of the software
45without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
46make no representations about the suitability of this software for any
47purpose. It is provided "as is" without express or implied warranty.
48
49Note that the file texinfo.tex, provided with this distribution, is from
50the Free Software Foundation, and is under different copyright restrictions
51from the remainder of this package.
52
Theodore Ts'o3839e651997-04-26 13:21:57 +000053@ignore
54Permission is granted to process this file through Tex and print the
55results, provided the printed document carries copying permission
56notice identical to this one except for the removal of this paragraph
57(this paragraph not being relevant to the printed manual).
58
59@end ignore
Theodore Ts'occfedb12013-01-02 10:06:09 -050060@end ifinfo
Theodore Ts'o3839e651997-04-26 13:21:57 +000061
62@setchapternewpage odd
63
64@titlepage
65@center @titlefont{A Common Error Description}
66@center @titlefont{Library for UNIX}
67@sp 2
68@center Ken Raeburn
69@center Bill Sommerfeld
70@sp 1
71@center MIT Student Information Processing Board
72@sp 3
73@center last updated 1 January 1989
74@center for version 1.2
75@center ***DRAFT COPY ONLY***
76
77@vskip 2in
78
79@center @b{Abstract}
80
81UNIX has always had a clean and simple system call interface, with a
82standard set of error codes passed between the kernel and user
83programs. Unfortunately, the same cannot be said of many of the
84libraries layered on top of the primitives provided by the kernel.
85Typically, each one has used a different style of indicating errors to
86their callers, leading to a total hodgepodge of error handling, and
87considerable amounts of work for the programmer. This paper describes
88a library and associated utilities which allows a more uniform way for
89libraries to return errors to their callers, and for programs to
90describe errors and exceptional conditions to their users.
91
92@page
93@vskip 0pt plus 1filll
94
95Copyright @copyright{} 1987, 1988 by the Student Information Processing
96Board of the Massachusetts Institute of Technology.
97
98Permission to use, copy, modify, and distribute this software and its
99documentation for any purpose and without fee is hereby granted, provided
100that the above copyright notice appear in all copies and that both that
101copyright notice and this permission notice appear in supporting
102documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
103used in advertising or publicity pertaining to distribution of the software
104without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
105make no representations about the suitability of this software for any
106purpose. It is provided "as is" without express or implied warranty.
107
108Note that the file texinfo.tex, provided with this distribution, is from
109the Free Software Foundation, and is under different copyright restrictions
110from the remainder of this package.
111
112@end titlepage
113
Theodore Ts'occfedb12013-01-02 10:06:09 -0500114@ifinfo
Theodore Ts'o5966f362001-09-11 00:38:03 -0400115@node Top, Why com_err?, (dir), (dir)
116
117@top A Common Error Description Library for UNIX
118
119This manual documents the com_err library.
120
121@menu
122* Why com_err?::
123* Error codes::
124* Error table source file::
125* The error-table compiler::
126* Run-time support routines::
127* Coding Conventions::
128* Building and Installation::
129* Bug Reports::
130* Acknowledgements::
131@end menu
132
Theodore Ts'occfedb12013-01-02 10:06:09 -0500133@page
Theodore Ts'o3839e651997-04-26 13:21:57 +0000134@end ifinfo
135
Theodore Ts'o5966f362001-09-11 00:38:03 -0400136@node Why com_err?, Error codes, Top, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500137@chapter Why com_err?
Theodore Ts'o3839e651997-04-26 13:21:57 +0000138
139In building application software packages, a programmer often has to
140deal with a number of libraries, each of which can use a different
141error-reporting mechanism. Sometimes one of two values is returned,
142indicating simply SUCCESS or FAILURE, with no description of errors
143encountered. Sometimes it is an index into a table of text strings,
144where the name of the table used is dependent on the library being
145used when the error is generated; since each table starts numbering at
1460 or 1, additional information as to the source of the error code is
147needed to determine which table to look at. Sometimes no text messages are
148supplied at all, and the programmer must supply them at any point at which
149he may wish to report error conditions.
150Often, a global variable is assigned some value describing the error, but
151the programmer has to know in each case whether to look at @code{errno},
152@code{h_errno}, the return value from @code{hes_err()}, or whatever other
153variables or routines are specified.
154And what happens if something
155in the procedure of
156examining or reporting the error changes the same variable?
157
158The package we have developed is an attempt to present a common
159error-handling mechanism to manipulate the most common form of error code
160in a fashion that does not have the problems listed above.
161
162A list of up to 256 text messages is supplied to a translator we have
163written, along with the three- to four-character ``name'' of the error
164table. The library using this error table need only call a routine
165generated from this error-table source to make the table ``known'' to the
166com_err library, and any error code the library generates can be converted
167to the corresponding error message. There is also a default format for
168error codes accidentally returned before making the table known, which is
169of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
170of the table.
171
Theodore Ts'o5966f362001-09-11 00:38:03 -0400172@node Error codes, Error table source file, Why com_err?, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500173@chapter Error codes
Theodore Ts'o3839e651997-04-26 13:21:57 +0000174
175Error codes themselves are 32 bit (signed) integers, of which the high
176order 24 bits are an identifier of which error table the error code is
177from, and the low order 8 bits are a sequential error number within
178the table. An error code may thus be easily decomposed into its component
179parts. Only the lowest 32 bits of an error code are considered significant
180on systems which support wider values.
181
182Error table 0 is defined to match the UNIX system call error table
183(@code{sys_errlist}); this allows @code{errno} values to be used directly
184in the library (assuming that @code{errno} is of a type with the same width
185as @t{long}). Other error table numbers are formed by compacting together
186the first four characters of the error table name. The mapping between
187characters in the name and numeric values in the error code are defined in
188a system-independent fashion, so that two systems that can pass integral
189values between them can reliably pass error codes without loss of meaning;
190this should work even if the character sets used are not the same.
191(However, if this is to be done, error table 0 should be avoided, since the
192local system call error tables may differ.)
193
194Any variable which is to contain an error code should be declared @t{long}.
195The draft proposed American National Standard for C (as of May, 1988)
196requires that @t{long} variables be at least 32 bits; any system which does
197not support 32-bit @t{long} values cannot make use of this package (nor
198much other software that assumes an ANSI-C environment base) without
199significant effort.
200
Theodore Ts'o5966f362001-09-11 00:38:03 -0400201@node Error table source file, The error-table compiler, Error codes, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500202@chapter Error table source file
Theodore Ts'o3839e651997-04-26 13:21:57 +0000203
204The error table source file begins with the declaration of the table name,
205as
206
207@example
208error_table @var{tablename}
209@end example
210
211Individual error codes are
212specified with
213
214@example
215error_code @var{ERROR_NAME}, @var{"text message"}
216@end example
217
218where @samp{ec} can also be used as a short form of @samp{error_code}. To
219indicate the end of the table, use @samp{end}. Thus, a (short) sample
220error table might be:
221
222@example
223
224 error_table dsc
225
226 error_code DSC_DUP_MTG_NAME,
227 "Meeting already exists"
228
229 ec DSC_BAD_PATH,
230 "A bad meeting pathname was given"
231
232 ec DSC_BAD_MODES,
233 "Invalid mode for this access control list"
234
235 end
236
237@end example
238
Theodore Ts'o5966f362001-09-11 00:38:03 -0400239@node The error-table compiler, Run-time support routines, Error table source file, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500240@chapter The error-table compiler
Theodore Ts'o3839e651997-04-26 13:21:57 +0000241
242The error table compiler is named @code{compile_et}. It takes one
243argument, the pathname of a file (ending in @samp{.et}, e.g.,
244@samp{dsc_err.et}) containing an error table source file. It parses the
245error table, and generates two output files -- a C header file
246(@samp{discuss_err.h}) which contains definitions of the numerical values
247of the error codes defined in the error table, and a C source file which
248should be compiled and linked with the executable. The header file must be
249included in the source of a module which wishes to reference the error
250codes defined; the object module generated from the C code may be linked in
251to a program which wishes to use the printed forms of the error codes.
252
Theodore Ts'o5966f362001-09-11 00:38:03 -0400253@node Run-time support routines, Coding Conventions, The error-table compiler, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500254@chapter Run-time support routines
Theodore Ts'o3839e651997-04-26 13:21:57 +0000255
256Any source file which uses the routines supplied with or produced by the
257com_err package should include the header file @file{<com_err.h>}. It
258contains declarations and definitions which may be needed on some systems.
259(Some functions cannot be referenced properly without the return type
260declarations in this file. Some functions may work properly on most
261architectures even without the header file, but relying on this is not
262recommended.)
263
264The run-time support routines and variables provided via this package
265include the following:
266
267@example
268void initialize_@var{xxxx}_error_table (void);
269@end example
270
271One of these routines is built by the error compiler for each error table.
272It makes the @var{xxxx} error table ``known'' to the error reporting
273system. By convention, this routine should be called in the initialization
274routine of the @var{xxxx} library. If the library has no initialization
275routine, some combination of routines which form the core of the library
276should ensure that this routine is called. It is not advised to leave it
277the caller to make this call.
278
279There is no harm in calling this routine more than once.
280
281@example
282#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
283@end example
284
285This symbol contains the value of the first error code entry in the
286specified table.
287This rarely needs be used by the
288programmer.
289
Theodore Ts'o5966f362001-09-11 00:38:03 -0400290@deftypefun const char *error_message (long @var{code});
Theodore Ts'o3839e651997-04-26 13:21:57 +0000291
292This routine returns the character string error message associated
293with @code{code}; if this is associated with an unknown error table, or
294if the code is associated with a known error table but the code is not
295in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
296returned, where @var{xxxx} is the error table name produced by
297reversing the compaction performed on the error table number implied
298by that error code, and @var{nn} is the offset from that base value.
299
300Although this routine is available for use when needed, its use should be
301left to circumstances which render @code{com_err} (below) unusable.
302
Theodore Ts'o5966f362001-09-11 00:38:03 -0400303@end deftypefun
304
Theodore Ts'occfedb12013-01-02 10:06:09 -0500305@deftypefun void com_err (const char *@var{whoami}, long @var{error_code}, const char *@var{format}, ...);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000306
307This routine provides an alternate way to print error messages to
308standard error; it allows the error message to be passed in as a
309parameter, rather than in an external variable. @emph{Provide grammatical
310context for ``message.''}
311
Theodore Ts'o5966f362001-09-11 00:38:03 -0400312The module reporting the error should be passed in via @var{whoami}.
Theodore Ts'o3839e651997-04-26 13:21:57 +0000313If @var{format} is @code{(char *)NULL}, the formatted message will not be
314printed. @var{format} may not be omitted.
315
Theodore Ts'o5966f362001-09-11 00:38:03 -0400316@end deftypefun
Theodore Ts'o3839e651997-04-26 13:21:57 +0000317
Theodore Ts'occfedb12013-01-02 10:06:09 -0500318@deftypefun void com_err_va (const char *@var{whoami}, long @var{error_code}, const char *@var{format}, va_list @var{args});
Theodore Ts'o3839e651997-04-26 13:21:57 +0000319
320This routine provides an interface, equivalent to @code{com_err} above,
321which may be used by higher-level variadic functions (functions which
322accept variable numbers of arguments).
323
Theodore Ts'o5966f362001-09-11 00:38:03 -0400324@end deftypefun
Theodore Ts'o3839e651997-04-26 13:21:57 +0000325
Theodore Ts'occfedb12013-01-02 10:06:09 -0500326@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}));
Theodore Ts'o3839e651997-04-26 13:21:57 +0000327
Theodore Ts'o5966f362001-09-11 00:38:03 -0400328@deftypefunx void reset_com_err_hook ();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000329
330These two routines allow a routine to be dynamically substituted for
331@samp{com_err}. After @samp{set_com_err_hook} has been called,
332calls to @samp{com_err} will turn into calls to the new hook routine.
333@samp{reset_com_err_hook} turns off this hook. This may intended to
Theodore Ts'o5966f362001-09-11 00:38:03 -0400334be used in daemons (to use a routine which calls @cite{syslog(3)}), or
Theodore Ts'o3839e651997-04-26 13:21:57 +0000335in a window system application (which could pop up a dialogue box).
336
337If a program is to be used in an environment in which simply printing
338messages to the @code{stderr} stream would be inappropriate (such as in a
339daemon program which runs without a terminal attached),
340@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
Theodore Ts'o5966f362001-09-11 00:38:03 -0400341The following is an example of an error handler which uses @cite{syslog(3)}
Theodore Ts'o3839e651997-04-26 13:21:57 +0000342as supplied in BSD 4.3:
343
344@example
345#include <stdio.h>
346#include <stdarg.h>
347#include <syslog.h>
348
349/* extern openlog (const char * name, int logopt, int facility); */
350/* extern syslog (int priority, char * message, ...); */
351
352void hook (const char * whoami, long code,
353 const char * format, va_list args)
354@{
355 char buffer[BUFSIZ];
356 static int initialized = 0;
357 if (!initialized) @{
358 openlog (whoami,
359 LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
360 LOG_DAEMON);
361 initialized = 1;
362 @}
363 vsprintf (buffer, format, args);
364 syslog (LOG_ERR, "%s %s", error_message (code), buffer);
365@}
366@end example
367
368After making the call
369@code{set_com_err_hook (hook);},
370any calls to @code{com_err} will result in messages being sent to the
371@var{syslogd} daemon for logging.
372The name of the program, @samp{whoami}, is supplied to the
373@samp{openlog()} call, and the message is formatted into a buffer and
374passed to @code{syslog}.
375
376Note that since the extra arguments to @code{com_err} are passed by
377reference via the @code{va_list} value @code{args}, the hook routine may
378place any form of interpretation on them, including ignoring them. For
379consistency, @code{printf}-style interpretation is suggested, via
380@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
381the ANSI C library).
382
Theodore Ts'o5966f362001-09-11 00:38:03 -0400383@end deftypefun
384
385@node Coding Conventions, Building and Installation, Run-time support routines, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500386@chapter Coding Conventions
Theodore Ts'o3839e651997-04-26 13:21:57 +0000387
388The following conventions are just some general stylistic conventions
389to follow when writing robust libraries and programs. Conventions
390similar to this are generally followed inside the UNIX kernel and most
391routines in the Multics operating system. In general, a routine
392either succeeds (returning a zero error code, and doing some side
393effects in the process), or it fails, doing minimal side effects; in
394any event, any invariant which the library assumes must be maintained.
395
396In general, it is not in the domain of non user-interface library
397routines to write error messages to the user's terminal, or halt the
398process. Such forms of ``error handling'' should be reserved for
399failures of internal invariants and consistancy checks only, as it
400provides the user of the library no way to clean up for himself in the
401event of total failure.
402
403Library routines which can fail should be set up to return an error
404code. This should usually be done as the return value of the
405function; if this is not acceptable, the routine should return a
406``null'' value, and put the error code into a parameter passed by
407reference.
408
409Routines which use the first style of interface can be used from
410user-interface levels of a program as follows:
411
412@example
413@{
414 if ((code = initialize_world(getuid(), random())) != 0) @{
415 com_err("demo", code,
416 "when trying to initialize world");
417 exit(1);
418 @}
419 if ((database = open_database("my_secrets", &code))==NULL) @{
420 com_err("demo", code,
421 "while opening my_secrets");
422 exit(1);
423 @}
424@}
425@end example
426
427A caller which fails to check the return status is in error. It is
428possible to look for code which ignores error returns by using lint;
429look for error messages of the form ``foobar returns value which is
430sometimes ignored'' or ``foobar returns value which is always
431ignored.''
432
433Since libraries may be built out of other libraries, it is often necessary
434for the success of one routine to depend on another. When a lower level
435routine returns an error code, the middle level routine has a few possible
436options. It can simply return the error code to its caller after doing
437some form of cleanup, it can substitute one of its own, or it can take
438corrective action of its own and continue normally. For instance, a
439library routine which makes a ``connect'' system call to make a network
440connection may reflect the system error code @code{ECONNREFUSED}
441(Connection refused) to its caller, or it may return a ``server not
442available, try again later,'' or it may try a different server.
443
444Cleanup which is typically necessary may include, but not be limited
445to, freeing allocated memory which will not be needed any more,
446unlocking concurrancy locks, dropping reference counts, closing file
447descriptors, or otherwise undoing anything which the procedure did up
448to this point. When there are a lot of things which can go wrong, it
449is generally good to write one block of error-handling code which is
450branched to, using a goto, in the event of failure. A common source
451of errors in UNIX programs is failing to close file descriptors on
452error returns; this leaves a number of ``zombied'' file descriptors
453open, which eventually causes the process to run out of file
454descriptors and fall over.
455
456@example
457@{
458 FILE *f1=NULL, *f2=NULL, *f3=NULL;
459 int status = 0;
460
461 if ( (f1 = fopen(FILE1, "r")) == NULL) @{
462 status = errno;
463 goto error;
464 @}
465
466 /*
467 * Crunch for a while
468 */
469
470 if ( (f2 = fopen(FILE2, "w")) == NULL) @{
471 status = errno;
472 goto error;
473 @}
474
475 if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
476 status = errno;
477 goto error;
478 @}
479
480 /*
481 * Do more processing.
482 */
483 fclose(f1);
484 fclose(f2);
485 fclose(f3);
486 return 0;
487
488error:
489 if (f1) fclose(f1);
490 if (f2) fclose(f2);
491 if (f3) fclose(f3);
492 return status;
493@}
494@end example
495
Theodore Ts'o5966f362001-09-11 00:38:03 -0400496@node Building and Installation, Bug Reports, Coding Conventions, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500497@chapter Building and Installation
Theodore Ts'o3839e651997-04-26 13:21:57 +0000498
499The distribution of this package will probably be done as a compressed
500``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
501Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
502@t{profiled} should be created to hold objects compiled for profiling.
503Running ``make all'' should then be sufficient to build the library and
504error-table compiler. The files @samp{libcom_err.a},
505@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
506installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
507installed as manual pages.
508
Theodore Ts'o5966f362001-09-11 00:38:03 -0400509@node Bug Reports, Acknowledgements, Building and Installation, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500510@chapter Bug Reports
Theodore Ts'o3839e651997-04-26 13:21:57 +0000511
Theodore Ts'o5966f362001-09-11 00:38:03 -0400512The principal author of this library is: Ken
513Raeburn, @t{raeburn@@MIT.EDU}.
Theodore Ts'o3839e651997-04-26 13:21:57 +0000514
Theodore Ts'o5966f362001-09-11 00:38:03 -0400515This version of the com_err library is being maintained by Theodore
516Ts'o, and so bugs and comments should be sent to @t{tytso@@thunk.org}.
517
518
519@node Acknowledgements, , Bug Reports, Top
Theodore Ts'occfedb12013-01-02 10:06:09 -0500520@chapter Acknowledgements
Theodore Ts'o3839e651997-04-26 13:21:57 +0000521
522I would like to thank: Bill Sommerfeld, for his help with some of this
523documentation, and catching some of the bugs the first time around;
524Honeywell Information Systems, for not killing off the @emph{Multics}
525operating system before I had an opportunity to use it; Honeywell's
526customers, who persuaded them not to do so, for a while; Ted Anderson of
527CMU, for catching some problems before version 1.2 left the nest; Stan
528Zanarotti and several others of MIT's Student Information Processing Board,
529for getting us started with ``discuss,'' for which this package was
530originally written; and everyone I've talked into --- I mean, asked to read
531this document and the ``man'' pages.
532
Theodore Ts'o4534f8b2009-11-29 20:19:10 -0500533@contents
Theodore Ts'o3839e651997-04-26 13:21:57 +0000534@bye