Sender: nate AT cartsys DOT com Message-ID: <37043DBC.C076CB2@cartsys.com> Date: Thu, 01 Apr 1999 19:47:08 -0800 From: Nate Eldredge X-Mailer: Mozilla 4.08 [en] (X11; I; Linux 2.2.5 i586) MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Re: [davidprrenz AT cityweb DOT de: DJGPP-Problem] References: <199904020136 DOT UAA25678 AT envy DOT delorie DOT com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com DJ Delorie wrote: > > Could someone do a patch that abort()s whenever you try to fflush() an > input stream, preferably with a suitably FAQ answer? I don't think it's a good idea. Aborting on an invalid operation is awfully harsh, especially when a mechanism exists for reporting errors. Just because ANSI allows us the loophole of undefined behavior to abort, I don't think it's very clean or professional to exploit it. I note that we don't complain at all, and *that* I believe we should do. Following is a patch to set errno to EINVAL and return EOF when fflushing an input stream. I realize this isn't a big change in real life; the lusers who try to fflush stdin probably won't be checking the return value either. But something like abort strikes me as a bit self-serving; it's mainly to keep *us* from having to give clues to the clueless. Btw, this doesn't seem to be in the FAQ (unless I've missed something). Adding it should certainly be the first line of defense. We should escalate to behavior like this only if it seems absolutely necessary, and IMHO, at this time, it doesn't. > Note: Linux doesn't support flushing input streams either. Actually, with glibc 2.1 using libio, it seems to. At least fflush(stdin) returns 0 and doesn't set errno. From what I can make of the libio source (it's pretty incomprehensible), it looks like fflush() of an input stream attempts to lseek back and refill the buffer to its current point. This would be an extension. An error return of ESPIPE is ignored. Though with the stdio implementation, it does return EOF and set errno to EINVAL. Here's the patch to do the same. *** src/libc/ansi/stdio/fflush.c Sun Jun 28 16:36:20 1998 --- src/libc/ansi/stdio/fflush.c.new Thu Apr 1 19:32:47 1999 *************** *** 16,34 **** --- 16,51 ---- { char *base; int n, rn; + static int puke_on_read_only = 1; if (f == NULL) { int e = errno; errno = 0; + puke_on_read_only = 0; _fwalk((void (*)(FILE *))fflush); + puke_on_read_only = 1; if (errno) return EOF; errno = e; return 0; } + if ((f->_flag & _IOREAD)) + { + if (puke_on_read_only) + { + errno = EINVAL; + return EOF; + } + else + { + /* For fflush(NULL), fwalk will try all files indiscriminately, + including read-onlys. Don't act like it's an error. */ + return 0; + } + } f->_flag &= ~_IOUNGETC; if ((f->_flag&(_IONBF|_IOWRT))==_IOWRT && (base = f->_base) != NULL -- Nate Eldredge nate AT cartsys DOT com