rbutterworth@watmath.UUCP (Ray Butterworth) (08/11/86)
> On the whole I think this an excellent idea... but Ray, is it too late > to convince the people involved *not* to use signals for communications? > This has long been recognized as a bad idea. And it's so unnecessary > in this case, and related ones: it suffices to say that whenever the > _WriteBuf function fails, it calls (say) _WBerror with some suitable > parameters, and the user can substitute his own _WBerror function if he > doesn't like the default one. This gets much of the benefit without > the various problems and unportabilities of signals. We've already rejected the idea of signals. Our library is intended to be a portable interface over a number of different systems and compilers, so signals aren't always available anyway. We also rejected the call-a-function approach, although this required a lot more arguing. What we actually do is provide macros to set and unset a trap. When an error occurs, an error message is formatted (but not printed) and a longjump is made. If some function has set a trap, it can ignore the error, print the message, replace or append to the message, and/or reraise the event. If the event isn't explicitly trapped by the program, the event is automattically trapped by the event mechainism, which prints the message and exits. In general, most functions don't set traps. Those that do, do it so that they can free malloc'ed space or reset static flags before reraising the event. Programs only set the traps when they expect that something might go wrong that they might know how to recover from. We do lack the ability for a trap to decide that the error isn't important and that execution should continue from the point where the event was raised. So far, this hasn't been a great inconvenience. A lot of extra work is required in writing the library functions. This is rewarded by a lot less work in (correctly) writing programs. We provide "cover functions" for many libc functions. For example our cover for malloc() always returns a pointer to allocated memory. There is never any need for the caller to check every time to see if the function failed. Thus the programs tend to look the same as most people (incorrectly) write normal C.