[net.bugs.usg] SVR2

rcj@burl.UUCP (Curtis Jackson) (08/28/85)

This bug is known to the Unix Hotline and the appropriate PIC (People
In Charge), but wasn't known to me so I thought I'd share it.

If you open a file for simple update (mode "r+" on fopen), then read
some stuff in the file, then try to write on the file, the writes
will appear to work perfectly (printf returns good bytecounts and
everything), but no writes will take place in the real world.

This happens because the code to check for _IORW (read/write permissions)
is wrong in printf.c, fprintf.c, vprintf.c, and vfprintf.c.  This
causes the write permissions (_IOWRT) turnon code to be skipped and
_doprnt() returns a negative number; so the _cnt field in the FILE
descriptor decrements rather than increments, and the fflush() therefore
has no effect -- thus silently no writes.

The errant lines are:

	if (!(stdout->_flag | _IOWRT)) {
		/* if no write flag */
		if (stdout->_flag | _IORW) {

since |'ing with a constant is not a very good idea, change them to &'s:

	if (!(stdout->_flag & _IOWRT)) {
		/* if no write flag */
		if (stdout->_flag & _IORW) {

and everything works fine.

I found this bug very interesting to track down since (apparently) the
initial modes on the file are both _IOWRT and _IORW.  This means that
if you just write a file fopened with "r+" everything works, but the
first read turns off _IOWRT and any subsequent writes silently fail.

Don't forget to remake the library!!
-- 

The MAD Programmer -- 919-228-3313 (Cornet 291)
alias: Curtis Jackson	...![ ihnp4 ulysses cbosgd mgnetp ]!burl!rcj
			...![ ihnp4 cbosgd akgua masscomp ]!clyde!rcj

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/20/86)

Dave Yost found a bug in nroff that can cause a core dump on some machines.
In file n1.c, init1() contains a call to mchbits(), which uses device-
specific data that has not yet been set up!  This file is shared by otroff,
which therefore has the same bug.  BWK seems to have fixed it in new troff.

/*
 *	roff.src  -  v 2.9 of 9/9/83
...
 */
...
#ifdef NROFF
char ntversion[] = "@(#)nroff:	n1.c 2.9";
#else
char ntversion[] = "@(#)otroff:	n1.c 2.9";
#endif
...
int version = 29;		/* nroff/troff version tag */
...
init1(a)	/* DAG -- there was a FF at the beginning of this line! */
char a;
{
...
	trtab[UNPAD] = ' ';
/*	mchbits();	/* DAG -- device info not available here; moved to init2() (fixes bug reported by Dave Yost) */
...
}
init2()		/* DAG -- FF here too! */
{
...
	ptinit();
	mchbits();	/* DAG -- moved here from init1() */
...