Path: utzoo!attcan!uunet!husc6!uwvax!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: _IOSTRG in stdio.h Message-ID: <14561@mimsy.UUCP> Date: 15 Nov 88 13:54:47 GMT References: <1004@cps3xx.UUCP> <14413@mimsy.UUCP> <1353@mcgill-vision.UUCP> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 74 >In article <14413@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@mcgill-vision.UUCP> mouse@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@mimsy.umd.edu Path: uunet!mimsy!chris