_IOSTRG in stdio.h
Chris Torek
chris at mimsy.UUCP
Tue Nov 15 23:54:47 AEST 1988
>In article <14413 at mimsy.UUCP> I claimed:
>>... It is never tested. You can expect it to vanish in the future.
[what, Never? well, Hardly Ever :-) ]
In article <1353 at mcgill-vision.UUCP> mouse at mcgill-vision.UUCP
(der Mouse) writes:
>[Reality check time: I'm about to disagree with Chris.]
[Yipes, that was my third egregious netnews error in the last few weeks.
What *is* the world coming to? ... Must have been the worm! :-) ]
>flsbuf.c:
> fclose(iop)
>....
> (iop->_flag&_IOSTRG)==0
This one is actually rather amusing, as the routines which set _IOSTRG
never call fclose(), and the FILE blocks in which _IOSTRG is set are
not on the regular list, so an exit() in a signal handler will never
see them. In other words, this test is always true.
>filbuf.c:
> if (iop->_flag&(_IOSTRG|_IOEOF))
This one is probably actually necessary in the current implementation.
(Actually, there is an easy hack to make it unnecessary.)
The last time I actually ran `grep _IOSTRG' on the source was for
4.1BSD, as I had just run into an interesting bug in (Gosling) Emacs.
>To answer what the original poster probably wanted to know, _IOSTRG
>indicates that the stream is a fake stream for I/O to a string: sprintf
>or sscanf. As for what it actually *controls*, Chris is almost
>correct; I think _doprnt doesn't check this flag at all [VAX version],
>and (bug alert!) neither does _flsbuf.
Right. This led to the bug I was investigating when I found this.
>If you sprintf more than 32K, sprintf will make mistakes. Initially,
>the mistakes are (relatively) benign (the sprintffed output past 32K
>gets stuffed in malloc()ed memory which is then lost), but if you push
>it to 40K, it will start flushing stuff to a random file descriptor ....
I was using a routine called `sprintfl', which took a length parameter
and `guaranteed' not to write past the end of that length. The code
was (before varargs cleanup)
char *
sprintfl(buf, len, fmt, a1)
char *buf;
int len;
char *fmt;
{
FILE f;
f._flag = _IOWRT|_IOSTRG;
f._ptr = buf;
f._cnt = len - 1;
_doprnt(fmt, &a1, &f);
putc('\0', &f);
buf[len-1] = '\0';
return (buf);
}
It misbehaved terribly (along the lines der Mouse indicated).
The `fix' was to change the first code line to
f._flag = _IOSTRG;
!
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list