xref: /csrg-svn/lib/libc/stdio/fseek.c (revision 26653)
1 #if defined(LIBC_SCCS) && !defined(lint)
2 static char sccsid[] = "@(#)fseek.c	5.3 (Berkeley) 03/09/86";
3 #endif LIBC_SCCS and not lint
4 
5 /*
6  * Seek for standard library.  Coordinates with buffering.
7  */
8 
9 #include	<stdio.h>
10 
11 long lseek();
12 
13 fseek(iop, offset, ptrname)
14 	register FILE *iop;
15 	long offset;
16 {
17 	register resync, c;
18 	long p = -1;			/* can't happen? */
19 
20 	iop->_flag &= ~_IOEOF;
21 	if (iop->_flag&_IOREAD) {
22 		if (ptrname<2 && iop->_base &&
23 			!(iop->_flag&_IONBF)) {
24 			c = iop->_cnt;
25 			p = offset;
26 			if (ptrname==0) {
27 				long curpos = lseek(fileno(iop), 0L, 1);
28 				if (curpos == -1)
29 					return (-1);
30 				p += c - curpos;
31 			} else
32 				offset -= c;
33 			if(!(iop->_flag&_IORW) && c>0&&p<=c
34 			    && p>=iop->_base-iop->_ptr){
35 				iop->_ptr += (int)p;
36 				iop->_cnt -= (int)p;
37 				return(0);
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 && p != -1)
50 			if (getc(iop) == EOF)
51 				p = -1;
52 	}
53 	else if (iop->_flag & (_IOWRT|_IORW)) {
54 		p = fflush(iop);
55 		if (iop->_flag & _IORW) {
56 			iop->_cnt = 0;
57 			iop->_flag &= ~_IOWRT;
58 			iop->_ptr = iop->_base;
59 		}
60 		return(lseek(fileno(iop), offset, ptrname) == -1 || p == EOF ?
61 		    -1 : 0);
62 	}
63 	return(p==-1?-1:0);
64 }
65