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