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