xref: /csrg-svn/lib/libc/stdio/fseek.c (revision 22134)
1 #ifndef lint
2 static char sccsid[] = "@(#)fseek.c	5.1 (Berkeley) 06/05/85";
3 #endif not lint
4 
5 /*
6  * Seek for standard library.  Coordinates with buffering.
7  */
8 
9 #include	<stdio.h>
10 
11 long lseek();
12 
13 long
14 fseek(iop, offset, ptrname)
15 	register FILE *iop;
16 	long offset;
17 {
18 	register resync, c;
19 	long p, curpos = -1;
20 
21 	iop->_flag &= ~_IOEOF;
22 	if (iop->_flag&_IOREAD) {
23 		if (ptrname<2 && iop->_base &&
24 			!(iop->_flag&_IONBF)) {
25 			c = iop->_cnt;
26 			p = offset;
27 			if (ptrname==0) {
28 				curpos = lseek(fileno(iop), 0L, 1);
29 				if (curpos == -1)
30 					return (-1);
31 				p += c - curpos;
32 			} else
33 				offset -= c;
34 			if(!(iop->_flag&_IORW) && c>0&&p<=c
35 			    && p>=iop->_base-iop->_ptr){
36 				iop->_ptr += (int)p;
37 				iop->_cnt -= (int)p;
38 				if (curpos == -1)
39 					curpos = lseek(fileno(iop), 0L, 1);
40 				return (curpos == -1? -1: curpos - iop->_cnt);
41 			}
42 			resync = offset&01;
43 		} else
44 			resync = 0;
45 		if (iop->_flag & _IORW) {
46 			iop->_ptr = iop->_base;
47 			iop->_flag &= ~_IOREAD;
48 			resync = 0;
49 		}
50 		p = lseek(fileno(iop), offset-resync, ptrname);
51 		iop->_cnt = 0;
52 		if (resync && getc(iop) != EOF && p != -1)
53 			p++;
54 	}
55 	else if (iop->_flag & (_IOWRT|_IORW)) {
56 		fflush(iop);
57 		if (iop->_flag & _IORW) {
58 			iop->_cnt = 0;
59 			iop->_flag &= ~_IOWRT;
60 			iop->_ptr = iop->_base;
61 		}
62 		p = lseek(fileno(iop), offset, ptrname);
63 	}
64 	return(p);
65 }
66