V9/libc/stdio/fseek.c
/*
* Seek for standard library. Coordinates with buffering.
*/
#include <stdio.h>
long lseek();
fseek(iop, offset, ptrname)
register FILE *iop;
long offset;
{
register d;
register flag = iop->_flag;
register long p;
iop->_flag &= ~_IOEOF;
if (flag & _IOWRT)
fflush(iop);
if (flag & _IORW)
iop->_flag &= ~(_IOWRT|_IOREAD);
if ((flag&_IOREAD) && iop->_base && ptrname!=2) do {
if (ptrname==1 && offset<=iop->_cnt &&
offset>=iop->_base-iop->_ptr)
d = offset;
else {
p = lseek(fileno(iop), 0L, 1);
if (p < 0)
break;
d = iop->_cnt;
if (ptrname == 1) {
offset += p - d;
ptrname = 0;
}
if (offset<0 || flag&_IORW)
break;
p -= offset;
if (p >= 0 && p <= iop->_ptr - iop->_base + d)
d -= (int)p;
else {
d = (unsigned int)offset % BUFSIZ;
if (d == 0) /* room for ungetc */
break;
lseek(fileno(iop), offset - d, 0);
if (_filbuf(iop) == EOF)
break;
if (--d > iop->_cnt) /* part buf */
break;
}
}
iop->_cnt -= d;
iop->_ptr += d;
return (0);
} while (0);
if (flag & (_IORW|_IOREAD)) {
iop->_cnt = 0;
iop->_ptr = iop->_base;
}
return (lseek(fileno(iop), offset, ptrname) < 0? -1: 0);
}