Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

too many enumerated types?

16 views
Skip to first unread message

Scott Weitzenkamp

unread,
Feb 5, 1989, 2:02:14 AM2/5/89
to

I am having problems getting a 35000 line C program to link on a
Bell Technologies 386 box running BellTech's System V, Release 3.2.
The 70 source files compiled fine, but here's the error message I
get when I try to link them:

$ cc -g *.o
ld fatal: fail to write symbol name LESSEQ_OP in string table
for file a.out

LESSEQ_OP is an enumerated value; we use a lot of enumerated types
in the code. I have only had this machine for 2 days, and I'm
beginning to really dislike System V UNIX.

What is going on here? Am I out of room in the symbol table for
all my enumerated values? Am I going to have to change all
my enums to defines? If so, that really sucks. This code runs
fine on BSD-based Unix boxes (Sun3, Sun4, Ultrix). Have I been
living in Berkeley-land for too long? What other nasty little
quirks await me? Is it tougher to port from BSD to System V,
or vice-versa? I hate dbx, but I think I hate sdb even more.
Is System V Release 4 going to be the big AT&T-Sun merge? God,
I hope so.

Scott Weitzenkamp UUCP: {lll-lcc.arpa,ucbvax}!leadsv!laic!scott
Lockheed AI Center ARPA: far...@portia.stanford.edu
"The faster I go, the behinder I get."

Scott Weitzenkamp UUCP: {lll-lcc.arpa,ucbvax}!leadsv!laic!scott
Lockheed AI Center ARPA: far...@portia.stanford.edu
"The faster I go, the behinder I get."

Scott Weitzenkamp

unread,
Feb 5, 1989, 2:26:33 AM2/5/89
to

More info on my link problem: I am compiling all the .c files with
-g, so I guess that accounts for all the extra symbol table info.

Guy Harris

unread,
Feb 5, 1989, 4:12:40 PM2/5/89
to
>What is going on here? Am I out of room in the symbol table for
>all my enumerated values?

Probably not. A quick check of the "ld" source reveals that the error
message in question is printed if an "fwrite" of one symbol table entry
fails to return 1. The most likely causes of this are:

1) an error from a "write" call in the standard I/O library
failing - i.e.:

you ran out of disk space

or

you overflowed the stupid 1MB default file size limit
that many S5 implementations use (I guess they're scared
to up the default to infinitely, or at least some large
value - hey, guys, it's not in the SVID, AT&T won't yank
your S5 license if you default it to a huge value, and
many many many of your customers will probably love you
for it)

or

you got a real live I/O error

or...

2) a bug in standard I/O in your system.

It definitely has nothing to do with "too many enumerated types"; you're
making a fairly broad assumption by concluding that it's the problem.

My guess would be that it's 1). If so, there are a variety of
techniques for upping the ulimit; I think in S5R3.2 you can simply
reconfigure your system to set the default higher. I'd advise that you
set it as high as you can.

>What other nasty little quirks await me?

Hard to say. There are a variety of other differences; I don't have a
list of all of them handy.

>Is it tougher to port from BSD to System V, or vice-versa?

Hard to say. It depends on what you're doing. It's tougher to port
from a system that supports the facilities you use to a system that
doesn't; in some cases vanilla BSD has the facilities and vanilla S5
doesn't, and in other cases vanilla S5 has the facilities and vanilla
BSD does't.

Note that in your case you're not dealing with vanilla BSD, though; both
Ultrix and SunOS have a number of S5 facilities in addition to BSD
facilities.

Jim Shankland

unread,
Feb 5, 1989, 8:58:19 PM2/5/89
to
In article <4...@laic.UUCP> sc...@nova.laic.uucp (Scott Weitzenkamp) writes:
>
>I am having problems getting a 35000 line C program to link on a
>Bell Technologies 386 box running BellTech's System V, Release 3.2.
>The 70 source files compiled fine, but here's the error message I
>get when I try to link them:
>
>$ cc -g *.o
>ld fatal: fail to write symbol name LESSEQ_OP in string table
>for file a.out

