{
    "content": [
        {
            "type": "text",
            "text": "# com_err (info)\n\n## Sections\n\n- **A Common Error Description Library for UNIX**\n- **1 Why comerr?**\n- **2 Error codes**\n- **3 Error table source file**\n- **4 The error-table compiler**\n- **5 Run-time support routines**\n- **6 Coding Conventions**\n- **7 Building and Installation**\n- **8 Bug Reports**\n- **9 Acknowledgements**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "com_err",
        "section": "",
        "mode": "info",
        "summary": null,
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "A Common Error Description Library for UNIX",
                "lines": 16,
                "subsections": []
            },
            {
                "name": "1 Why comerr?",
                "lines": 33,
                "subsections": []
            },
            {
                "name": "2 Error codes",
                "lines": 28,
                "subsections": []
            },
            {
                "name": "3 Error table source file",
                "lines": 30,
                "subsections": []
            },
            {
                "name": "4 The error-table compiler",
                "lines": 13,
                "subsections": []
            },
            {
                "name": "5 Run-time support routines",
                "lines": 118,
                "subsections": []
            },
            {
                "name": "6 Coding Conventions",
                "lines": 105,
                "subsections": []
            },
            {
                "name": "7 Building and Installation",
                "lines": 11,
                "subsections": []
            },
            {
                "name": "8 Bug Reports",
                "lines": 7,
                "subsections": []
            },
            {
                "name": "9 Acknowledgements",
                "lines": 12,
                "subsections": []
            }
        ],
        "sections": {
            "A Common Error Description Library for UNIX": {
                "content": "This manual documents the comerr library.\n\n* Menu:\n\n* Why comerr?::\n* Error codes::\n* Error table source file::\n* The error-table compiler::\n* Run-time support routines::\n* Coding Conventions::\n* Building and Installation::\n* Bug Reports::\n* Acknowledgements::\n\nFile: comerr.info,  Node: Why comerr?,  Next: Error codes,  Prev: Top,  Up: Top\n",
                "subsections": []
            },
            "1 Why comerr?": {
                "content": "In building application software packages, a programmer often has to\ndeal with a number of libraries, each of which can use a different\nerror-reporting mechanism.  Sometimes one of two values is returned,\nindicating simply SUCCESS or FAILURE, with no description of errors\nencountered.  Sometimes it is an index into a table of text strings,\nwhere the name of the table used is dependent on the library being used\nwhen the error is generated; since each table starts numbering at 0 or\n1, additional information as to the source of the error code is needed\nto determine which table to look at.  Sometimes no text messages are\nsupplied at all, and the programmer must supply them at any point at\nwhich he may wish to report error conditions.  Often, a global variable\nis assigned some value describing the error, but the programmer has to\nknow in each case whether to look at 'errno', 'herrno', the return\nvalue from 'heserr()', or whatever other variables or routines are\nspecified.  And what happens if something in the procedure of examining\nor reporting the error changes the same variable?\n\nThe package we have developed is an attempt to present a common\nerror-handling mechanism to manipulate the most common form of error\ncode in a fashion that does not have the problems listed above.\n\nA list of up to 256 text messages is supplied to a translator we have\nwritten, along with the three- to four-character \"name\" of the error\ntable.  The library using this error table need only call a routine\ngenerated from this error-table source to make the table \"known\" to the\ncomerr library, and any error code the library generates can be\nconverted to the corresponding error message.  There is also a default\nformat for error codes accidentally returned before making the table\nknown, which is of the form 'unknown code foo 32', where 'foo' would be\nthe name of the table.\n\nFile: comerr.info,  Node: Error codes,  Next: Error table source file,  Prev: Why comerr?,  Up: Top\n",
                "subsections": []
            },
            "2 Error codes": {
                "content": "Error codes themselves are 32 bit (signed) integers, of which the high\norder 24 bits are an identifier of which error table the error code is\nfrom, and the low order 8 bits are a sequential error number within the\ntable.  An error code may thus be easily decomposed into its component\nparts.  Only the lowest 32 bits of an error code are considered\nsignificant on systems which support wider values.\n\nError table 0 is defined to match the UNIX system call error table\n('syserrlist'); this allows 'errno' values to be used directly in the\nlibrary (assuming that 'errno' is of a type with the same width as\nlong).  Other error table numbers are formed by compacting together the\nfirst four characters of the error table name.  The mapping between\ncharacters in the name and numeric values in the error code are defined\nin a system-independent fashion, so that two systems that can pass\nintegral values between them can reliably pass error codes without loss\nof meaning; this should work even if the character sets used are not the\nsame.  (However, if this is to be done, error table 0 should be avoided,\nsince the local system call error tables may differ.)\n\nAny variable which is to contain an error code should be declared\nlong.  The draft proposed American National Standard for C (as of May,\n1988) requires that long variables be at least 32 bits; any system which\ndoes not support 32-bit long values cannot make use of this package (nor\nmuch other software that assumes an ANSI-C environment base) without\nsignificant effort.\n\nFile: comerr.info,  Node: Error table source file,  Next: The error-table compiler,  Prev: Error codes,  Up: Top\n",
                "subsections": []
            },
            "3 Error table source file": {
                "content": "The error table source file begins with the declaration of the table\nname, as\n\nerrortable TABLENAME\n\nIndividual error codes are specified with\n\nerrorcode ERRORNAME, \"TEXT MESSAGE\"\n\nwhere 'ec' can also be used as a short form of 'errorcode'.  To\nindicate the end of the table, use 'end'.  Thus, a (short) sample error\ntable might be:\n\n\nerrortable     dsc\n\nerrorcode      DSCDUPMTGNAME,\n\"Meeting already exists\"\n\nec              DSCBADPATH,\n\"A bad meeting pathname was given\"\n\nec              DSCBADMODES,\n\"Invalid mode for this access control list\"\n\nend\n\n\nFile: comerr.info,  Node: The error-table compiler,  Next: Run-time support routines,  Prev: Error table source file,  Up: Top\n",
                "subsections": []
            },
            "4 The error-table compiler": {
                "content": "The error table compiler is named 'compileet'.  It takes one argument,\nthe pathname of a file (ending in '.et', e.g., 'dscerr.et') containing\nan error table source file.  It parses the error table, and generates\ntwo output files - a C header file ('discusserr.h') which contains\ndefinitions of the numerical values of the error codes defined in the\nerror table, and a C source file which should be compiled and linked\nwith the executable.  The header file must be included in the source of\na module which wishes to reference the error codes defined; the object\nmodule generated from the C code may be linked in to a program which\nwishes to use the printed forms of the error codes.\n\nFile: comerr.info,  Node: Run-time support routines,  Next: Coding Conventions,  Prev: The error-table compiler,  Up: Top\n",
                "subsections": []
            },
            "5 Run-time support routines": {
                "content": "Any source file which uses the routines supplied with or produced by the\ncomerr package should include the header file '<comerr.h>'.  It\ncontains declarations and definitions which may be needed on some\nsystems.  (Some functions cannot be referenced properly without the\nreturn type declarations in this file.  Some functions may work properly\non most architectures even without the header file, but relying on this\nis not recommended.)\n\nThe run-time support routines and variables provided via this package\ninclude the following:\n\nvoid initializeXXXXerrortable (void);\n\nOne of these routines is built by the error compiler for each error\ntable.  It makes the XXXX error table \"known\" to the error reporting\nsystem.  By convention, this routine should be called in the\ninitialization routine of the XXXX library.  If the library has no\ninitialization routine, some combination of routines which form the core\nof the library should ensure that this routine is called.  It is not\nadvised to leave it the caller to make this call.\n\nThere is no harm in calling this routine more than once.\n\n#define ERRORTABLEBASEXXXX NNNNNL\n\nThis symbol contains the value of the first error code entry in the\nspecified table.  This rarely needs be used by the programmer.\n\n-- Function: const char *errormessage (long CODE);\n\nThis routine returns the character string error message associated\nwith 'code'; if this is associated with an unknown error table, or\nif the code is associated with a known error table but the code is\nnot in the table, a string of the form 'Unknown code XXXX NN' is\nreturned, where XXXX is the error table name produced by reversing\nthe compaction performed on the error table number implied by that\nerror code, and NN is the offset from that base value.\n\nAlthough this routine is available for use when needed, its use\nshould be left to circumstances which render 'comerr' (below)\nunusable.\n\n-- Function: void comerr (const char *WHOAMI, long ERRORCODE, const\nchar *FORMAT, ...);\n\nThis routine provides an alternate way to print error messages to\nstandard error; it allows the error message to be passed in as a\nparameter, rather than in an external variable.  Provide\ngrammatical context for \"message.\"\n\nThe module reporting the error should be passed in via WHOAMI.  If\nFORMAT is '(char *)NULL', the formatted message will not be\nprinted.  FORMAT may not be omitted.\n\n-- Function: void comerrva (const char *WHOAMI, long ERRORCODE,\nconst char *FORMAT, valist ARGS);\n\nThis routine provides an interface, equivalent to 'comerr' above,\nwhich may be used by higher-level variadic functions (functions\nwhich accept variable numbers of arguments).\n\n-- Function: void *setcomerrhook (void (*PROC) (const char *WHOAMI,\nlong ERRORCODE, valist ARGS) (const char *WHOAMI, long\nERRORCODE, valist ARGS));\n\n-- Function: void resetcomerrhook ();\n\nThese two routines allow a routine to be dynamically substituted\nfor 'comerr'.  After 'setcomerrhook' has been called, calls to\n'comerr' will turn into calls to the new hook routine.\n'resetcomerrhook' turns off this hook.  This may intended to be\nused in daemons (to use a routine which calls 'syslog(3)'), or in a\nwindow system application (which could pop up a dialogue box).\n\nIf a program is to be used in an environment in which simply\nprinting messages to the 'stderr' stream would be inappropriate\n(such as in a daemon program which runs without a terminal\nattached), 'setcomerrhook' may be used to redirect output from\n'comerr'.  The following is an example of an error handler which\nuses 'syslog(3)' as supplied in BSD 4.3:\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <syslog.h>\n\n/* extern openlog (const char * name, int logopt, int facility); */\n/* extern syslog (int priority, char * message, ...); */\n\nvoid hook (const char * whoami, long code,\nconst char * format, valist args)\n{\nchar buffer[BUFSIZ];\nstatic int initialized = 0;\nif (!initialized) {\nopenlog (whoami,\nLOGNOWAIT|LOGCONS|LOGPID|LOGNDELAY,\nLOGDAEMON);\ninitialized = 1;\n}\nvsprintf (buffer, format, args);\nsyslog (LOGERR, \"%s %s\", errormessage (code), buffer);\n}\n\nAfter making the call 'setcomerrhook (hook);', any calls to\n'comerr' will result in messages being sent to the SYSLOGD daemon\nfor logging.  The name of the program, 'whoami', is supplied to the\n'openlog()' call, and the message is formatted into a buffer and\npassed to 'syslog'.\n\nNote that since the extra arguments to 'comerr' are passed by\nreference via the 'valist' value 'args', the hook routine may\nplace any form of interpretation on them, including ignoring them.\nFor consistency, 'printf'-style interpretation is suggested, via\n'vsprintf' (or 'doprnt' on BSD systems without full support for\nthe ANSI C library).\n\nFile: comerr.info,  Node: Coding Conventions,  Next: Building and Installation,  Prev: Run-time support routines,  Up: Top\n",
                "subsections": []
            },
            "6 Coding Conventions": {
                "content": "The following conventions are just some general stylistic conventions to\nfollow when writing robust libraries and programs.  Conventions similar\nto this are generally followed inside the UNIX kernel and most routines\nin the Multics operating system.  In general, a routine either succeeds\n(returning a zero error code, and doing some side effects in the\nprocess), or it fails, doing minimal side effects; in any event, any\ninvariant which the library assumes must be maintained.\n\nIn general, it is not in the domain of non user-interface library\nroutines to write error messages to the user's terminal, or halt the\nprocess.  Such forms of \"error handling\" should be reserved for failures\nof internal invariants and consistency checks only, as it provides the\nuser of the library no way to clean up for himself in the event of total\nfailure.\n\nLibrary routines which can fail should be set up to return an error\ncode.  This should usually be done as the return value of the function;\nif this is not acceptable, the routine should return a \"null\" value, and\nput the error code into a parameter passed by reference.\n\nRoutines which use the first style of interface can be used from\nuser-interface levels of a program as follows:\n\n{\nif ((code = initializeworld(getuid(), random())) != 0) {\ncomerr(\"demo\", code,\n\"when trying to initialize world\");\nexit(1);\n}\nif ((database = opendatabase(\"mysecrets\", &code))==NULL) {\ncomerr(\"demo\", code,\n\"while opening mysecrets\");\nexit(1);\n}\n}\n\nA caller which fails to check the return status is in error.  It is\npossible to look for code which ignores error returns by using lint;\nlook for error messages of the form \"foobar returns value which is\nsometimes ignored\" or \"foobar returns value which is always ignored.\"\n\nSince libraries may be built out of other libraries, it is often\nnecessary for the success of one routine to depend on another.  When a\nlower level routine returns an error code, the middle level routine has\na few possible options.  It can simply return the error code to its\ncaller after doing some form of cleanup, it can substitute one of its\nown, or it can take corrective action of its own and continue normally.\nFor instance, a library routine which makes a \"connect\" system call to\nmake a network connection may reflect the system error code\n'ECONNREFUSED' (Connection refused) to its caller, or it may return a\n\"server not available, try again later,\" or it may try a different\nserver.\n\nCleanup which is typically necessary may include, but not be limited\nto, freeing allocated memory which will not be needed any more,\nunlocking concurrency locks, dropping reference counts, closing file\ndescriptors, or otherwise undoing anything which the procedure did up to\nthis point.  When there are a lot of things which can go wrong, it is\ngenerally good to write one block of error-handling code which is\nbranched to, using a goto, in the event of failure.  A common source of\nerrors in UNIX programs is failing to close file descriptors on error\nreturns; this leaves a number of \"zombied\" file descriptors open, which\neventually causes the process to run out of file descriptors and fall\nover.\n\n{\nFILE *f1=NULL, *f2=NULL, *f3=NULL;\nint status = 0;\n\nif ( (f1 = fopen(FILE1, \"r\")) == NULL) {\nstatus = errno;\ngoto error;\n}\n\n/*\n* Crunch for a while\n*/\n\nif ( (f2 = fopen(FILE2, \"w\")) == NULL) {\nstatus = errno;\ngoto error;\n}\n\nif ( (f3 = fopen(FILE3, \"a+\")) == NULL) {\nstatus = errno;\ngoto error;\n}\n\n/*\n* Do more processing.\n*/\nfclose(f1);\nfclose(f2);\nfclose(f3);\nreturn 0;\n\nerror:\nif (f1) fclose(f1);\nif (f2) fclose(f2);\nif (f3) fclose(f3);\nreturn status;\n}\n\nFile: comerr.info,  Node: Building and Installation,  Next: Bug Reports,  Prev: Coding Conventions,  Up: Top\n",
                "subsections": []
            },
            "7 Building and Installation": {
                "content": "The distribution of this package will probably be done as a compressed\n\"tar\"-format file available via anonymous FTP from SIPB.MIT.EDU.\nRetrieve 'pub/comerr.tar.Z' and extract the contents.  A subdirectory\nprofiled should be created to hold objects compiled for profiling.\nRunning \"make all\" should then be sufficient to build the library and\nerror-table compiler.  The files 'libcomerr.a', 'libcomerrp.a',\n'comerr.h', and 'compileet' should be installed for use; 'comerr.3'\nand 'compileet.1' can also be installed as manual pages.\n\nFile: comerr.info,  Node: Bug Reports,  Next: Acknowledgements,  Prev: Building and Installation,  Up: Top\n",
                "subsections": []
            },
            "8 Bug Reports": {
                "content": "The principal author of this library is: Ken Raeburn, raeburn@MIT.EDU.\n\nThis version of the comerr library is being maintained by Theodore\nTs'o, and so bugs and comments should be sent to tytso@thunk.org.\n\nFile: comerr.info,  Node: Acknowledgements,  Prev: Bug Reports,  Up: Top\n",
                "subsections": []
            },
            "9 Acknowledgements": {
                "content": "I would like to thank: Bill Sommerfeld, for his help with some of this\ndocumentation, and catching some of the bugs the first time around;\nHoneywell Information Systems, for not killing off the Multics\noperating system before I had an opportunity to use it; Honeywell's\ncustomers, who persuaded them not to do so, for a while; Ted Anderson of\nCMU, for catching some problems before version 1.2 left the nest; Stan\nZanarotti and several others of MIT's Student Information Processing\nBoard, for getting us started with \"discuss,\" for which this package was\noriginally written; and everyone I've talked into -- I mean, asked to\nread this document and the \"man\" pages.\n\n",
                "subsections": []
            }
        }
    }
}