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