V9/libc/stdio/fseek.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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);
}