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