15622Swollman\input texinfo @c -*-texinfo-*-
25622Swollman
350488Speter@c $FreeBSD$
45622Swollman
55622Swollman@c Note that although this source file is in texinfo format (more
65622Swollman@c or less), it is not yet suitable for turning into an ``info''
75622Swollman@c file.  Sorry, maybe next time.
85622Swollman@c
95622Swollman@c In order to produce hardcopy documentation from a texinfo file,
105622Swollman@c run ``tex com_err.texinfo'' which will load in texinfo.tex,
115622Swollman@c provided in this distribution.  (texinfo.tex is from the Free
125622Swollman@c Software Foundation, and is under different copyright restrictions
135622Swollman@c from the rest of this package.)
145622Swollman
155622Swollman@ifinfo
165622Swollman@barfo
175622Swollman@end ifinfo
185622Swollman
195622Swollman@iftex
205622Swollman@tolerance 10000
215622Swollman
225622Swollman@c Mutate section headers...
235622Swollman@begingroup
245622Swollman  @catcode#=6
255622Swollman  @gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
265622Swollman@endgroup
275622Swollman@end iftex
285622Swollman
2922176Sjoerg@c %**start of header (This is for running Texinfo on a region.)
305622Swollman@setfilename com_err
315622Swollman@settitle A Common Error Description Library for UNIX
3222176Sjoerg@c %**end of header (This is for running Texinfo on a region.)
335622Swollman
345622Swollman@ifinfo
355622SwollmanThis file documents the use of the Common Error Description library.
365622Swollman
375622SwollmanCopyright (C) 1987, 1988 Student Information Processing Board of the
385622SwollmanMassachusetts Institute of Technology.
395622Swollman
405622SwollmanPermission to use, copy, modify, and distribute this software and its
415622Swollmandocumentation for any purpose and without fee is hereby granted, provided
425622Swollmanthat the above copyright notice appear in all copies and that both that
435622Swollmancopyright notice and this permission notice appear in supporting
445622Swollmandocumentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
455622Swollmanused in advertising or publicity pertaining to distribution of the software
465622Swollmanwithout specific, written prior permission.  M.I.T. and the M.I.T. S.I.P.B.
475622Swollmanmake no representations about the suitability of this software for any
485622Swollmanpurpose.  It is provided "as is" without express or implied warranty.
495622Swollman
505622SwollmanNote that the file texinfo.tex, provided with this distribution, is from
515622Swollmanthe Free Software Foundation, and is under different copyright restrictions
525622Swollmanfrom the remainder of this package.
535622Swollman
545622Swollman@end ifinfo
555622Swollman
565622Swollman@ignore
575622SwollmanPermission is granted to process this file through Tex and print the
585622Swollmanresults, provided the printed document carries copying permission
595622Swollmannotice identical to this one except for the removal of this paragraph
605622Swollman(this paragraph not being relevant to the printed manual).
615622Swollman
625622Swollman@end ignore
635622Swollman
645622Swollman@setchapternewpage odd
655622Swollman
665622Swollman@titlepage
675622Swollman@center @titlefont{A Common Error Description}
685622Swollman@center @titlefont{Library for UNIX}
695622Swollman@sp 2
705622Swollman@center Ken Raeburn
715622Swollman@center Bill Sommerfeld
725622Swollman@sp 1
735622Swollman@center MIT Student Information Processing Board
745622Swollman@sp 3
755622Swollman@center last updated 1 January 1989
765622Swollman@center for version 1.2
775622Swollman@center ***DRAFT COPY ONLY***
785622Swollman
795622Swollman@vskip 2in
805622Swollman
815622Swollman@center @b{Abstract}
825622Swollman
835622SwollmanUNIX has always had a clean and simple system call interface, with a
845622Swollmanstandard set of error codes passed between the kernel and user
855622Swollmanprograms.  Unfortunately, the same cannot be said of many of the
865622Swollmanlibraries layered on top of the primitives provided by the kernel.
875622SwollmanTypically, each one has used a different style of indicating errors to
885622Swollmantheir callers, leading to a total hodgepodge of error handling, and
895622Swollmanconsiderable amounts of work for the programmer.  This paper describes
905622Swollmana library and associated utilities which allows a more uniform way for
915622Swollmanlibraries to return errors to their callers, and for programs to
925622Swollmandescribe errors and exceptional conditions to their users.
935622Swollman
945622Swollman@page
955622Swollman@vskip 0pt plus 1filll
965622Swollman
975622SwollmanCopyright @copyright{} 1987, 1988 by the Student Information Processing
985622SwollmanBoard of the Massachusetts Institute of Technology.
995622Swollman
1005622SwollmanPermission to use, copy, modify, and distribute this software and its
1015622Swollmandocumentation for any purpose and without fee is hereby granted, provided
1025622Swollmanthat the above copyright notice appear in all copies and that both that
1035622Swollmancopyright notice and this permission notice appear in supporting
1045622Swollmandocumentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
1055622Swollmanused in advertising or publicity pertaining to distribution of the software
1065622Swollmanwithout specific, written prior permission.  M.I.T. and the M.I.T. S.I.P.B.
1075622Swollmanmake no representations about the suitability of this software for any
1085622Swollmanpurpose.  It is provided "as is" without express or implied warranty.
1095622Swollman
1105622SwollmanNote that the file texinfo.tex, provided with this distribution, is from
1115622Swollmanthe Free Software Foundation, and is under different copyright restrictions
1125622Swollmanfrom the remainder of this package.
1135622Swollman
1145622Swollman@end titlepage
1155622Swollman
1165622Swollman@ifinfo
11722176Sjoerg@node Top, Why com_err?, (dir), (dir)
11822176Sjoerg@comment  node-name,  next,  previous,  up
11922176Sjoerg@top General Introduction
12022176Sjoerg
12122176Sjoerg@menu
12222176Sjoerg* Why com_err?::                What is all this for?
12322176Sjoerg* Error codes::                 What's an error code, anyway?
12422176Sjoerg* Error table source file::     How to describe an error table.
12522176Sjoerg* The error-table compiler::    How to compile the table.
12622176Sjoerg* Run-time support routines::   How to use from within your program.
12722176Sjoerg* Coding Conventions::          Stylistic issues.
12822176Sjoerg* Building and Installation::   How to build and install.
12922176Sjoerg* Bug Reports::                 You have found a bug?  Report it.
13022176Sjoerg* Acknowledgements::            Whom to thank...
13122176Sjoerg
13222176Sjoerg@end menu
13322176Sjoerg
1345622Swollman@end ifinfo
1355622Swollman
1365622Swollman@page
1375622Swollman
13822176Sjoerg@ifinfo
13922176Sjoerg@node Why com_err?, Error codes, Top, (dir)
14022176Sjoerg@comment  node-name,  next,  previous,  up
14122176Sjoerg@end ifinfo
14222176Sjoerg
1435622Swollman@section Why com_err?
1445622Swollman
1455622SwollmanIn building application software packages, a programmer often has to
1465622Swollmandeal with a number of libraries, each of which can use a different
1475622Swollmanerror-reporting mechanism.  Sometimes one of two values is returned,
1485622Swollmanindicating simply SUCCESS or FAILURE, with no description of errors
1495622Swollmanencountered.  Sometimes it is an index into a table of text strings,
1505622Swollmanwhere the name of the table used is dependent on the library being
1515622Swollmanused when the error is generated; since each table starts numbering at
1525622Swollman0 or 1, additional information as to the source of the error code is
1535622Swollmanneeded to determine which table to look at.  Sometimes no text messages are
1545622Swollmansupplied at all, and the programmer must supply them at any point at which
1555622Swollmanhe may wish to report error conditions.
1565622SwollmanOften, a global variable is assigned some value describing the error, but
1575622Swollmanthe programmer has to know in each case whether to look at @code{errno},
1585622Swollman@code{h_errno}, the return value from @code{hes_err()}, or whatever other
1595622Swollmanvariables or routines are specified.
1605622SwollmanAnd what happens if something
1615622Swollmanin the procedure of
1625622Swollmanexamining or reporting the error changes the same variable?
1635622Swollman
1645622SwollmanThe package we have developed is an attempt to present a common
1655622Swollmanerror-handling mechanism to manipulate the most common form of error code
1665622Swollmanin a fashion that does not have the problems listed above.
1675622Swollman
1685622SwollmanA list of up to 256 text messages is supplied to a translator we have
1695622Swollmanwritten, along with the three- to four-character ``name'' of the error
1705622Swollmantable.  The library using this error table need only call a routine
1715622Swollmangenerated from this error-table source to make the table ``known'' to the
1725622Swollmancom_err library, and any error code the library generates can be converted
1735622Swollmanto the corresponding error message.  There is also a default format for
1745622Swollmanerror codes accidentally returned before making the table known, which is
1755622Swollmanof the form @samp{unknown code foo 32}, where @samp{foo} would be the name
1765622Swollmanof the table.
1775622Swollman
17822176Sjoerg@ifinfo
17922176Sjoerg@node Error codes, Error table source file, Why com_err?, (dir)
18022176Sjoerg@comment  node-name,  next,  previous,  up
18122176Sjoerg@end ifinfo
18222176Sjoerg
1835622Swollman@section Error codes
1845622Swollman
1855622SwollmanError codes themselves are 32 bit (signed) integers, of which the high
1865622Swollmanorder 24 bits are an identifier of which error table the error code is
1875622Swollmanfrom, and the low order 8 bits are a sequential error number within
1885622Swollmanthe table.  An error code may thus be easily decomposed into its component
1895622Swollmanparts.  Only the lowest 32 bits of an error code are considered significant
1905622Swollmanon systems which support wider values.
1915622Swollman
1925622SwollmanError table 0 is defined to match the UNIX system call error table
1935622Swollman(@code{sys_errlist}); this allows @code{errno} values to be used directly
1945622Swollmanin the library (assuming that @code{errno} is of a type with the same width
1955622Swollmanas @t{long}).  Other error table numbers are formed by compacting together
1965622Swollmanthe first four characters of the error table name.  The mapping between
1975622Swollmancharacters in the name and numeric values in the error code are defined in
1985622Swollmana system-independent fashion, so that two systems that can pass integral
1995622Swollmanvalues between them can reliably pass error codes without loss of meaning;
2005622Swollmanthis should work even if the character sets used are not the same.
2015622Swollman(However, if this is to be done, error table 0 should be avoided, since the
2025622Swollmanlocal system call error tables may differ.)
2035622Swollman
2045622SwollmanAny variable which is to contain an error code should be declared @t{long}.
2055622SwollmanThe draft proposed American National Standard for C (as of May, 1988)
2065622Swollmanrequires that @t{long} variables be at least 32 bits; any system which does
2075622Swollmannot support 32-bit @t{long} values cannot make use of this package (nor
2085622Swollmanmuch other software that assumes an ANSI-C environment base) without
2095622Swollmansignificant effort.
2105622Swollman
21122176Sjoerg@ifinfo
21222176Sjoerg@node Error table source file, The error-table compiler, Error codes, (dir)
21322176Sjoerg@comment  node-name,  next,  previous,  up
21422176Sjoerg@end ifinfo
21522176Sjoerg
2165622Swollman@section Error table source file
2175622Swollman
2185622SwollmanThe error table source file begins with the declaration of the table name,
2195622Swollmanas
2205622Swollman
2215622Swollman@example
2225622Swollmanerror_table @var{tablename}
2235622Swollman@end example
2245622Swollman
2255622SwollmanIndividual error codes are
2265622Swollmanspecified with
2275622Swollman
2285622Swollman@example
2295622Swollmanerror_code @var{ERROR_NAME}, @var{"text message"}
2305622Swollman@end example
2315622Swollman
2325622Swollmanwhere @samp{ec} can also be used as a short form of @samp{error_code}.  To
2335622Swollmanindicate the end of the table, use @samp{end}.  Thus, a (short) sample
2345622Swollmanerror table might be:
2355622Swollman
2365622Swollman@example
2375622Swollman
2385622Swollman        error_table     dsc
2395622Swollman
2405622Swollman        error_code      DSC_DUP_MTG_NAME,
2415622Swollman                        "Meeting already exists"
2425622Swollman
2435622Swollman        ec              DSC_BAD_PATH,
2445622Swollman                        "A bad meeting pathname was given"
2455622Swollman
2465622Swollman        ec              DSC_BAD_MODES,
2475622Swollman                        "Invalid mode for this access control list"
2485622Swollman
2495622Swollman        end
2505622Swollman
2515622Swollman@end example
2525622Swollman
25322176Sjoerg@ifinfo
25422176Sjoerg@node The error-table compiler, Run-time support routines, Error table source file, (dir)
25522176Sjoerg@comment  node-name,  next,  previous,  up
25622176Sjoerg@end ifinfo
25722176Sjoerg
2585622Swollman@section The error-table compiler
2595622Swollman
2605622SwollmanThe error table compiler is named @code{compile_et}.  It takes one
2615622Swollmanargument, the pathname of a file (ending in @samp{.et}, e.g.,
2625622Swollman@samp{dsc_err.et}) containing an error table source file.  It parses the
2635622Swollmanerror table, and generates two output files -- a C header file
2645622Swollman(@samp{discuss_err.h}) which contains definitions of the numerical values
2655622Swollmanof the error codes defined in the error table, and a C source file which
2665622Swollmanshould be compiled and linked with the executable.  The header file must be
2675622Swollmanincluded in the source of a module which wishes to reference the error
2685622Swollmancodes defined; the object module generated from the C code may be linked in
2695622Swollmanto a program which wishes to use the printed forms of the error codes.
2705622Swollman
2715622SwollmanThis translator accepts a @kbd{-language @var{lang}} argument, which
2725622Swollmandetermines for which language (or language variant) the output should be
2735622Swollmanwritten.  At the moment, @var{lang} is currently limited to @kbd{ANSI-C}
2745622Swollmanand @kbd{K&R-C}, and some abbreviated forms of each.  Eventually, this will
2755622Swollmanbe extended to include some support for C++.  The default is currently
2765622Swollman@kbd{K&R-C}, though the generated sources will have ANSI-C code
2775622Swollmanconditionalized on the symbol @t{__STDC__}.
2785622Swollman
27922176Sjoerg@ifinfo
28022176Sjoerg@node Run-time support routines, Coding Conventions, The error-table compiler, (dir)
28122176Sjoerg@comment  node-name,  next,  previous,  up
28222176Sjoerg@end ifinfo
28322176Sjoerg
2845622Swollman@section Run-time support routines
2855622Swollman
2865622SwollmanAny source file which uses the routines supplied with or produced by the
2875622Swollmancom_err package should include the header file @file{<com_err.h>}.  It
2885622Swollmancontains declarations and definitions which may be needed on some systems.
2895622Swollman(Some functions cannot be referenced properly without the return type
2905622Swollmandeclarations in this file.  Some functions may work properly on most
2915622Swollmanarchitectures even without the header file, but relying on this is not
2925622Swollmanrecommended.)
2935622Swollman
2945622SwollmanThe run-time support routines and variables provided via this package
2955622Swollmaninclude the following:
2965622Swollman
2975622Swollman@example
2985622Swollmanvoid initialize_@var{xxxx}_error_table (void);
2995622Swollman@end example
3005622Swollman
3015622SwollmanOne of these routines is built by the error compiler for each error table.
3025622SwollmanIt makes the @var{xxxx} error table ``known'' to the error reporting
3035622Swollmansystem.  By convention, this routine should be called in the initialization
3045622Swollmanroutine of the @var{xxxx} library.  If the library has no initialization
3055622Swollmanroutine, some combination of routines which form the core of the library
3065622Swollmanshould ensure that this routine is called.  It is not advised to leave it
3075622Swollmanthe caller to make this call.
3085622Swollman
3095622SwollmanThere is no harm in calling this routine more than once.
3105622Swollman
3115622Swollman@example
3125622Swollman#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
3135622Swollman@end example
3145622Swollman
3155622SwollmanThis symbol contains the value of the first error code entry in the
3165622Swollmanspecified table.
3175622SwollmanThis rarely needs be used by the
3185622Swollmanprogrammer.
3195622Swollman
3205622Swollman@example
3215622Swollmanconst char *error_message (long code);
3225622Swollman@end example
3235622Swollman
3245622SwollmanThis routine returns the character string error message associated
3255622Swollmanwith @code{code}; if this is associated with an unknown error table, or
3265622Swollmanif the code is associated with a known error table but the code is not
3275622Swollmanin the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
3285622Swollmanreturned, where @var{xxxx} is the error table name produced by
3295622Swollmanreversing the compaction performed on the error table number implied
3305622Swollmanby that error code, and @var{nn} is the offset from that base value.
3315622Swollman
3325622SwollmanAlthough this routine is available for use when needed, its use should be
3335622Swollmanleft to circumstances which render @code{com_err} (below) unusable.
3345622Swollman
3355622Swollman@example
3365622Swollmanvoid com_err (const char *whoami,  /* module reporting error */
3375622Swollman              long code,           /* error code */
3385622Swollman              const char *format,  /* format for additional detail */
3395622Swollman              ...);                /*  (extra parameters) */
3405622Swollman@end example
3415622Swollman
3425622SwollmanThis routine provides an alternate way to print error messages to
3435622Swollmanstandard error; it allows the error message to be passed in as a
3445622Swollmanparameter, rather than in an external variable.  @emph{Provide grammatical
3455622Swollmancontext for ``message.''}
3465622Swollman
3475622SwollmanIf @var{format} is @code{(char *)NULL}, the formatted message will not be
3485622Swollmanprinted.  @var{format} may not be omitted.
3495622Swollman
3505622Swollman@example
3515622Swollman#include <stdarg.h>
3525622Swollman
3535622Swollmanvoid com_err_va (const char *whoami,
3545622Swollman                 long code,
3555622Swollman                 const char *format,
3565622Swollman                 va_list args);
3575622Swollman@end example
3585622Swollman
3595622SwollmanThis routine provides an interface, equivalent to @code{com_err} above,
3605622Swollmanwhich may be used by higher-level variadic functions (functions which
3615622Swollmanaccept variable numbers of arguments).
3625622Swollman
3635622Swollman@example
3645622Swollman#include <stdarg.h>
3655622Swollman
3665622Swollmanvoid (*set_com_err_hook (void (*proc) ())) ();
3675622Swollman
3685622Swollmanvoid (*@var{proc}) (const char *whoami, long code, va_list args);
3695622Swollman
3705622Swollmanvoid reset_com_err_hook ();
3715622Swollman@end example
3725622Swollman
3735622SwollmanThese two routines allow a routine to be dynamically substituted for
3745622Swollman@samp{com_err}.  After @samp{set_com_err_hook} has been called,
3755622Swollmancalls to @samp{com_err} will turn into calls to the new hook routine.
3765622Swollman@samp{reset_com_err_hook} turns off this hook.  This may intended to
3775622Swollmanbe used in daemons (to use a routine which calls @var{syslog(3)}), or
3785622Swollmanin a window system application (which could pop up a dialogue box).
3795622Swollman
3805622SwollmanIf a program is to be used in an environment in which simply printing
3815622Swollmanmessages to the @code{stderr} stream would be inappropriate (such as in a
3825622Swollmandaemon program which runs without a terminal attached),
3835622Swollman@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
3845622SwollmanThe following is an example of an error handler which uses @var{syslog(3)}
3855622Swollmanas supplied in BSD 4.3:
3865622Swollman
3875622Swollman@example
3885622Swollman#include <stdio.h>
3895622Swollman#include <stdarg.h>
3905622Swollman#include <syslog.h>
3915622Swollman
3925622Swollman/* extern openlog (const char * name, int logopt, int facility); */
3935622Swollman/* extern syslog (int priority, char * message, ...); */
3945622Swollman
3955622Swollmanvoid hook (const char * whoami, long code,
3965622Swollman           const char * format, va_list args)
3975622Swollman@{
3985622Swollman    char buffer[BUFSIZ];
3995622Swollman    static int initialized = 0;
4005622Swollman    if (!initialized) @{
4015622Swollman        openlog (whoami,
4025622Swollman                 LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
4035622Swollman                 LOG_DAEMON);
4045622Swollman        initialized = 1;
4055622Swollman    @}
4065622Swollman    vsprintf (buffer, format, args);
4075622Swollman    syslog (LOG_ERR, "%s %s", error_message (code), buffer);
4085622Swollman@}
4095622Swollman@end example
4105622Swollman
4115622SwollmanAfter making the call
4125622Swollman@code{set_com_err_hook (hook);},
4135622Swollmanany calls to @code{com_err} will result in messages being sent to the
4145622Swollman@var{syslogd} daemon for logging.
4155622SwollmanThe name of the program, @samp{whoami}, is supplied to the
4165622Swollman@samp{openlog()} call, and the message is formatted into a buffer and
4175622Swollmanpassed to @code{syslog}.
4185622Swollman
4195622SwollmanNote that since the extra arguments to @code{com_err} are passed by
4205622Swollmanreference via the @code{va_list} value @code{args}, the hook routine may
4215622Swollmanplace any form of interpretation on them, including ignoring them.  For
4225622Swollmanconsistency, @code{printf}-style interpretation is suggested, via
4235622Swollman@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
4245622Swollmanthe ANSI C library).
4255622Swollman
42622176Sjoerg@ifinfo
42722176Sjoerg@node Coding Conventions, Building and Installation, Run-time support routines, (dir)
42822176Sjoerg@comment  node-name,  next,  previous,  up
42922176Sjoerg@end ifinfo
43022176Sjoerg
4315622Swollman@section Coding Conventions
4325622Swollman
4335622SwollmanThe following conventions are just some general stylistic conventions
4345622Swollmanto follow when writing robust libraries and programs.  Conventions
4355622Swollmansimilar to this are generally followed inside the UNIX kernel and most
4365622Swollmanroutines in the Multics operating system.  In general, a routine
4375622Swollmaneither succeeds (returning a zero error code, and doing some side
4385622Swollmaneffects in the process), or it fails, doing minimal side effects; in
4395622Swollmanany event, any invariant which the library assumes must be maintained.
4405622Swollman
4415622SwollmanIn general, it is not in the domain of non user-interface library
4425622Swollmanroutines to write error messages to the user's terminal, or halt the
4435622Swollmanprocess.  Such forms of ``error handling'' should be reserved for
4445622Swollmanfailures of internal invariants and consistancy checks only, as it
4455622Swollmanprovides the user of the library no way to clean up for himself in the
4465622Swollmanevent of total failure.
4475622Swollman
4485622SwollmanLibrary routines which can fail should be set up to return an error
4495622Swollmancode.  This should usually be done as the return value of the
4505622Swollmanfunction; if this is not acceptable, the routine should return a
4515622Swollman``null'' value, and put the error code into a parameter passed by
4525622Swollmanreference.
4535622Swollman
4545622SwollmanRoutines which use the first style of interface can be used from
4555622Swollmanuser-interface levels of a program as follows:
4565622Swollman
4575622Swollman@example
4585622Swollman@{
4595622Swollman    if ((code = initialize_world(getuid(), random())) != 0) @{
4605622Swollman        com_err("demo", code,
4615622Swollman                "when trying to initialize world");
4625622Swollman        exit(1);
4635622Swollman    @}
4645622Swollman    if ((database = open_database("my_secrets", &code))==NULL) @{
4655622Swollman        com_err("demo", code,
4665622Swollman                "while opening my_secrets");
4675622Swollman        exit(1);
4685622Swollman    @}
4695622Swollman@}
4705622Swollman@end example
4715622Swollman
4725622SwollmanA caller which fails to check the return status is in error.  It is
4735622Swollmanpossible to look for code which ignores error returns by using lint;
4745622Swollmanlook for error messages of the form ``foobar returns value which is
4755622Swollmansometimes ignored'' or ``foobar returns value which is always
4765622Swollmanignored.''
4775622Swollman
4785622SwollmanSince libraries may be built out of other libraries, it is often necessary
4795622Swollmanfor the success of one routine to depend on another.  When a lower level
4805622Swollmanroutine returns an error code, the middle level routine has a few possible
4815622Swollmanoptions.  It can simply return the error code to its caller after doing
4825622Swollmansome form of cleanup, it can substitute one of its own, or it can take
4835622Swollmancorrective action of its own and continue normally.  For instance, a
4845622Swollmanlibrary routine which makes a ``connect'' system call to make a network
4855622Swollmanconnection may reflect the system error code @code{ECONNREFUSED}
4865622Swollman(Connection refused) to its caller, or it may return a ``server not
4875622Swollmanavailable, try again later,'' or it may try a different server.
4885622Swollman
4895622SwollmanCleanup which is typically necessary may include, but not be limited
4905622Swollmanto, freeing allocated memory which will not be needed any more,
4915622Swollmanunlocking concurrancy locks, dropping reference counts, closing file
4925622Swollmandescriptors, or otherwise undoing anything which the procedure did up
4935622Swollmanto this point.  When there are a lot of things which can go wrong, it
4945622Swollmanis generally good to write one block of error-handling code which is
4955622Swollmanbranched to, using a goto, in the event of failure.  A common source
4965622Swollmanof errors in UNIX programs is failing to close file descriptors on
4975622Swollmanerror returns; this leaves a number of ``zombied'' file descriptors
4985622Swollmanopen, which eventually causes the process to run out of file
4995622Swollmandescriptors and fall over.
5005622Swollman
5015622Swollman@example
5025622Swollman@{
5035622Swollman    FILE *f1=NULL, *f2=NULL, *f3=NULL;
5045622Swollman    int status = 0;
5055622Swollman
5065622Swollman    if ( (f1 = fopen(FILE1, "r")) == NULL) @{
5075622Swollman        status = errno;
5085622Swollman        goto error;
5095622Swollman    @}
5105622Swollman
5115622Swollman    /*
5125622Swollman     * Crunch for a while
5135622Swollman     */
5145622Swollman
5155622Swollman    if ( (f2 = fopen(FILE2, "w")) == NULL) @{
5165622Swollman        status = errno;
5175622Swollman        goto error;
5185622Swollman    @}
5195622Swollman
5205622Swollman    if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
5215622Swollman        status = errno;
5225622Swollman            goto error;
5235622Swollman    @}
5245622Swollman
5255622Swollman    /*
5265622Swollman     * Do more processing.
5275622Swollman     */
5285622Swollman    fclose(f1);
5295622Swollman    fclose(f2);
5305622Swollman    fclose(f3);
5315622Swollman    return 0;
5325622Swollman
5335622Swollmanerror:
5345622Swollman    if (f1) fclose(f1);
5355622Swollman    if (f2) fclose(f2);
5365622Swollman    if (f3) fclose(f3);
5375622Swollman    return status;
5385622Swollman@}
5395622Swollman@end example
5405622Swollman
54122176Sjoerg@ifinfo
54222176Sjoerg@node Building and Installation, Bug Reports, Coding Conventions, (dir)
54322176Sjoerg@comment  node-name,  next,  previous,  up
54422176Sjoerg@end ifinfo
54522176Sjoerg
5465622Swollman@section Building and Installation
5475622Swollman
5485622SwollmanThe distribution of this package will probably be done as a compressed
5495622Swollman``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
5505622SwollmanRetrieve @samp{pub/com_err.tar.Z} and extract the contents.  A subdirectory
5515622Swollman@t{profiled} should be created to hold objects compiled for profiling.
5525622SwollmanRunning ``make all'' should then be sufficient to build the library and
5535622Swollmanerror-table compiler.  The files @samp{libcom_err.a},
5545622Swollman@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
5555622Swollmaninstalled for use; @samp{com_err.3} and @samp{compile_et.1} can also be
5565622Swollmaninstalled as manual pages.
5575622Swollman
5585622SwollmanPotential problems:
5595622Swollman
5605622Swollman@itemize @bullet
5615622Swollman
5625622Swollman@item Use of @code{strcasecmp}, a routine provided in BSD for
5635622Swollmancase-insensitive string comparisons.  If an equivalent routine is
5645622Swollmanavailable, you can modify @code{CFLAGS} in the makefile to define
5655622Swollman@code{strcasecmp} to the name of that routine.
5665622Swollman
5675622Swollman@item Compilers that defined @code{__STDC__} without providing the header
5685622Swollmanfile @code{<stdarg.h>}.  One such example is Metaware's High ``C''
5695622Swollmancompiler, as provided at Project Athena on the IBM RT/PC workstation; if
5705622Swollman@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not
5715622Swollmanavailable, and therefore @code{<varargs.h>} must be used.  If the symbol
5725622Swollman@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will
5735622Swollmanbe used.
5745622Swollman
5755622Swollman@item If your linker rejects symbols that are simultaneously defined in two
5765622Swollmanlibrary files, edit @samp{Makefile} to remove @samp{perror.c} from the
5775622Swollmanlibrary.  This file contains a version of @var{perror(3)} which calls
5785622Swollman@code{com_err} instead of calling @code{write} directly.
5795622Swollman
5805622Swollman@end itemize
5815622Swollman
5825622SwollmanAs I do not have access to non-BSD systems, there are probably
5835622Swollmanbugs present that may interfere with building or using this package on
5845622Swollmanother systems.  If they are reported to me, they can probably be fixed for
5855622Swollmanthe next version.
5865622Swollman
58722176Sjoerg@ifinfo
58822176Sjoerg@node Bug Reports, Acknowledgements, Building and Installation, (dir)
58922176Sjoerg@comment  node-name,  next,  previous,  up
59022176Sjoerg@end ifinfo
59122176Sjoerg
5925622Swollman@section Bug Reports
5935622Swollman
5945622SwollmanPlease send any comments or bug reports to the principal author: Ken
5955622SwollmanRaeburn, @t{Raeburn@@Athena.MIT.EDU}.
5965622Swollman
59722176Sjoerg@ifinfo
59822176Sjoerg@node Acknowledgements, , Bug Reports, (dir)
59922176Sjoerg@comment  node-name,  next,  previous,  up
60022176Sjoerg@end ifinfo
60122176Sjoerg
6025622Swollman@section Acknowledgements
6035622Swollman
6045622SwollmanI would like to thank: Bill Sommerfeld, for his help with some of this
6055622Swollmandocumentation, and catching some of the bugs the first time around;
6065622SwollmanHoneywell Information Systems, for not killing off the @emph{Multics}
6075622Swollmanoperating system before I had an opportunity to use it; Honeywell's
6085622Swollmancustomers, who persuaded them not to do so, for a while; Ted Anderson of
6095622SwollmanCMU, for catching some problems before version 1.2 left the nest; Stan
6105622SwollmanZanarotti and several others of MIT's Student Information Processing Board,
6115622Swollmanfor getting us started with ``discuss,'' for which this package was
6125622Swollmanoriginally written; and everyone I've talked into --- I mean, asked to read
6135622Swollmanthis document and the ``man'' pages.
6145622Swollman
6155622Swollman@bye
616