/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * %sccs.include.redist.c% */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ftell.c 5.4 (Berkeley) 02/05/91"; #endif /* LIBC_SCCS and not lint */ #include #include #include "local.h" /* * ftell: return current offset. */ long ftell(fp) register const FILE *fp; { register fpos_t pos; if (fp->_seek == NULL) { errno = ESPIPE; /* historic practice */ return (-1L); } /* * Find offset of underlying I/O object, then * adjust for buffered bytes. */ if (fp->_flags & __SOFF) pos = fp->_offset; else { pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR); if (pos == -1L) return (pos); } if (fp->_flags & __SRD) { /* * Reading. Any unread characters (including * those from ungetc) cause the position to be * smaller than that in the underlying object. */ pos -= fp->_r; if (HASUB(fp)) pos -= fp->_ur; } else if (fp->_flags & __SWR && fp->_p != NULL) { /* * Writing. Any buffered characters cause the * position to be greater than that in the * underlying object. */ pos += fp->_p - fp->_bf._base; } return (pos); }