Mail Archives: djgpp-workers/1999/04/01/22:47:03
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
- Raw text -