Check your ulimit. System V imposes a ``soft'' maximum file size --
1 Meg. on the machines I've worked on, maybe less on yours. You need
to be root to change this limit, on a per-process basis. Whether this
makes you laugh or cry is up to you. (Make sure your disk isn't full, also.)

Jim Shankland
j...@ernie.berkeley.edu

"I've been walking in a river all my life, and now my feet are wet"

Steve Summit

unread,
Feb 11, 1989, 12:56:50 PM2/11/89
to
In article <4...@laic.UUCP> sc...@nova.laic.uucp (Scott Weitzenkamp) writes:
>I am having problems getting a 35000 line C program to link...
>...here's the error message I get when I try to link them:

>$ cc -g *.o
>ld fatal: fail to write symbol name LESSEQ_OP in string table
>for file a.out

In article <9...@auspex.UUCP> g...@auspex.UUCP (Guy Harris) writes:
>...the error message in question is printed if an "fwrite" of one symbol


>table entry fails to return 1. The most likely causes of this are:

> you ran out of disk space

> you overflowed the stupid 1MB default file size limit

> or you got a real live I/O error

This example shows that the ld in question has violated one of
the cardinal rules* of error messages, and also nicely
illustrates the importance of these rules. Had ld called
perror() or the equivalent**, the real reson for the error would
have been immediately evident, and Scott would not have been led
to his (reasonable, under the circumstances) misconception about
the number of enumerations.

Steve Summit
s...@adam.pika.mit.edu

* Briefly, the rules are:
1. always include the name of the program (ld got this right)
2. for errors related to system calls (including most
stdio errors) always call perror
3. for errors that relate to a user file being read, always
include the file name and line number

** perror() is less convenient than it could be for printing
informative error messages. You could call it with the name
of the program, the name of the system call, or the name of
the file being read, but not with all three. Here is a simple
routine I use to overcome these difficulties. A sample use
would be

errorp("%s: error writing %s", progname, outfile);

Note that errorp is varargs; be sure to declare it as

extern void errorp(char *, ...);

under an ANSI compiler. Also note that it appends a newline;
the format string shouldn't normally include one.

#include <stdio.h>
#include <stdarg.h>

extern int errno;

extern char *strerror();

/* VARARGS1 */

void errorp(fmt)
char *fmt;
{
va_list argp;

va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
fprintf(stderr, ": %s\n", strerror(errno));
va_end(argp);
}

If you don't have an ANSI <stdarg.h>, you'll have to change it
slightly to use <varargs.h> (or, failing that, _doprnt). If you
don't have strerror(), you can use sys_errlist[].

Stephen J. Friedl

unread,
Feb 12, 1989, 2:27:40 AM2/12/89
to
In article <92...@bloom-beacon.MIT.EDU>, s...@adam.pika.mit.edu (Steve Summit) writes:
>
> This example shows that the ld in question has violated one of
> the cardinal rules* of error messages, and also nicely
> illustrates the importance of these rules.
> [ * good rules deleted, also mentioning perror(3) ]

For you portability fanatics, perror(BA_LIB) is Level 2 in
the System V Interface Definition (aka the SVID). `Level 2'
means that the feature is not guaranteed to be supported in the
SVID beyond three years of the Level 2 date, and in this case,
the date is 1/1/1985.

Reliable sources tell that perror(3) will still be in the
next SVID, but there are `Future Directions' that are much more
substantial (they will make the error messages look more like
VMS).

What does POSIX say about perror(3)?

Steve

--
Stephen J. Friedl 3B2-kind-of-guy fri...@vsi.com
V-Systems, Inc. I speak for you only attmail!vsi!friedl
Santa Ana, CA USA +1 714 545 6442 {backbones}!vsi!friedl
--------Barbara Bush on... on... No, I just can't do it...--------

John Woods

unread,
Feb 14, 1989, 2:02:00 AM2/14/89
to
In article <10...@vsi.COM>, fri...@vsi.COM (Stephen J. Friedl) writes:
> Reliable sources tell that perror(3) will still be in the
> next SVID, but there are `Future Directions' that are much more
> substantial (they will make the error messages look more like
> VMS).

I attended a System V Release 4.0 Software Developers' Conference in December,
and I can attest that they are definitely making the error messages look like
VMS. They showed an example of 5 different current UNIX utilities trying to
open an unreadable file, and each gave different one-line complaint, of
varying helpfulness. Then they showed an example of The New Wave, a four-line
error message which took 3 lines to misdiagnose the problem, and reminded
you that this was, in fact, an error. Yup. Just like VMS... :-)
--
John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101
...!decvax!frog!john, jo...@frog.UUCP, ...!mit-eddie!jfw, j...@eddie.mit.edu

Presumably this means that it is vital to get the wrong answers quickly.
Kernighan and Plauger, The Elements of Programming Style

Rahul Dhesi

unread,
Feb 16, 1989, 11:29:00 AM2/16/89
to
In article <14...@X.UUCP> jo...@frog.UUCP (John Woods) writes:
>Then they showed an example of The New Wave, a four-line
>error message which took 3 lines to misdiagnose the problem, and reminded
>you that this was, in fact, an error. Yup. Just like VMS... :-)

Hmmm...I hope they don't take it too far.

TODAY (cryptic, confusing, not reassuring at all)

$ xyz=test_symbol; export xyz
$ sh
$ ^D
$

TOMORROW (warm, friendly, reassuring)

$ xyz=test_symbol; export xyz
%SHELL-I-SUPERSEDE, previous value of XYZ has been superseded
%SHELL-I-EXPORT, of XYZ has been exported
$ sh
%SHELL-S-SPAWNED, process SHELL_002 spawned
%SHELL-S-ATTACHED, terminal now attached to process SHELL_002
$ ^D
Process SHELL_002 logged out at 16-FEB-1989 11:11:16.41
%SHELL-S-RETURNED, control returned to process SHELL_001
$

I'm not kidding. I actually did "define xyz test_symbol", "spawn", and
"logout" at the VMS prompt and saw roughly the above.

Here's what I would REALLY like to see:

$ dir
%DIR-Q-AREYOUSURE, you asked for a directory, are you sure [y/n]: y
%DIR-Q-VERYSURE, you said yes, but are you REALLY sure [y/n]: y
%DIR-Q-REALSURE, are you REALLY REALLY sure [y/n]: y
%DIR-F-JUSTINCASE, no directory, say PRETTY_PLEASE
$ dir/pretty_please
%DIR-I-OHWELL, ok, well, if you insist
%DIR-S-UASKED4IT, but we warn you, you did ask for it
[ directory listing appears here]
%DIR-I-DIRDONE, directory listing done, control returned to CLI
%CLI-I-WHEW, *whew*, thought DIR was going to take over system
$
--
Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi
ARPA: bsu-cs!dh...@iuvax.cs.indiana.edu

Guy Harris

unread,
Feb 18, 1989, 4:19:33 AM2/18/89
to
>Then they showed an example of The New Wave, a four-line error message
>which took 3 lines to misdiagnose the problem, and reminded
>you that this was, in fact, an error.

Fortunately, with any luck, you will at least be able to set an
environment variable to cut out most of the more useless stuff from
those messages.

James D. Allen

unread,
Feb 20, 1989, 9:36:15 PM2/20/89
to
In article <57...@bsu-cs.UUCP>, dh...@bsu-cs.UUCP (Rahul Dhesi) writes:
> Here's what I would REALLY like to see:
Really? :-}

>
> $ dir
> %DIR-Q-AREYOUSURE, you asked for a directory, are you sure [y/n]: y
> %DIR-Q-VERYSURE, you said yes, but are you REALLY sure [y/n]: y
> %DIR-Q-REALSURE, are you REALLY REALLY sure [y/n]: y
> %DIR-F-JUSTINCASE, no directory, say PRETTY_PLEASE
> $ dir/pretty_please
> %DIR-I-OHWELL, ok, well, if you insist
> %DIR-S-UASKED4IT, but we warn you, you did ask for it
> [ directory listing appears here]
> %DIR-I-DIRDONE, directory listing done, control returned to CLI
> %CLI-I-WHEW, *whew*, thought DIR was going to take over system
> $

This really made me laugh! From time-to-time I've wanted to mail some
software to where_the_sun_doesnt_shine@software_vendor. Rahul's
posting has induced me to give the net the benefit of my invective. :-}

I only wish that superfluous dialog were the worst problem with
friendly software. The "improved" `dir', for example, when it finally
gets around to listing a directory, will silently substitute a
*different* ("better", "friendlier") directory than the one you asked for.

Here are two examples of programs which try to be helpful, but where I
wish the programmer had called in sick the day he was going to add the
feature.

Example 1)

IBM language processors abound with self-righteous "logic".

Consider a C fragment like:
/*
* Temporarily disable database updates, until
* the xlurg_gak module is debugged:
*/
#define write(X,Y,Z) \
(printf("Would have written %d bytes\n", Z), Z)

This can be quite convenient. The macro definition doesn't "use" X or
Y, but that is the intent.

IBM has a macro facility in JCL, something like:
//FOOBAR PROC X,Y,Z

It's been a long time, but as I recall, typical output from `PROC' is:
ILQJCL773P2: Fatal error, Formal argument `X' not used in `FOOBAR'

If you think about the implementation, it's clear that somewhere in
the JCL processor is code like:
/*
* The `refcnt' array is of no value to *us* whatsoever
* but we need it for the friendly ILQJCL773P2 error.
*/
++refcnt[var_index];

Great concept! A `fatal error' you have to go out of your way to
detect and which, if undetected, would harmlessly have the desired
effect (ie, none).


Example 2)

Just yesterday a friend asked me to help transfer some files from his
Mac to his new Unix machine. First we connected a couple of wires
between pins 2 & 3 and pins 3 & 2. Then we needed some software to
get the wires busy. I'm sure everybody in this newsgroup could whip
that together in a few minutes but my friend had already purchased a
Mr_Everything_you_ever_wanted_to_do_with_your_serial_line application
so we double-clicked its icon. I should have smelled trouble when I
noticed the icon had a real *friendly* smile.

We immediately got a "Password:" string safely back from the other end
of the wire. "This will be real easy," I said. "Unix is smart enough to
play stupid when you tell it to." I did something like
% stty raw -echo
% cat -u > foobar^J
and selected Mr_Everything's "Send File" menu. "We'll have to `kill'
`cat' from the other end, but that's harmless enough."

However, Mr_Everything was too friendly to send a *binary* file over the
wire. It doesn't care what the data is, mind you, just whether it
recognizes the flavor of the mindless Macintosh file prefix.


Summary)

What are the reasons for this type of software "quality"? I nominate
1) Mediocre programmers only get a low bug-to-keystroke ratio with
`printf'-type code so they do lots of it.
2) Too often, software quality is judged by managers who are not
real users.
3) Programmers view themselves as more intelligent then their users,
but ignore that their intelligence will be "out of the loop"
once the software (a tiny subset of their skill) is delivered.

