Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!husc6!harvard!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.unix Subject: Re: gripes about error reporting Message-ID: <1449@umcp-cs.UUCP> Date: Sat, 10-May-86 21:46:59 EDT Article-I.D.: umcp-cs.1449 Posted: Sat May 10 21:46:59 1986 Date-Received: Tue, 13-May-86 02:48:35 EDT References: <406@houligan.UUCP> Reply-To: chris@maryland.UUCP (Chris Torek) Organization: University of Maryland, Dept. of Computer Sci. Lines: 95 In article <406@houligan.UUCP> daemon@houligan.UUCP writes: >Another problem: Recently, I wrote a device driver for an exclusive-use >device [...]. I finally settled on EBUSY [for an `in use' error], >but if you run that through perror, you get "mount device busy".... 4.3BSD's perror says "Device busy". >The second gripe involves utilities. A number of them don't bother to do >perror or anything like it; they just say "can't open file" or something >like that. I have a feeling this is caused by two things: First, perror() is not always sufficient. Second, it is not as well known as it should be, perhaps because of the first problem. I have been pushing my own `error' routine. It seems to work pretty well. There are a few things I might change, but it currently works as follows: ERROR(3) UNIX Programmer's Manual ERROR(3) NAME error - error message output routine SYNOPSIS error(quit, syserr, format [, arg ] ... ) int quit, syserr; char *format; DESCRIPTION Error prints an error message on the standard error output, just as fprintf(stderr, format [, arg ] ... ) would, but preceded by the program's name, and followed by the error message that perror(3) would print if the system error number syserr were in the global variable errno. After printing a terminating newline, if quit is nonzero, error performs an exit(quit); . If syserr is zero, the system error message is suppressed; error may thus be used for user errors. Examples To abort a program if a file cannot be opened for reading: extern int errno; ... if ((fp = fopen(filename, "r")) == NULL) error(1, errno, "can't open %s for reading", filename); To abort after a user error: error(1, 0, "usage: foo bar"); To gripe about a system error, without exiting: extern int errno; ... if (unlink(tempfile)) error(0, errno, "warning: couldn't remove %s", tempfile); AUTHOR Chris Torek SEE ALSO printf(3S), perror(3), exit(3) BUGS Printed 5/10/86 U of MD Local 1 The changes I might make involve the following: - error() cannot print to stdout (perhaps it should take a `FILE *' or a file descriptor); and - error() cannot get the system error number itself (this is a minor nuisance); and - the name `error' may be too presumptuous. However, it is refreshing to be able to go through my old code and replace umpteen occurrences of if ((fd = open(file, mode)) < 0) { (void) fprintf(stderr, "myprog: cannot open"); perror(arg); exit(1); } with if ((fd = open(file, mode)) < 0) error(1, errno, "cannot open %s", arg); -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu