1 /*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 05/04/95"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <stdio.h> 16 #include <errno.h> 17 #include "local.h" 18 19 /* 20 * ftell: return current offset. 21 */ 22 long 23 ftell(fp) 24 register FILE *fp; 25 { 26 register fpos_t pos; 27 28 if (fp->_seek == NULL) { 29 errno = ESPIPE; /* historic practice */ 30 return (-1L); 31 } 32 33 /* 34 * Find offset of underlying I/O object, then 35 * adjust for buffered bytes. 36 */ 37 if (fp->_flags & __SOFF) 38 pos = fp->_offset; 39 else { 40 pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR); 41 if (pos == -1L) 42 return (pos); 43 } 44 if (fp->_flags & __SRD) { 45 /* 46 * Reading. Any unread characters (including 47 * those from ungetc) cause the position to be 48 * smaller than that in the underlying object. 49 */ 50 pos -= fp->_r; 51 if (HASUB(fp)) 52 pos -= fp->_ur; 53 } else if (fp->_flags & __SWR && fp->_p != NULL) { 54 /* 55 * Writing. Any buffered characters cause the 56 * position to be greater than that in the 57 * underlying object. 58 */ 59 pos += fp->_p - fp->_bf._base; 60 } 61 return (pos); 62 } 63