[comp.sources.d] Inapproprtiae ioctl for user

peter@ficc.uu.net (Peter da Silva) (01/14/89)

It's not closely related, then, but it's the same basic problem... using
perror or errno where it's not meaningful.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Work: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.   `-_-'
Home: bigtex!texbell!sugar!peter, peter@sugar.uu.net.                 'U`
Opinions may not represent the policies of FICC or the Xenix Support group.

guy@auspex.UUCP (Guy Harris) (01/14/89)

>It's not closely related, then, but it's the same basic problem... using
>perror or errno where it's not meaningful.

No, not really; the problem with "fprintf" followed by "perror" is that
"errno" *is* meaningful before the "fprintf" but "fprintf" might destroy
it, and the problem in "sendmail" is that it isn't meaningful at all. 

As such, the fixes are different as well: in the first case, you
preserve "errno" (or generate the error message) before you call
"fprintf", and in the second case, you somehow indicate whether you
should bother doing anything with "errno" *at all*.  The fix to the
first problem doesn't apply to the second, nor does the fix to the
second problem apply to the first....

You can apply a common fix - namely, don't use "errno" at all - but that
is rather excessive for the first problem.

peter@ficc.uu.net (Peter da Silva) (01/15/89)

I said:
> >It's not closely related, then, but it's the same basic problem... using
> >perror or errno where it's not meaningful.
 
In article <846@auspex.UUCP>, guy@auspex.UUCP (Guy Harris) writes:
> No, not really; the problem with "fprintf" followed by "perror" is that
> "errno" *is* meaningful before the "fprintf" but "fprintf" might destroy
> it, and the problem in "sendmail" is that it isn't meaningful at all. 

The only place errno is meaningful is immediately after a system call that
has returned an error indication. After the fprintf it is no longer
meaningful.

You're just being a mite too literal-minded here. The exact code to fix the
problem is different, but the place to look is the same. It's like, if your
leg hurts, you want to start looking at the leg. The actual remedy is different
if it's caused by an insect bite or a cut, but it's still the leg that's
the problem.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Work: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.   `-_-'
Home: bigtex!texbell!sugar!peter, peter@sugar.uu.net.                 'U`
Opinions may not represent the policies of FICC or the Xenix Support group.

peter@ficc.uu.net (Peter da Silva) (01/16/89)

I said:
> >The exact code to fix the problem is different, but the place to look
> >is the same.

In article <852@auspex.UUCP>, guy@auspex.UUCP (Guy Harris) writes:
> No, it isn't.

Yes it is. The place to look is where you call perror. Then you trace
back from there to see how you might get to the call with an invalid
perror.

> fix - "errno = 0" statements are liberally sprinkled throughout the
> source).

Which sounds like you've got some incredibly poor design here. When I'm
doing a generalised error reporting mechanism, I do something like this:

errors.h:
	#define USE_ERRNO 0
	#define L_ESYNTAX 1
	#define L_EBOOJUM 2
	...

errors.c:
	#include <errno.h>
	#include "errors.h"

	char *local_errlist[] = {
		"Can't happen",
		"Syntax error",
		"Boojum",
		...
	};
	int local_nerr = sizeof local_errlist / sizeof local_errlist[0];
	extern char *sys_errlist[];
	extern int sys_nerr;
	extern int errno;

	local_perror(text, code)
	char text[];
	int code;
	{
		char **errlist;
		int nerr;

		if(code)
		{
			errlist = local_errlist;
			nerr = local_nerr;
		}
		else
		{
			errlist = sys_errlist;
			nerr = sys_nerr;
			code = errno;
		}

		if(code < nerr)
			fprintf(stderr, "%s: %s\n", text, local_errtab[code]);
		else
			fprintf(stderr, "%s: Unknown error %d\n", text, code);
	}

random_file.c:

	if(next_token != ':') {
		local_perror(line, ESYNTAX);
		return ERROR;
	}

	if(!(fp = fopen(file, "r"))) {
		local_perror(file, 0);
		return ERROR;
	}

> You have to look at more than just the routine that produces
> the error message.... 

Yes, you have to look at how it's called.

I'm sure there's a Zen koan about this somewhere... maybe the one about
the finger and the moon.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.
Work: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.   `-_-'
Home: bigtex!texbell!sugar!peter, peter@sugar.uu.net.                 'U`
Opinions may not represent the policies of FICC or the Xenix Support group.

guy@auspex.UUCP (Guy Harris) (01/17/89)

>The exact code to fix the problem is different, but the place to look
>is the same.

No, it isn't.  In the "fprintf"/"perror" case, the problem is localized
to those two calls.  In the "sendmail" case, the problem is scattered
throughout the code (and, in recent versions of "sendmail", so is the
fix - "errno = 0" statements are liberally sprinkled throughout the
source).  You have to look at more than just the routine that produces
the error message.... 

guy@auspex.UUCP (Guy Harris) (01/18/89)

>The place to look is where you call perror. Then you trace back from
>there to see how you might get to the call with an invalid perror.

And get lost in the code.  The problem is that the call that set
"errno" to a non-zero value was probably some "isatty" call somewhere
not connected with the call to "errstring" (which, BTW, contains no call
to "perror", it uses "sys_errlist" directly, so if you decide to look
where you call "perror" you're not going to be very successful).

>> fix - "errno = 0" statements are liberally sprinkled throughout the
>> source).
>
>Which sounds like you've got some incredibly poor design here.

*I* don't have *any* design here; I didn't write "sendmail".  There are
probably people who might agree with you about its design (but I'm going
to ask them not to start a debate on the merits of "sendmail", or the
quality of its design, here - it's nice that you (generic) have an
opinion on the subject, but please don't let it piddle on the carpet). 

In this particular case, part of the problem is that the "giveresponse"
routine doesn't take an error number as an argument - it uses "errno" as
a global variable.  However, it uses both "errno" and "h_errno", and you
could probably spend some time prowling through the code to figure out
which one should be passed and when. 

In addition, it's not clear that the code that calls "giveresponse"
would necessarily *know* whether to pass "errno" or 0 to a
"giveresponse" that took an error number as an argument; the error it's
going to use in the response came from some lower-level routine, and
that error might be due to a procedure call that failed and set "errno",
or it might not.

A better analogy than the leg injury given earlier might be a pain in
the chest; is it a heart attack, or heartburn, or...?  The fact that
it's a chest pain localizes it somewhat, but just because two problems
cause pain in the chest doesn't mean they're particularly related.