SVR2.0 stdio bugs
Doug Gwyn
gwyn at smoke.BRL.MIL
Thu Aug 17 04:32:36 AEST 1989
We just discovered that the UNIX System V stdio writing routines, in three
out of four uses of the write() system call, fail to properly deal with a
short write count return, and in one case doesn't even detect an I/O error.
Here are the fixes we applied:
In libc/port/stdio/flsbuf.c:
/* @(#)flsbuf.c 2.8 */
...
int
_flsbuf(c, iop)
unsigned char c;
register FILE *iop;
{
unsigned char c1;
register int w; /* DAG -- write() return count */
...
/* write out an unbuffered file, if have write perm, but no EOF */
if ( (iop->_flag & (_IONBF | _IOWRT | _IOEOF)) == (_IONBF | _IOWRT) ) {
c1 = c;
iop->_cnt = 0;
while ((w = write(fileno(iop), (char *) &c1, 1)) == 0)
; /* DAG -- loop! */
if (w > 0)
return(c);
iop->_flag |= _IOERR;
return(EOF);
}
...
int
_xflsbuf(iop)
register FILE *iop;
{
register unsigned char *base;
register int n;
register int w; /* DAG -- write() return count */
...
_BUFSYNC(iop);
while (n > 0) /* DAG -- loop! */
if ((w = write(fileno(iop),(char*)base,(unsigned)n)) < 0) {
iop->_flag |= _IOERR;
return(EOF);
} else {
base += w;
n -= w;
}
return(0);
In libc/port/stdio/fputs.c:
/* <@(#)fputs.c 3.5> */
...
int
fputs(ptr, iop)
char *ptr;
register FILE *iop;
{
...
} else {
/* write out to an unbuffered file */
register unsigned int cnt = strlen(ptr);
register unsigned int r = cnt; /* DAG -- bytes remaining */
register int w; /* DAG -- write() return count */
while (r > 0) /* DAG -- loop! */
if ((w = write(iop->_file, ptr, r)) < 0) {
iop->_flag |= _IOERR;
return(EOF); /* DAG -- report error! */
} else {
ptr += w;
r -= w;
}
return cnt;
}
More information about the Comp.bugs.sys5
mailing list