Some will argue that my complaints are not caused because software is
"friendly" but because "it isn't friendly enough!" But adding lots of
features *increases* problems whenever the features prove inadequate.
It's better to give the user a *simple* model of the software.
This is the original Unix philosophy:
- do something simple
- do it well
- do it silently

Returning to the farcical version of `dir', for example, after receiving
complaints about the inane dialog, the "friendly" solution is to add
another option to `dir':

$ dir/omit_inane_dialog
%DIR-Q-IAMSOSAD, sure you want to omit the inane dialog? [y/n]:

Friendly software. Just say no.

Dave Decot

unread,
Feb 21, 1989, 8:24:44 AM2/21/89
to
> Then they showed an example of The New Wave, a four-line error message
> which took 3 lines to misdiagnose the problem, and reminded you that
> this was, in fact, an error. Yup. Just like VMS... :-)

I object to this use of an HP trademark (NewWave) for something unrelated
to our product and for a situation this disgusting. Now, perhaps it is an
example of the Open Look...

We now return you to your regularly scheduled article.
Thank you for your time. :-)

Dave

Patrick Curran

unread,
Feb 21, 1989, 5:02:41 PM2/21/89
to
In response to various amusing comments about VMS's tendency to keep you
over-informed about what it's doing:
========

While I'm no great fan of VMS, I did spend a couple of years working with
it, and I really must correct the (mis)impressions that are being
generated here.

Yes, VMS's messages can be irritatingly wordy. However, it is possible
to customize the message system to behave the way you want it to. I
forget the precise details, but essentially there are several sorts of
messages (informational, warning, error, system?), and each message has
several components (a number, an identification of the program which
issued the message, an indication of its type, and the message itself).

It's possible to specify that you only want particular types of messages
to be displayed, and/or that you only want to see particular message
components. Consequently, if you want nothing but UNIX-style terse error
messages (no fluff, no warnings, no informational messages) you can get
them. If you want more, you can have that too.

(Now that I think of it, if you're from the "real hackers don't need
error messages" school, you could turn off all messages, so implementing
the ultimate in silent systems :-)

The advantage of the centralized error-message-handler is that user-
written or third-party programs can utilize its capabilities, inserting
their own messages into the database. All (well-written) programs
therefore behave in exactly the same way. Similar capabilities exist for
adding user-supplied help messages to the system help database, and for
accessing the command-line parsing capabilities of the CLI.

The result is a much cleaner interface; users know how to invoke
programs, how to get help while using them, and how to interpret the
messages they produce. Sounds to me like a big win over the current
state of affairs in the UNIX world. The sooner we implement something
similar, the sooner we'll be taken seriously in the real world where
people run applications rather than hack software.

Patrick Curran (uunet!ism780c!patrick)
INTERACTIVE Systems Corp, Santa Monica, CA. (213) 453-8649

stpe...@dawn.steinmetz

unread,
Feb 22, 1989, 4:07:29 PM2/22/89
to
In article <22...@ism780c.isc.com> pat...@ism780c.UUCP (Patrick Curran) writes:
>Yes, VMS's messages can be irritatingly wordy. However, it is possible
>to customize the message system to behave the way you want it to.

Not really. For example, if you turn off all the components, you
never get *any* error messages, which is a bit more terse than even
UNIX. However, even if you have the messages turned off, VMS will
still inform you that you've logged off. Rather handy, that. :-)

There are other things too. Fortunately, I don't have to use VMS much
anymore, so I don't remember what they are, but they were once a pain.

>The result is a much cleaner interface; ...


>Sounds to me like a big win over the current
>state of affairs in the UNIX world. The sooner we implement something
>similar, the sooner we'll be taken seriously in the real world where
>people run applications rather than hack software.

>Patrick Curran (uunet!ism780c!patrick)
>INTERACTIVE Systems Corp, Santa Monica, CA. (213) 453-8649

Well, Pat, we were once an all VMS site. Management was a little slow
noticing that 1) most of the applications we ran were ported from
UNIX, and 2) every time they bought a VMS machine they wound up
shelling out thousands of dollars for INTERACTIVE's UNIX emulation.

Finally, they let us have real UNIX. We've been happily running
applications ever since. More and more the business components of GE
have been doing so as well.
--
Dick St.Peters
GE Corporate R&D, Schenectady, NY
stpe...@ge-crd.arpa
uunet!steinmetz!stpeters

David C Lawrence

unread,
Feb 22, 1989, 8:27:05 PM2/22/89
to
In some unknown article, someone writes:
> Then they showed an example of The New Wave, a four-line error message
> which took 3 lines to misdiagnose the problem, and reminded you that
> this was, in fact, an error. Yup. Just like VMS... :-)

In article <1402...@hpisod2.HP.COM> de...@hpisod2.HP.COM (Dave Decot) writes:
dd> I object to this use of an HP trademark (NewWave) for something unrelated
dd> to our product and for a situation this disgusting.

[So, why didn't you reference the article which you quoted? I believe
that they are in the "friendly messages" subject. <4...@laic.UUCP> had
no mention of The New Wave or NewWave (tm).]

I certainly hope you are saying this with mock sincerity. I would not
be at all surprised if the original poster had never even heard of
"NewWave". Secondly, "The New Wave" is not an infringement on
"NewWave". Finally, if the two things are as disparate as you assert,
then why care at all? Geesh.
--
ta...@rpitsmts.bitnet, tale%m...@rpitsgw.rpi.edu, ta...@pawl.rpi.edu

Dave Decot

unread,
Feb 23, 1989, 1:56:37 PM2/23/89
to
> In some unknown article, someone writes:
> > Then they showed an example of The New Wave, a four-line error message
> > which took 3 lines to misdiagnose the problem, and reminded you that
> > this was, in fact, an error. Yup. Just like VMS... :-)
>
>In article <1402...@hpisod2.HP.COM> de...@hpisod2.HP.COM (Dave Decot) writes:
>dd> I object to this use of an HP trademark (NewWave) for something unrelated
>dd> to our product and for a situation this disgusting.
>
> [So, why didn't you reference the article which you quoted? I believe
> that they are in the "friendly messages" subject. <4...@laic.UUCP> had
> no mention of The New Wave or NewWave (tm).]

