[net.unix-wizards] error - but which program??

chris@umcp-cs.UUCP (06/09/84)

*	From: jpl@allegra.UUCP

	... don't you just love it when you run a pipeline of commands
	and one of them prints:
	    malloc failed.
	and then dies without identifying itself?

Here's where I'd like to see a small addition to the C library...:

    NAME
	error - print an error message and optionally exit

    SYNOPSIS
	error(quit, syserr, fmt, arg, ...)
	int quit;
	int syserr;
	char *fmt;

    DESCRIPTION

	Prints (to stderr) the name of the program, followed by a colon
	and a space, and then performs a printf() to stderr using the
	given format and arguments.  Then, if syserr is nonzero, prints
	the system error message associated with that error index (that
	is, prints what ``perror'' would).  Finally, it prints a newline
	and calls fflush(stderr).

	If quit is nonzero, the program is terminated (via ``exit(quit);'').
	Otherwise, control is returned to the caller.

	The program name is squirreled away in the external ``ProgName''.

    SEE ALSO
	intro(2), exit(2), fprintf(3S), fflush(3S), perror(3)

    EXAMPLE
	.
	.
	.
	char *fname;
	FILE *f;
	extern int errno;
	.
	.
	.
	f = fopen(fname, "r");
	if (f == NULL)
		error(1, errno, "can't read %s", fname);
	if (isbad(f)) {
		error(0, 0, "file %s is not in the correct format; rebuilt",
			fname);
		rebuild_it(f, fname);
	}

    BUGS
       The system error message can only appear at the end.  It would
       be nice to have a printf() format specifier to produce the system
       error message from the error index number.
------------------------------------------------------------------------
The function is obviously implementable on any machine that has fprintf().
In fact, I like it so much that I've taken to using it even though it's
not in the C Library.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

dan@haddock.UUCP (06/13/84)

#R:umcp-cs:-742900:haddock:16800016:000:1120
haddock!dan    Jun 11 14:20:00 1984

When I wrote a function like that a few years ago, I didn't have a 'quit'
argument, as I wanted to minimize the number of arguments to encourage
people to use the routine without thinking about it.  Instead I defined
variants on the routine which exited, aborted, and called reset()
(the predecessor to setjmp/longjmp).  The basic function was "cmderr",
and the others were "ecmderr", "acmderr", and "rcmderr".  If I were
doing it over again I might add "jcmderr(jmpbuf, sys_errno, fmt, ...)".

It was easy to convert most commands to use this format; just set the
global "progname" at the beginning of "main" and then, almost mechanically,
convert all the fprintf calls to cmderr calls.	We even considered having
crt0.o set "progname" to eliminate that part.

One thing you discover after you do this is that the system message strings
occupy a significant portion of the total address space on a 16-bit machine.
We put them all into a file--except, of course, for EMFILE and ENFILE, which
have to be compiled in.  Having them in a file also made it easy to add
new messages, or change the existing ones to be clearer.