Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!decvax!harpo!seismo!hao!hplabs!sri-unix!dm@bbn-unix From: dm%bbn-unix@sri-unix.UUCP Newsgroups: net.unix Subject: Re: 'exit(1);' considered useless (slight flame) Message-ID: <16732@sri-arpa.UUCP> Date: Fri, 10-Feb-84 14:54:07 EST Article-I.D.: sri-arpa.16732 Posted: Fri Feb 10 14:54:07 1984 Date-Received: Mon, 20-Feb-84 01:15:43 EST Lines: 99 From: Dave MankinsWhat's wrong with PERROR is that it's dreadfully limited. Since perror only allows you to give a canned, inflexible message (plus the error message), the amount of detail you can stick into an error message is restricted. BBN has a set of routines (the cmderr family, and errmsg) which do this very well. Cmderr, unfortunately depends on the non-portable "%r" (for "remote") printf format discussed in this forum a few months ago. I recently moved to a new computer system (at MIT's Project Athena) which doesn't have these, and the first thing I did was add errmsg (which is portable), at least, and I put it into a LIBRARY (and wrote a manual page, too, of course) so I could use it in every program I write or modify: /* ---------------------- e r r m s g --------------------------- */ /* * Returns system error string. * Argument: * if error is positive, assume that it is an error number. * if error is 0, then use the message associated with the * current value in errno. */ char * errmsg(error) int error; { extern int errno; if(error == 0) error = errno; if(error <= 0 && error > sys_nerr) return("Unknown error"); else return(sys_errlist[error]); } (Forgive me, I'm reconstructing this from memory, and I don't have access to the Athena system right now--I think the declarations of char *sys_errlist[] and int sys_nerr are available from some include file on 4.xBSD. If you don't have those, look at the source for perror, and see where it gets its error message strings (if you don't have the source for perror, I guess you could use adb on a program which uses it, and rebuild the table--I can't tell you, cause Mother Bell wouldn't like it if I did).) This routine then allows: if((file_pointer = fopen(file, "r")) == NULL) { fprintf(stderr, "%s: Can't open \"%s\"; %s.\n", progname, file, errmsg(0)); ... } Which produces an error message: rabbit: Can't open "/usr/dm/lettuce"; No such file or directory. And which is almost as easy to use as perror, except that it ENCOURAGES your error message to contain more information. [Sigh, it's still not as easy to use as cmderr...] It's amazing how quickly you can find and fix problems when your error messages contain that much information. I'm truly tired of programs which say "Can't open file." Can't open what file? Why not? As a system maintainer I don't have time to look at the sources of some god-awful huge program to figure out what it's complaining about. Now, the problem with this scheme is that it requires the error messages to be compiled into the program, so programs compiled a long time ago won't know about new system error codes (I don't believe in semantic overloading of error messages) when they appear. At BBN, where new kernel-originated network error codes appear with some frequency, this is a problem. At Project Athena, where new kernel-originated distributed filesystem errors will be appearing with some frequency, it will also be a problem. A better solution (which is, in fact, how BBN's stuff does all that) is to store the error messages in a file, and open the file and read it to get the error message. Of course, if the error message in question is "Too many open files" you won't be able to open the file to read the message, so you have to watch out for that case, (and similar cases) but that CAN be done. [The possibilities of errors in your error routines reminds me of an error message which would appear occasionally on a TENEX system I used to work on (a "JSYS" is a system call): rabbit: Can't open lettuce.txt; JSYS error in JSYS error routine! AAAIIIEEEEeeee.......! I never did get out of the habit of looking over at the machine to see if the lights were still flickering when that message appeared...]