The References: line in the article tells which article string this
refers to, the Subject: line (which you said "was" the former subject
in your article's Subject) tells the Subject of the article string.
I had hoped this would be sufficient context, since most news reading
programs are able to keep discussions together by subject.

> I certainly hope you are saying this with mock sincerity.

Yes, substantially mock. That is what the smiley face was for at the
end of my article, which you did not quote.

> I would not be at all surprised if the original poster had never even
> heard of "NewWave".

NewWave is an HP trademark for a user interface technology which is/was the
subject of a highly-publicized court battle among Apple, Microsoft, and
HP, which to my knowledge has not been resolved yet. Open Look is the
name of a similar (not the same) technology provided by AT&T, whose
user-interface products the original "unknown article" was describing.

> Secondly, "The New Wave" is not an infringement on
> "NewWave". Finally, if the two things are as disparate as you assert,
> then why care at all? Geesh.

I did not say it was an infringement, nor certainly do I plan to file
suit against anyone. I said that I objected to the use of a
similar-sounding word in conjunction with an highly obnoxious user
interface.

> ta...@rpitsmts.bitnet, tale%m...@rpitsgw.rpi.edu, ta...@pawl.rpi.edu

Dave

Barry Shein

unread,
Feb 23, 1989, 3:34:37 PM2/23/89
to

>The result is a much cleaner interface; users know how to invoke
>programs, how to get help while using them, and how to interpret the
>messages they produce. Sounds to me like a big win over the current
>state of affairs in the UNIX world. The sooner we implement something
>similar, the sooner we'll be taken seriously in the real world where
>people run applications rather than hack software.
>
>Patrick Curran (uunet!ism780c!patrick)

You miss the whole point of Unix's terseness.

The point is that the output of one command is intended to be useful
as the input of another command, or, the terminal.

It's not a "user-friendly" issue or decision, it's a productivity
decision. VMS doesn't have pipes and often produces output its other
programs can't read anyhow, due to the zillions of RMS file format
mismatches (even if you manage to figure out how to save it to a file,
no I/O redirection) so it's comparing apples and oranges, who cares if
it's full of "RMS-I-EVERYTHING-A-OK" messages, it's just zipping off
the screen anyhow (no piping to "more" either, lovely, user-friendly
system, zip zip zip...what was that?) It's nice to hear there's some
way to shut it up but that really begs the point (ie. the design of
VMS.)

Being as VMS never considered the output of its programs very useful
they felt free to babble whatever they wanted and generally make it
impossible to ever parse up. In unix the designers preferred the
output of programs to be useful.

I realize people find this point aggravatingly subtle.

-Barry "Keen Eye for the Obvious" Shein, ||Encore||

Barry Shein

unread,
Feb 23, 1989, 3:40:40 PM2/23/89
to

Cryptic is in the eye of the beholder. Consider a voice-communications
system which required you to type in 7 to 10 digit strings to
establish virtual circuits! AT&T has done fairly well with this
design, and it's not obvious that any change would be for the better.

The most amazing part of any technology are the people who use it,
be careful when playing armchair psychologist.

-Barry Shein, ||Encore||

Guy Harris

unread,
Feb 24, 1989, 4:26:41 PM2/24/89
to
>The point is that the output of one command is intended to be useful
>as the input of another command, or, the terminal.

Output, or error output? The error output of commands *should* be
intended to be useful to the poor sap who's trying to use the command,
even at the expense of making it harder for some program to parse.

Guy Harris

unread,
Feb 24, 1989, 4:48:00 PM2/24/89
to
>Cryptic is in the eye of the beholder. Consider a voice-communications
>system which required you to type in 7 to 10 digit strings to
>establish virtual circuits! AT&T has done fairly well with this
>design, and it's not obvious that any change would be for the better.

Yes, at times I've noticed the annoying similarity between the error
messages UNIX coughs up and the error messages the phone system coughs
up.... Whilst a change to the scheme for dialing may or may not
represent an improvement, other aspects of the phone system *could* be
changed in ways that, at least from the end-user's viewpoint, would be
for the better.

One example is the moral equivalent of the "syntax error" message. You
know, the one that starts with that horrible shriek (which, I seem to
remember hearing, is required by some standard, so that one may not be
AT&T's fault), and then informs you that "your call cannot be completed
as dialed".

This is about as annoying as, say, the "foo: alpha/beta/gamma: cannot open"
messages that UNIX programs tend to cough up. A change that is
obviously for the better is to have those messages print out the error
message associated with "errno", so you don't have to try an "ls" to see
if the file doesn't exist, or exists but doesn't let you read it, or....

The moral equivalent of such a change to the phone system user interface
would be for it to tell you something like "that call's in your area
code, dummy, leave the area code off!" An even better change would be
for it to ignore the area code; I don't know whether either change is
possible - it may well not be, and it may be too expensive to change the
phone system to support it, and may have been too expensive to built the
phone system to support it. The same isn't true of UNIX; using "perror",
or using "sys_nerr" and "sys_errlist", isn't that costly.

(Also, going back to the original point, consider a networking system
that required you to type in N-digit strings to specify host addresses
in individual configuration files for various network services; a change
that centralized the host-name-to-address mapping and let all the
services use that mapping, so that their configuration files could have
names, would be a change for the better.)

>The most amazing part of any technology are the people who use it,
>be careful when playing armchair psychologist.

Well, I *have* used UNIX and the phone system, and yes, there are places
in both where the cryptic error messages simply suck. Ever tried
debugging a long "ed" script with a version of "ed" that *cannot* be
told to print long error messages? I made the SunOS 4.0 "ed" print *line
numbers* when it's in "long error messages" mode - as turned on by the
"H" command, since that "ed" is derived from the S5R3 "ed" - and was
given the "-" option. That made it *lots* easier to debug big "ed"
scripts such as the ones used when building the S5R3 "curses" library.

People too often seem to take it for granted that short, cryptic error
messages are ultimately a Good Thing under all circumstances and that
UNIX has nothing to learn or to improve in this regard. It's simply not
true. (Why did not "ed" print TECO-style short error messages instead
of just "?"? As I remember, DEC TECO printed error messages with a "?"
followed by a 3-letter code, or maybe vice versa. Terse, but at least
it doesn't throw away information....)

None of this is to say that VMS-style error messages necessarily
represent an improvement, just that there *is* plenty of room for
improvement in UNIX's error messages. (At least we no longer have
botches such as "ar" printing its error messages to standard output;
well do I remember doing "ar t foo.a | lpr" and getting one sheet of
printout saying "foo.a does not exist"....)

Guy Harris

unread,
Feb 26, 1989, 4:04:45 PM2/26/89
to
>Ah, but Guy, if the phone system were more like VMS then they'd surely
>have to charge you for unanswered calls and the like or they'd go
>broke!

I neither want UNIX nor the phone system to be "more like VMS" in that
regard. I just want them to be less prone to withholding information
from me when reporting an error, since that information could allow me
more quickly to fix the problem they're reporting. I also don't want to
see people equating "better error messages" with "error messages like
VMS", either when arging against better error messages or when trying to
improve them!

Brian Westley

unread,
Feb 27, 1989, 3:23:49 PM2/27/89
to
>Cryptic is in the eye of the beholder. Consider a voice-communications
>system which required you to type in 7 to 10 digit strings to
>establish virtual circuits! AT&T has done fairly well with this
>design, and it's not obvious that any change would be for the better.
> -Barry Shein, ||Encore||

It's easy to do better; phone USED to work better. You picked up
the phone and said "John Q. Public, please" and that was all.
I bet phones will do this in the future, only you'll be talking to
a voice recognition circuit instead of a human. It'll also know
who YOU mean if you ask for "John" or "Mom" or whomever.

Merlyn LeRoy

Unix Consultation Mailbox

unread,
Feb 27, 1989, 4:16:25 PM2/27/89
to
Despite the fact that a lot of people have a lot to say (or flame) on this
issue, it seems that there is really very little controversy, at least about
what error messages should say. The consensus seems to be (correct me if
I'm wrong.. :-) that error messages should say just enough to please the
user and no more. The problem here is (of course) defining the term "user".
The same problem exists with the term "user-friendly". It's not possible to
lump all users of any commercial computer system into a single group with
definite and consistent interface preferences. This applies to error
messages as well as the syntax of a command-line interface or whether the
system has a command-line at all (e.g. Mac).

In general I won't touch anything "user-friendly" with a ten-foot mouse.
This is because I personally find the typical "user-friendly" interface to
be anything but a help to software development. I already understand the
system I am working on pretty well; I am familiar with navigating UNIX
filesystems, making system calls, predicting the effect of wildcards in
shell scripts, etc. I don't want to be led by the hand through fifteen
nested menus to get into an editor. I don't want to ever *have* to use a
mouse - I've been a touch-typist since long before I ever worked with
computers and because I *write text* for a living, it's much more important
for me to have my fingers on the home keys than to be able to point to a
menu selection when I'm just trying to logout.

We write applications on UNIX systems which run on UNIX systems and are
used by (largely) unskilled users. We have to be very careful about what
our "users" see, that it is as consistent as possible between systems and
neither cryptic nor prolix. When our programmers are called upon to
second-guess the users by predicting the acceptability of a certain
feature, they frequently get it wrong because they are looking at the
system from a completely different angle. (We are slowly learning that
we don't have the smarts to outguess our "unsophisticated" users.)

I don't like systems that assume that I have no experience with them. Many
other programmers that I work with feel the same. Some don't. Some
otherwise perfectly good programmers always have to be led very carefully
the first time through something or they won't get it. On the other side
of the coin, some applications try to assume that the "user" knows a lot
more than they really do; most of our "users" don't like it when our systems
do this, though some do.

I think the fundamental problem here is that some people haven't yet
figured out that they are trying to make everybody happy at once, which we
know (cf. Heisenberg :-) cannot be done in reality, whatever that is.

I'll keep using UNIX as long as I can, unless I find something I like
better. I have so far found no "user-friendly" interfaces which I find
more intuitive or productive than the Bourne shell. If I ever do, I'll be
sure to let everyone know. :-)


Phil Kos
Curmudgeon Supreme

Dan Jacobson

unread,
Feb 27, 1989, 9:57:18 PM2/27/89
to
I remember this VMS nastiness:
%E-BUZZOFF Foreign commie terminal type. By a DEC terminal and reenter command
--
Dan Jacobson, jaco...@eecs.nwu.edu, {oddjob,gargoyle,att,...}!nucsrl!jacobson

Guy Harris

unread,
Feb 28, 1989, 3:43:42 PM2/28/89
to
>The consensus seems to be (correct me if I'm wrong.. :-) that error
>messages should say just enough to please the user and no more.

Yes. However, one gets the impression that some programmers have a
quite bogus idea of how much this actually is - often bogusly small. If
I have to dive into the source code to figure out what the problem is,
and then find that it's, say, some straightforward error in a
configuration file, the person who designed the error messages screwed
up. If I have to "ls" a file to figure out whether the application
couldn't open it because it doesn't exist, or because it's not
readable/writable by me, or because it's on a read-only file system,
or..., the person who designed the error messages screwed up -
especially given that the "open" call will tell you that, so all they
had to do was *not* to throw out the information stashed in "errno"!

>The problem here is (of course) defining the term "user".

And one of the main problems is that they too often define "user" as
"wizard" - or, worse, assume that "the experienced user can" - and
*should* - "figure out what's wrong". Even wizards sometimes get
*really* ticked off at cryptic error messages; yes, they *can* -
eventually - figure out what the problem is, but they often don't like
playing 20 Questions with the machine in order to do so.

I've been working with UNIX for over 10 years now, and I *still* find
many of its error messages to be quite poor, although they have slowly
gotten better over time - yes, I can poke at enough things and figure
out what the *real* problem is, eventually, but I'd rather *not* be
forced to do so, especially if the computer could have added some extra
bit of information to its messages that would have told me what the real
problem was immediately.

>The same problem exists with the term "user-friendly". It's not
>possible to lump all users of any commercial computer system into
>a single group with definite and consistent interface preferences.
>This applies to error messages as well as the syntax of a command-line
>interface or whether the system has a command-line at all (e.g. Mac).

The term "user-friendly" doesn't denote very much. It *con*notes quite
a bit, but the connotation depends on the audience; if it's some bunch
of novices, it's intended to connote Motherhood, Apple Pie, and the
Flag, and if it's some bunch of UNIX hackers, it's often intended to
connote Satan and grape Flavor-Aid. In the former case, it can be used
to make some not-so-wonderful package sound better than it is, and in
the latter case it can be used to inappropriately dismiss some
reasonable ideas.

In other words, the issue of whether mouse-based user interfaces are
good or bad has a lot less to do with the issue of how noisy an
application might be in the face of errors that is often thought.

Bob Lenk

unread,
Feb 28, 1989, 5:51:08 PM2/28/89
to
In article <10...@vsi.COM>, fri...@vsi.COM (Stephen J. Friedl) writes:

> What does POSIX say about perror(3)?

The ANSI C standard includes perror(); it leaves the text of messages
implementation-defined. POSIX (1003.1) requires perror() by reference
to the ANSI C standard. I think we can expect it to be around for a
long time. That doesn't mean that other (possibly better, possibly not)
interfaces for printing error messages won't come about, and perhaps
even become standard.

Bob Lenk
hplabs!hpfcla!rml
rml%hpf...@hplabs.hp.com

Larry Campbell

unread,
Feb 28, 1989, 11:22:05 PM2/28/89
to
Having spent the last year or so trying, among other things, to help
our customers use our software, I have developed some very strong opinions
on the subject of error messages:

1. Messages must be accurate and relevant. This should go without
saying, but the infamous "not a typewriter" message reminds me
that it bears repeating.

2. Messages must be complete. If the problem is related to
a particular entity (file, process, device), the entity
MUST be named. "File not found" is useless -- you must
tell me *which* file you were trying to find!

3. Messages must not be excessively scary. Words like "illegal",
"corrupted", "damaged" and the like should be avoided. They
*will* result in telephone calls which *cost* *you* *money*.

4. If there's anything the user can do about the error, the message
must be understandable and must suggest a course of corrective
action. But if it's just a bug the user can't do anything about,
the message should direct the user to call customer support,
and it should display enough information so the poor support
person has half a chance of fixing the problem.

5. It is better to give too much information than too little.
You can always ignore the excess information, but when you're
trying to support a customer six time zones away, you're going
to want as much information as possible to be available. Remember,
the hard problems aren't repeatable, and even if they were, it's
too expensive to keep a customer on the phone trying things out
for you.

I once attended a lecture given by Ben Schneiderman (Univ. of Md.) about
human factors engineering. He pointed out that the best error message he
knew of was the one you get when you misdial a phone number (this was before
divestiture):

"We're sorry, but we are unable to complete your call as dialed.
Please check the number and try your call again, or call your
operator for assistance."

This is an excellent error message, for the following reasons:

1. "We're sorry," It starts out by apologizing! For your mistake!

2. "We are unable..." It blames itself, and not the user!

3. "Please check the number..." It suggests not one, but two
alternative courses of corrective action.

In contrast, if compter programmers had designed the message, it would
probably say something like:

%ATT-F-INVADDR, Invalid or incomplete address, call aborted
or
Not a typewriter

which, to the average user, would be frightening, confusing, and
almost completely uninformative.
--
Larry Campbell The Boston Software Works, Inc.
camp...@bsw.com 120 Fulton Street
wjh12!redsox!campbell Boston, MA 02146

John A. Ebersold

unread,
Mar 2, 1989, 1:29:14 PM3/2/89
to
In article <10...@auspex.UUCP> g...@auspex.UUCP (Guy Harris) writes:
>>The consensus seems to be (correct me if I'm wrong.. :-) that error
>>messages should say just enough to please the user and no more.
>
>Yes. However, one gets the impression that some programmers have a
>quite bogus idea of how much this actually is - often bogusly small.

Yes, like printing errno, instead of the error message.

On a releated topic...

How many times has anyone heard (or said) something like. "I'm not checking
the return value becuase I can't do anything about it anyway."

To me, this is not true. You can always print a message that says:

Horrible error in program foo, function bar, the function bletch returned a
-1 on about line x.

I'd rather have this than a mysterious failure.

--
John A. Ebersold at Defense Logistics Agency osu-cis!dsacg1!dsacg3!vfm6066
Unify Corporation System Automation Center Columbus, Ohio 1-614-238-5923
Me? Speak for anyone else? Don't be ridiculous! AV 850-5923
Systems with poorly understood requirements cannot be developed in a crunch.

Peter da Silva

unread,
Mar 2, 1989, 4:07:56 PM3/2/89
to
Have you looked at the new "perror()" docs? They describe a 4-component
error message format for all programs to use, containing the name of the
program issuing the message, the name of the object responsible, the error
message itself, and a severity level (INFO, WARNING, ERROR, FATAL).

Like this:

% cat /dev/dull
cat: fatal: /dev/dull: No such file or directory

Unfortunately, they still haven't bothered to make all programs use perror()
itself! This, all by itself, would take care of the biggest problems with
UNIX error messages.

You get this:
% cat /dev/dull
cat: cannot open /dev/dull
% nm /dev/dull
nm: can't open "/dev/dull"
% file /dev/dull
/dev/dull: cannot open

Doesn't exist? File not found? What?

At least they could do this:
% more /dev/dull
/dev/dull: No such file or directory

That's more like it.

It'd take one summer student to fix this. Sigh...
--
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Work: uunet.uu.net!ficc!peter, pe...@ficc.uu.net, +1 713 274 5180. `-_-'
Home: bigtex!texbell!sugar!peter, pe...@sugar.uu.net. 'U`
People have opinions. Companies have policy. And typos are my own business.

Doug Gwyn

unread,
Mar 3, 1989, 7:00:52 AM3/3/89
to
In article <32...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
>Have you looked at the new "perror()" docs? They describe a 4-component
>error message format for all programs to use, containing the name of the
>program issuing the message, the name of the object responsible, the error
>message itself, and a severity level (INFO, WARNING, ERROR, FATAL).
> cat: fatal: /dev/dull: No such file or directory

perror() CANNOT do this, as its interface is standardized and has no
room for the additional information (severity and object; the program
name can and probably should be automated). Presumably there is an
analogous function that accepts the additional information. The specs
for this interface would be very handy; we could implement it and
start using it now, rather than having to wait a year.

Generally I approve of the extended message format and agree that it
needs to be used by (nearly) all the standard system utilities.

What is supposed to be done when there is no particular object?
prog: fatal: ???: Insufficient memory available

Doug Gwyn

unread,
Mar 3, 1989, 7:05:29 AM3/3/89
to
In article <13...@dsacg3.UUCP> vfm...@dsacg3.UUCP (John A. Ebersold) writes:
-How many times has anyone heard (or said) something like. "I'm not checking
-the return value becuase I can't do anything about it anyway."
-To me, this is not true. You can always print a message that says:
-Horrible error in program foo, function bar, the function bletch returned a
--1 on about line x.
-I'd rather have this than a mysterious failure.

I agree with you in general; however, there's one common case where the
best solution seems to be to ignore the failure: when an attempt to
output an error message (to stderr, usually) fails. What are you going
to do, try to print yet another error message?

The "assert" macro defined by "#include <assert.h>" is very handy for
handling program logic bugs, in many cases. Sometimes it is important
to try to recover from an error and resume normal operation, rather
than terminating the process.

Peter da Silva

unread,
Mar 6, 1989, 9:05:50 AM3/6/89
to
In article <97...@smoke.BRL.MIL>, gw...@smoke.BRL.MIL (Doug Gwyn ) writes:
> In article <32...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
> >Have you looked at the new "perror()" docs? They describe a 4-component
> >error message format for all programs to use...

> perror() CANNOT do this, as its interface is standardized and has no
> room for the additional information (severity and object; the program
> name can and probably should be automated).

I realise this. The document describes what programs should do for error
messages, but makes no recommendation as to how this should be done.

> Presumably there is an
> analogous function that accepts the additional information.

Unfortunately it's like Open Look... they just specced what it should look
like without providing a programmer interface. The documentation has been
out in the bookstores for some time: it's a red book with a plastic spiral
binding.

> What is supposed to be done when there is no particular object?
> prog: fatal: ???: Insufficient memory available

What does perror do when there is no particular object?

if(!(buffer = malloc(BUFSIZ*NUMBUFS))) {
perror(.....?.....);
...
}

Same problem.

Perhaps we (the usenet community) should spec a better interface:

extern char *progname;
extern char *errformat;
extern char default_errformat[];
char *errmsg();

main(argc, argv)
int argc;
char **argv;
{
progname = argv[0];
errformat = getenv("ERRORFORMAT");
if(errformat == NULL)
errformat = default_errformat;
...
}

...
fprintf(stderr, "%s\n", errmsg(object, severity));

errformat would be printf/sccs-like:

%p program name
%P program name, tail only (no path).
%o object
%e error message
%E short error message
%s severity
%S severity, 1 char
%E %p: %s: %o: %e
%Q %o: %e


--
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Work: uunet.uu.net!ficc!peter, pe...@ficc.uu.net, +1 713 274 5180. `-_-'

Home: ...!texbell!sugar!peter, pe...@sugar.hackercorp.com. 'U`

Lee Carver

unread,
Mar 6, 1989, 12:35:47 PM3/6/89
to
In article <13...@dsacg3.UUCP>, vfm...@dsacg3.UUCP (John A. Ebersold) writes:
> In article <10...@auspex.UUCP> g...@auspex.UUCP (Guy Harris) writes:
> >>The consensus seems to be (correct me if I'm wrong.. :-) that error
> >>messages should say just enough to please the user and no more.
> >
> >Yes. However, one gets the impression that some programmers have a
> >quite bogus idea of how much this actually is - often bogusly small.
>
> Yes, like printing errno, instead of the error message.
>

Actually, the problem is that there is NO right level of detail.
The slickest approach I've seen is to let the user decide how much
detail to look at. No surpisingly, this approach is well based in
cognitive psychology.

A recent CACM paper (K Efe, "A proposed solution to the problem of
levels in error-message generation", CACM, vol 30, no 11, Nov 1987,
pg 948) provides a very simple implementation. It allows the user
to review the failed execution, and uncover the problem. It also
starts with a good discussion of why a single error message is
inadequate. Basically, it put the programmer in the position of
arrogantly "knowing" what the user wants.

For those without the paper, it is basically a tarceback stack in
user sensible terminalogy. You don't have to implement all the
"what next" capability in his paper to have a useful error system.

Lee Carver
Boeing Aerospace

William E. Davidsen Jr

unread,
Mar 6, 1989, 2:43:49 PM3/6/89
to
In article <13...@dsacg3.UUCP> vfm...@dsacg3.UUCP (John A. Ebersold) writes:

| On a releated topic...
|
| How many times has anyone heard (or said) something like. "I'm not checking
| the return value becuase I can't do anything about it anyway."
|
| To me, this is not true. You can always print a message that says:
|
| Horrible error in program foo, function bar, the function bletch returned a
| -1 on about line x.
|
| I'd rather have this than a mysterious failure.

I've done this many times. What would you do when you get an error,
for instance, writing stderr? When I detect a serious error I attempt to
output a warning message to terminal and/or files as appropriate, then
clean up as best I can. When something is seriously wrong writing error
messages, etc, can mess up additional parts of the program.
--
bill davidsen (we...@ge-crd.arpa)
{uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

Jim Prescott

unread,
Mar 29, 1989, 1:23:02 AM3/29/89
to
In article <33...@ficc.uu.net> pe...@ficc.uu.net (Peter da Silva) writes:
>Perhaps we (the usenet community) should spec a better interface:

A nice quick 90% solution is a printf-like function that writes to stderr,
prepends the program name to the message, and can append the system error
message. Something like:
if (open(fname, O_RDRW, 0) == -1)
errmsg("Cannot open \"%s\" for read/write -- ", fname);
would output:
prog: Cannot open "somefile" for read/write -- Read-only file system

This makes it fairly painless for the programmer to come up with an
informative message without worrying about the little details. Trying
to use perror to get a nice message is too much work, which is probably
why it isn't used as often as it should be.

The problems in implementing this are:
- finding the program name; most likely needs to be stashed away
while in main(). (It would have been nice if the ANSI-C
folks had invented some globals to hold copies of main's
arguments. (I know it isn't their job to invent :-).)
- deciding where to put the system error. The code below tacks it
on the end of the message iff it doesn't end in a newline.
Not a great solution but certainly much simpler than doing
a new % escape.

An enhancement would be introduce error levels (we use FATAL, ERROR, INFO
and DEBUG) and provide some way to specify which you want to see (we default
to FATAL & ERROR).

I've even enclosed a function to implement it below (about 99% of which is
from an article on varargs by Chris Torek). I'm not sure how portable
vsprintf is, its on our sun but wasn't in V7 so it probably isn't universal.
If anyone can tell me where to get a pd vsprintf I'd be grateful.

While we're on the subject, Guy mentioned TECO error messages but not how
nifty they actually are. You can tell it to print just the 3 letter code
(eg. ?FNF), to print the 1 line error (eg. ?FNF File not found.) or to print
the 1 line message followed by a couple of likely paragraphs out of the manual
(this is called "war and peace" mode). Its flexible even if not overly
useful (I can't imagine using anything other than 1 line messages. Maybe
the 3 letter only would be good on 110 baud ttys).

========= varargs version
#include <varargs.h>

int
errmsg(va_alist)
va_dcl /* N.B.: no semicolon */
{
int ret;
char *fmt;
va_list ap;
char buf[1024]; /* shouldn't be fixed size */

va_start(ap);
fmt = va_arg(ap, char *);
ret = vsprintf(buf, fmt, ap);
va_end(ap);

fprintf(stderr, "%s: %s", Progname, buf);
if (*(buf + strlen(buf) - 1) != '\n')
perror("");
return ret;
}
#endif

========= stdarg version
#include <stdarg.h>

int
errmsg(char *fmt, ...) /* the `...'s are part of the syntax */
{
int ret;
va_list ap;
char buf[1024]; /* shouldn't be fixed size */

va_start(ap, fmt);
ret = vsprintf(buf, fmt, ap);
va_end(ap);

fprintf(stderr, "%s: %s", Progname, buf);
if (*(buf + strlen(buf) - 1) != '\n')
perror("");
return ret;
}
--
Jim Prescott moscom!j...@cs.rochester.edu
{rutgers,ames,harvard}!rochester!moscom!jgp

Chris Torek

unread,
Mar 29, 1989, 11:16:50 PM3/29/89
to
In article <14...@moscom.UUCP> j...@moscom.UUCP (Jim Prescott) writes:
[much deleted; these are retained in order]

> ret = vsprintf(buf, fmt, ap);
> fprintf(stderr, "%s: %s", Progname, buf);
> perror("");

Beware, beware! His flashing eyes, his floating exception!

Oops, a bit of stream of unconsciousness there.

This can produce the infamous sendmail-style message:

Cannot exec /bin/mail: Not a typewriter

because fprintf() can call isatty() which can set errno to ENOTTY.
To fix this you should either save and restore errno, or change the
code to fish the error message directly out of sys_errmsg[], or
use strerror() (if your C library has it).
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: ch...@mimsy.umd.edu Path: uunet!mimsy!chris

Peter da Silva

unread,
Mar 30, 1989, 10:41:16 AM3/30/89
to
Neither of these solutions is correct:

In article <14...@moscom.UUCP>, j...@moscom.UUCP (Jim Prescott) writes:
> fprintf(stderr, "%s: %s", Progname, buf);
> if (*(buf + strlen(buf) - 1) != '\n')
> perror("");

If this is the first time I/O is done, on at least some machines stdio
will call isatty(0) to determine if stdout should be unbuffered. It will
not save and restore errno. Your program may give such useful advice
as:

foobar: can't open file barfoo -- Not a typewriter.

or:

foobar: can't open file barfoo -- Inappropriate ioctl for device.


--
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, pe...@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, pe...@sugar.hackercorp.com.

Dave Hammond

unread,
Mar 30, 1989, 5:54:36 PM3/30/89
to
In article <14...@moscom.UUCP> j...@moscom.UUCP posts his favorite error
message printer.

I note that for a return value it provides the return from vsprintf.
Since error message printers are typically invoked prior to a return,
or exit, I opt to have my favorite error printer return -1.

While this, perhaps, bastardizes the significance of the function's return
value, it (more often than not) makes for convenient error handling:

...
if (an_error_occurred)
return(errmsg(errcode, "Can't open file %s.", fname));

Obviously this presumes that the calling function normally returns -1 as
an its error condition value. Functions which don't employ a -1 error
return just void the return from the error printer.
--
Dave Hammond
da...@marob.masa.com

Guy Harris

unread,
Mar 30, 1989, 6:27:57 PM3/30/89
to

>A nice quick 90% solution is a printf-like function that writes to stderr,
>prepends the program name to the message, and can append the system error
>message. Something like:
> if (open(fname, O_RDRW, 0) == -1)
> errmsg("Cannot open \"%s\" for read/write -- ", fname);
>would output:
> prog: Cannot open "somefile" for read/write -- Read-only file system

CAREful - you may want to call this function for errors that *don't*
cause "errno" to be set. You might want to have some way to indicate
whether it should use "errno" or not - or, perhaps, just use the
(dp)ANSI C routine "strerror", which takes an "errno" as argument and
returns a pointer to the appropriate error message string, and just
stick "%s"es into the message string and calls to "strerror" into the
argument list. (If your implementation doesn't have "strerror", it's
probably a 5-minute job to whip one up, at least under UNIX.)

>This makes it fairly painless for the programmer to come up with an
>informative message without worrying about the little details. Trying
>to use perror to get a nice message is too much work, which is probably
>why it isn't used as often as it should be.

Yes, but unfortunately burying the call to "perror" in "errmsg" has its
own problems. Note also that there are places other than "errno" where
errors are reported (by other packages, such as TLI, ONC RPC, database
libraries, etc.), often with their own families of error codes and messages,
so you may end up having to stick calls to the "return error message"
code in *anyway* in some cases....

John F Carr

unread,
Mar 31, 1989, 6:37:54 PM3/31/89
to

I include in this article a manual entry for a library function for error
reporting developed by the Student Information Processing Board at MIT.
This is useful because it allows libraries to define their own set of
error codes and messages without adding any user level error processing
code. Library functions can return an internal error code or a unix error.
The com_err function recognizes the type of error and prints an appropriate
message. Each library is given its own range of error codes to avoid
conflict.

It is still possible to print useless or incomprehensible error messages
when using this library, but it encourages a consistent, hopefully good,
style of error reporting.

COM_ERR(3) UNIX Programmer's Manual COM_ERR(3)

NAME
com_err - common error display routine

SYNOPSIS
#include <com_err.h>

void com_err (whoami, code, format, ...);
const char *whoami;
long code;
const char *format;

proc = set_com_err_hook (proc);
void (* proc ) (const char *, long, const char *, va_list);

proc = reset_com_err_hook ();

void initialize_XXXX_error_table ();

DESCRIPTION
Com_err displays an error message on the standard error
stream stderr (see stdio(3S)) composed of the whoami string,
which should specify the program name or some subportion of
a program, followed by an error message generated from the
code value (derived from compile_et(1)), and a string pro-
duced using the format string and any following arguments,
in the same style as fprintf(3).

The behavior of com_err can be modified using
set_com_err_hook; this defines a procedure which is called
with the arguments passed to com_err, instead of the default
internal procedure which sends the formatted text to error
output. Thus the error messages from a program can all
easily be diverted to another form of diagnostic logging,
such as syslog(3). Reset_com_err_hook may be used to
restore the behavior of com_err to its default form. Both
procedures return the previous ``hook'' value. These
``hook'' procedures must have the declaration given for proc
above in the synopsis.

The initialize_XXXX_error_table routine is generated mechan-
ically by compile_et(1) from a source file containing names
and associated strings. Each table has a name of up to four
characters, which is used in place of the XXXX in the name
of the routine. These routines should be called before any
of the corresponding error codes are used, so that the
com_err library will recognize error codes from these tables
when they are used.

The com_err.h header file should be included in any source
file that uses routines from the com_err library; executable
files must be linked using ``-lcom_err'' in order to cause
the com_err library to be included.

SEE ALSO
compile_et (1), syslog (3).

Ken Raeburn, "A Common Error Description Library for UNIX".

-------

Here is an example of its usage (from "zwgc", the main client for the
Zephyr message delivery service):

if ( (nzqueued = ZPending()) == -1 )
{
if(errno == ZERR_EOF)
{
com_err("zwgc",errno," on select");
exit(-1); /* if eof, we still can't exit_cleanly */
}


--
John Carr "When they turn the pages of history,
j...@Athena.mit.edu When these days have passed long ago,
bloom-beacon! Will they read of us with sadness
athena.mit.edu!jfc For the seeds that we let grow?" --Neil Peart

Dan Bernstein

unread,
Apr 2, 1989, 9:34:49 PM4/2/89
to
I don't know about System V, but under BSD systems, including <errno.h>
gives you not only perror() but a sys_errlist[] of error message texts.
So how about this error message facility:

static char unknownerr[32];

char *err(errno)
int errno;
{
if (errno < 0 || errno >= sys_nerr)
{
(void) sprintf(unknownerr,"Unknown error number %d",errno);
return(unknownerr);
}
else
return(sys_errlist[errno]);
}

This is not a high-level routine, nor should it be. Instead of
attempting to build the generality of printf() into the error
message printer, I just reference err(errno) and use printf()
or sprintf() as usual. Why rebuild what's already there?

Some say that the error message facility should automatically print the
program name for you, and others say that the wave of ANSI/the future
is to include info/warning/verybad/fatal/endoftheworld; I'm happy with

fprintf(stderr,"%s: cannot open %s: %s\n",progname,fn,err(errno))
or
fprintf(stderr,"%s: endoftheworld: cannot open %s: %s\n",
progname,fn,err(errno))

(here progname is (argv[0] ? argv[0] : "Unknown program name")).

Along the same philosophy that motivates err(): if I ever found a need
to specify info/warning/fatal dynamically, I would much rather have a
function errlev() that returned a string based on a numeric input, and
continue using printf() at the top, than write a new errmsg() routine
for the occasion. I think this is the same philosophy behind a lot of
UNIX: combine little programs and functions to do big work.

---Dan Bernstein, bern...@phoenix.princeton.edu

Chris Torek

unread,
Apr 3, 1989, 10:27:18 AM4/3/89
to
In article <75...@phoenix.Princeton.EDU> bern...@phoenix.Princeton.EDU

(Dan Bernstein) writes:
> char *err(errno)
> int errno;
> {
> if ...
[compressed]
> else
> return(sys_errlist[errno]);
> }

This function is in the pANS, where it is called `strerror'. (The
implementation details---sys_errlist[], etc.---are not, but the function
that does what the one above does is called strerror.)

A slightly shorter test for the error number is

if ((unsigned)errno >= sys_nerr)
<out of range>
else
<in range; use sys_errlist>

>This is not a high-level routine, nor should it be. Instead of
>attempting to build the generality of printf() into the error
>message printer, I just reference err(errno) and use printf()
>or sprintf() as usual. Why rebuild what's already there?

Having an error printer that also exits is more convenient. Since
the latter is cheap (using vfprintf), why not provide both? I have
the function

error(int exitcode, int err, char *fmt, ...)

in our C library. It prints to stderr the program name (hidden away in
the external `_argv0', set by /lib/crt0.o), the string given by fmt+...,
appends strerror(err < 0 ? errno : err) if err != 0, appends a newline,
and then does an exit(exitcode) if exitcode != 0. (err is almost always
given as -1, and should perhaps be replaced with a boolean. If you want
something fancier, strerror() is there.) It is very handy:

if (argc < 2)
error(2, 0, "usage: %s filename", argv[0]);
if ((fd = open(argv[1], mode)) < 0)
error(1, -1, "cannot open %s", argv[1]);
...

Without it, you need

extern int errno;

if (argc < 2) {
(void) fprintf(stderr, "%s: usage: %s filename\n",
argv[0], argv[0]);
exit(2);
}
if ((fd = open(argv[1], mode)) < 0) {
(void) fprintf(stderr, "%s: cannot open %s: %s\n",
argv[0], argv[1], strerror(errno));
exit(1);
}

The difference is small, but significant (somewhat like using E-
notation for large floating point numbers---1.14E75 is easier to
read and write than 1140000000...000).

Guy Harris

unread,
Apr 3, 1989, 2:50:03 PM4/3/89
to
>I don't know about System V, but under BSD systems, including <errno.h>
>gives you not only perror() but a sys_errlist[] of error message texts.

This dates back long before BSD; it's a V7ism, and present in any modern
UNIX worthy of the name.

> char *err(errno)

Call it "strerror" instead - the ANSI C draft does.

>Some say that the error message facility should automatically print the
>program name for you, and others say that the wave of ANSI/the future
>is to include info/warning/verybad/fatal/endoftheworld;

I don't know about the wave of the future, but the (draft) ANSI C
standard says nothing about info/warning/...; POSIX P1003.1, which at
least at one point touted itself as a draft American National Standard -
although the final P1003.1 doesn't do so - says nothing about it either,
so I don't think it's the wave of ANSI.

It may show up in S5R4, but if so it'll probably let you turn off stuff
such as that if you don't want to see it.

0 new messages