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