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.