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