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