Path: utzoo!mnetor!uunet!mcvax!ukc!its63b!simon From: simon@its63b.ed.ac.uk (ECSC68 S Brown CS) Newsgroups: comp.lang.c Subject: Re: stdio error detection Message-ID: <814@its63b.ed.ac.uk> Date: 6 Dec 87 17:35:07 GMT References: <10649@brl-adm.ARPA> Reply-To: simon%lfcs.ed.ac.uk@nss.cs.ucl.ac.uk (Simon Brown) Organization: LFCS, University of Edinburgh Lines: 87 In article <10649@brl-adm.ARPA> dsill@NSWC-OAS.arpa (Dave Sill) writes: >>I used to be rather fond of C, but this error stuff is quite >>incredibly bad. The problem isn't really the language; it's >>the libraries. > >Rather than messing with errno, I think a new variable, say, liberr, >should be used. An include file, say liberr.h, could contain macro >definitions for the various types of errors. A macro named LIBERR >could also be defined in liberr.h so code could be written that would >take advantage of liberr if it was available or handle errors in the >usual way if it's not. Even better would be to have LIBERR be a >predefined macro like ANSI, unix, vax, et cetera. > This still has the same problem as with "errno"- namely that you're trying to describe a general ``error condition'' using a single number! I'm told that VMS (but it's a good idea for all that...) provides a stack of error values which allows a program to search backward to find out what the "real" error was, depending on what kind of detail is required. If you have several levels of library calls between you and the system call that failed, this can be extremely useful- it's not really much use having an error-value if you can't even tell what system call it came from (let alone what parameters were *passed* to that system call to cause it to fail!). A *decent* error-returning mechanism would describe: 1. What call (syscall or library call) failed. This could be a number- you could use something like internet addressing to put some kind of structure into it: libc.stdio.fopen 2. Why it failed. Simple E-numbers will do for this (although I suppose they'd have to be grouped for different libraries): E_STDIO.E_CANNOT_OPEN_FILE 3. What value it returned. (FILE *)NULL 3. What parameters were passed to it. This is the most difficult one, because it would have to have some kind of idea as to the types involved. It could (I suppose) deal only with string types (and convert any other type into "printable" form by doing the equivalent of sprintf()'ing it). It also has to be a "list", which means it would probably have to be done using something like "argc,argv": argc: 2 argv: "mumble.splat", "r" If the error is not "dealt with", then this information should propogate down (together with the info from the callee's failure), and so on... So, If you do a fopen("mumble.splat","r") and it fails, then the following would be left on the stack (in some format or other) to be dealt with by some error-diagnosing function: kernel.open: param 1: "mumble.splat" [string] param 2: 0 [int] returns: -1 [int] error: E_KERNEL.ENOENT libc.stdio.fopen: param 1: "mumble.splat" [string] param 2: "r" [string] returns: 0 [FILE *] error: E_LIBC.E_STDIO.E_CANNOT_OPEN_FILE The error-diagnosing stuff could then print something *useful* such as stdio fopen: couldn't open file "mumble.splat" for reading, because: kernel open: no file or directory "mumble.splat" (and of course the format of these messages could be user-configurable, so that noddies would just get the information they need, whereas people who understand what they're doing could get reams and reams of info- just by setting some environment parameter to the appropriate value). Of course, all this stuff would have to be known by the compiler, and I'm sure it'd be dead slow to execute! -- -------------------------------------------------- | Simon Brown | | Laboratory for Foundations of Computer Science | | Department of Computer Science | | University of Edinburgh, Scotland, UK. | -------------------------------------------------- UUCP: uunet!mcvax!ukc!lfcs!simon ARPA: simon%lfcs.ed@nss.cs.ucl.ac.uk "Life's like that, you know" JANET: simon@uk.ac.ed.lfcs