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