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