In article <news:1b*************************@posting.google.c om>
lynology <ya*********@lmco.com> wrote:
I need help trying to figure why this piece of code gives me a "Bad
File descriptor error" everytime I try to run it and invoke fflush.
[snippage]if (strlen(cdukeypad->Scrpad) > 0){
printf("Character received is %s.\n", cdukeypad->Scrpad);
if (strlen(CG_cdukeypad_CHA.Scrpad) < 25){
strcat(CG_cdukeypad_CHA.Scrpad, cdukeypad->Scrpad);
}
if (fflush(NULL) == EOF){
VP_INFO(("Error writing text to Scratchpad.\n"));
VP_INFO(("Error is %s\n", strerror(errno)));
}
}
[/code]
(a) What is VP_INFO?
(b) "errno" is, in effect, a "global variable". Global variables
have some very bad properties.
(c) Let me suppose, just for argument, that VP_INFO turns into an
fprintf to stderr or similar. Let me suppose further that
fflush(NULL) (which f{flush()es all open output streams) is
in fact returning EOF for some reason, and -- despite the nasty
nature of a single global "errno" -- has managed to record the
reason for the (possibly dozens of) failure(s) in "errno".
Alas, the very first fprintf() to stderr invokes some OS
code that tests to see if stderr is connected to an interactive
device. This code happens to clobber errno, setting it to
EBADF ("Bad file descriptor"). Then:
- fflush(NULL) returns EOF and sets errno
- the first VP_INFO(...) destroys that errno, replacing
it with a new value
- the second VP_INFO(...) invokes strerrno on the bogus
errno.
(d) "Global variables" (including errno) have some very bad
properties. I realize this is actually just one flaw, but
it is so huge I decided to mention it twice. :-) [I have
a keyring that says "my other spaceship is the Red Dwarf"]
Anyway, because the errno mechanism is such a fragile one, you
must make sure you capture the value immediately after a failure:
if (fflush(NULL) == EOF) {
int e = errno;
... /* things that may clobber errno, but we saved it */
... strerror(e) ...
}
or:
if (fflush(NULL) == EOF) {
const char *s = strerror(errno);
... /* more things that may clobber errno */
... s ...
}
Since strerror() is also allowed to use static data, the first form
is generally a bit safer.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.