From: Nigel Stephens Date: Wed, 24 Aug 94 16:19:50 +0100 To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Bug in fseek I have discovered a bug in the fseek routine in the 1.12 C library. A recent change to it disabled the offset adjustment which accounted for data that had already been read into the stdio buffer. This totally broke relative (i.e. SEEK_CUR) fseeks. The following patch to libsrc/c/io/fseek.c reenables the offset/buffer synchronisation, but removes the spurious code that tried to align the seek to a word boundary, and would have broken backward relative seeks. I have rebuilt fseek with these changes and it now appears to work correctly. =================================================================== RCS file: fseek.c,v retrieving revision 1.1 diff -c -r1.1 fseek.c *** 1.1 1994/08/22 16:04:07 --- fseek.c 1994/08/22 16:01:09 *************** *** 24,49 **** register FILE *iop; long offset; { ! register resync, c; long p = -1; /* can't happen? */ long adjust = 0; char *q, *qq; iop->_flag &= ~_IOEOF; if (iop->_flag&_IOREAD) { ! #if 0 ! if (ptrname<2 && iop->_base && !(iop->_flag&_IONBF)) { c = iop->_cnt; p = offset; ! if (ptrname==0) { long curpos = lseek(fileno(iop), 0L, 1); if (curpos == -1) return (-1); p += c - curpos; } else offset -= c; ! if(!(iop->_flag&_IORW) && c>0&&p<=c && p>=iop->_base-iop->_ptr){ if (iop->_flag&_IOTEXT){ q = &iop->_ptr[iop->_cnt]; --- 24,48 ---- register FILE *iop; long offset; { ! register long c; long p = -1; /* can't happen? */ long adjust = 0; char *q, *qq; iop->_flag &= ~_IOEOF; if (iop->_flag&_IOREAD) { ! if (ptrname!=SEEK_END && iop->_base && !(iop->_flag&_IONBF)) { c = iop->_cnt; p = offset; ! if (ptrname==SEEK_SET) { long curpos = lseek(fileno(iop), 0L, 1); if (curpos == -1) return (-1); p += c - curpos; } else offset -= c; ! if(!(iop->_flag&_IORW) && c>0 && p<=c && p>=iop->_base-iop->_ptr){ if (iop->_flag&_IOTEXT){ q = &iop->_ptr[iop->_cnt]; *************** *** 58,79 **** iop->_cnt -= (int)p; return(0); } ! resync = offset&01; ! } else ! resync = 0; ! #endif if (iop->_flag & _IORW) { iop->_ptr = iop->_base; iop->_flag &= ~_IOREAD; - resync = 0; } ! p = lseek(fileno(iop), offset-resync, ptrname); iop->_cnt = 0; - #if 0 - if (resync && p != -1) - if (getc(iop) == EOF) - p = -1; - #endif } else if (iop->_flag & (_IOWRT|_IORW)) { p = fflush(iop); --- 57,69 ---- iop->_cnt -= (int)p; return(0); } ! } if (iop->_flag & _IORW) { iop->_ptr = iop->_base; iop->_flag &= ~_IOREAD; } ! p = lseek(fileno(iop), offset, ptrname); iop->_cnt = 0; } else if (iop->_flag & (_IOWRT|_IORW)) { p = fflush(iop);