xref: /original-bsd/lib/libc/stdio/fseek.c (revision 4f485440)
1 /* @(#)fseek.c	4.2 (Berkeley) 03/09/81 */
2 /*
3  * Seek for standard library.  Coordinates with buffering.
4  */
5 
6 #include	<stdio.h>
7 
8 long lseek();
9 
10 fseek(iop, offset, ptrname)
11 FILE *iop;
12 long offset;
13 {
14 	register resync, c;
15 	long p;
16 
17 	iop->_flag &= ~_IOEOF;
18 	if (iop->_flag&_IOREAD) {
19 		if (ptrname<2 && iop->_base &&
20 			!(iop->_flag&_IONBF)) {
21 			c = iop->_cnt;
22 			p = offset;
23 			if (ptrname==0)
24 				p += c - lseek(fileno(iop),0L,1);
25 			else
26 				offset -= c;
27 			if(!(iop->_flag&_IORW) && c>0&&p<=c
28 			    && p>=iop->_base-iop->_ptr){
29 				iop->_ptr += (int)p;
30 				iop->_cnt -= (int)p;
31 				return(0);
32 			}
33 			resync = offset&01;
34 		} else
35 			resync = 0;
36 		if (iop->_flag & _IORW) {
37 			iop->_ptr = iop->_base;
38 			iop->_flag &= ~_IOREAD;
39 		}
40 		p = lseek(fileno(iop), offset-resync, ptrname);
41 		iop->_cnt = 0;
42 		if (resync)
43 			getc(iop);
44 	}
45 	else if (iop->_flag & (_IOWRT|_IORW)) {
46 		fflush(iop);
47 		if (iop->_flag & _IORW) {
48 			iop->_cnt = 0;
49 			iop->_flag &= ~_IOWRT;
50 			iop->_ptr = iop->_base;
51 		}
52 		p = lseek(fileno(iop), offset, ptrname);
53 	}
54 	return(p==-1?-1:0);
55 }
56