Home -> Error Reporting Library
Overview

CGI

Error reporting

Comma Separated Values

Singly Linked List
Maintained by suitti@uitti.net, Stephen Uitti

Name

err, erre, errp, errpe, errset

Synopsis

     #include <stdio.h>
     #include "err.h"

     cc file.c -lerr -lsll

Description

The liberr.a library provides functions to report errors. Use of the library facilitates consistent error reporting with flexibility. Function calls are terse, to allow more room for error messages.

There are several situations where the style of error reporting must differ. The following scenarios are supported.

The library is intended to allow convenient and consistent error formatting and reporting for applications and groups of applications. If the standard changes, consider changing the library.

  • A Unix command line application, errors are written to the standard error file descriptor and are prefixed by the name of the application, a colon and a space. After the error, the library writes a newline character. If a system error is also printed, it starts on a new line and ends with a newline.
  • For web applications, the error is formatted in HTML, in bold, and red. The error begins and ends with a
    to break the line.
  • There exist applications where the called routine does not know in advance how to report the error. In these cases, routines often pass back an error code, and require the caller to handle it. These routines allow error strings to be appended to a list, so that the caller, or further up the chain, can decide how to display them. The error library does not format the data in any way. Presumably, the caller knows how to do that.

Modes

The header file, err.h, defines three environment types. These are ERR_STDERR, ERR_STRLST, and ERR_HTML. If ERR_STDERR is specified with errset(), then error messages are prefixed with the program name and written to the standard error file descriptor. If ERR_STRLST is specified, then errors are appended to a list. The list uses libsll format. See the example for calling details. If ERR_HTML is specified, then errors are formatted for HTML, and emitted to the standard output, where CGI output normally goes.

Routines

void err(char *format, ...);

This routine behaves like printf(3). Format the error according to the current mode. Then write it to the appropriate place - file descriptor or list.

void erre(char *format, ...);

This routine behaves like printf(3). Format the error according to the current mode. Then write it to the appropriate place - file descriptor or list. Finally, exit. Note that this routine is not particularly valuable in list mode, since the list is lost on exit.

void errp(char *format, ...);

This routine behaves like printf(3). Format the error according to the current mode. Then examine errno for a system error and translate it to a string. Then write everything to the appropriate place - file descriptor or list.

void errpe(char *format, ...);

This routine behaves like printf(3). Format the error according to the current mode. Then examine errno for a system error and translate it to a string. Then write everything to the appropriate place - file descriptor or list. Finally, exit. Note that this routine is not particularly valuable in list mode, since the list is lost on exit.

int errset(char *argv0, int errtype, struct sll **errlist);

Initialize the liberr library. The first argument is the name of the application, usually argv[0]. The library knows how to extract the application name if a full path is present. The second argument is the type of environment. This should be one of ERR_STDERR, ERR_STRLST, or ERR_HTML. This routine may be called to delete the error list. Just call the routine again with the list head. Alternately, one may simply call sll_rmlist(list);.

The list is free()'d even if the mode is changed to something else. If the first argument, argv0, is NULL, then the application name is not changed. If errlist is NULL, the list is not free()'d. The routine returns the previous type of environment. This allows a routine to set the state temporarily, for exmple, to collect a list for an operation, then restore normal error reporting for the application.

Example

This is tsterr.c, which can be found with the sources. Note how the libsll list is traversed.
#include 
#include 
#include "err.h"

static void do_err(void);

static void
do_err()
{
	err("This is a test with %d arguments.\n", 1);
	err("This is a test with %d, %d arguments.\n", 1, 2);
	err("This is a test with %d, %d, %d arguments.\n", 1, 2, 3);
	err("This is a test with %d, %d, %d, %d arguments.\n", 1, 2, 3, 4);
	errno = ENOENT;
	errp("This is an errp test.\n");

#if 1 /* Naturally, ERR_STRLST won't work with this. */
	erre("The exit status should be 1.\n%s",
	     "This should be the last line printed.\n");
	err("This shouldn't print.\n");
#endif
}

int
main(int argc, char *argv[])
{
    register int errtype;
    register int i;
    register int list = FALSE;
    register struct sll *sp;
    register int seen = FALSE;

    for (i = 1; i < argc; i++) {
	if (strcmp("html", argv[i]) == 0) {
	    errtype = ERR_HTML;
	} else if (strcmp("list", argv[i]) == 0) {
	    errtype = ERR_STRLST;
	    list = TRUE;
	} else {
	    errtype = ERR_STDERR;
	}
	errset(argv[0], errtype, &sp);
	do_err();
	seen = TRUE;
    }
    if (!seen) {		/* Believe. */
	errset(argv[0], ERR_STDERR, &sp);
	do_err();
    }

    if (list) {
	printf("Printing list:\n");
	for (sp = liberr_list; sp != NULL; sp = sp->next) {
	    printf("%s\n", (char *)sp->key);
	}
    }
    return 0;
}

Diagnostics

Yes.

Files

/usr/local/lib/liberr.a
/usr/local/include/err.h
/usr/local/lib/libsll.a
/usr/local/include/sll.h

See Also

strings(3), perrno(3), libsll

Author

Stephen Uitti, 1995

Bugs

Use of erre() and errpe() with list mode (ERR_STRLST) is not particularly useful, since the list is lost on exit.