xref: /csrg-svn/lib/libc/stdio/ftell.c (revision 69214)
146088Sbostic /*-
261180Sbostic  * Copyright (c) 1990, 1993
361180Sbostic  *	The Regents of the University of California.  All rights reserved.
446088Sbostic  *
546088Sbostic  * This code is derived from software contributed to Berkeley by
646088Sbostic  * Chris Torek.
746088Sbostic  *
846088Sbostic  * %sccs.include.redist.c%
946088Sbostic  */
1046088Sbostic 
1126654Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*69214Sbostic static char sccsid[] = "@(#)ftell.c	8.2 (Berkeley) 05/04/95";
1346088Sbostic #endif /* LIBC_SCCS and not lint */
1422135Smckusick 
1546088Sbostic #include <stdio.h>
1646088Sbostic #include <errno.h>
1746088Sbostic #include "local.h"
1846088Sbostic 
192011Swnj /*
2046088Sbostic  * ftell: return current offset.
212011Swnj  */
2246088Sbostic long
ftell(fp)2346088Sbostic ftell(fp)
24*69214Sbostic 	register FILE *fp;
2546088Sbostic {
2646088Sbostic 	register fpos_t pos;
272011Swnj 
2846088Sbostic 	if (fp->_seek == NULL) {
2946088Sbostic 		errno = ESPIPE;			/* historic practice */
3046088Sbostic 		return (-1L);
3146088Sbostic 	}
322011Swnj 
3346088Sbostic 	/*
3446088Sbostic 	 * Find offset of underlying I/O object, then
3546088Sbostic 	 * adjust for buffered bytes.
3646088Sbostic 	 */
3746088Sbostic 	if (fp->_flags & __SOFF)
3846088Sbostic 		pos = fp->_offset;
3946088Sbostic 	else {
4046088Sbostic 		pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
4146088Sbostic 		if (pos == -1L)
4246088Sbostic 			return (pos);
4346088Sbostic 	}
4446088Sbostic 	if (fp->_flags & __SRD) {
4546088Sbostic 		/*
4646088Sbostic 		 * Reading.  Any unread characters (including
4746088Sbostic 		 * those from ungetc) cause the position to be
4846088Sbostic 		 * smaller than that in the underlying object.
4946088Sbostic 		 */
5046088Sbostic 		pos -= fp->_r;
5146088Sbostic 		if (HASUB(fp))
5246088Sbostic 			pos -= fp->_ur;
5346088Sbostic 	} else if (fp->_flags & __SWR && fp->_p != NULL) {
5446088Sbostic 		/*
5546088Sbostic 		 * Writing.  Any buffered characters cause the
5646088Sbostic 		 * position to be greater than that in the
5746088Sbostic 		 * underlying object.
5846088Sbostic 		 */
5946088Sbostic 		pos += fp->_p - fp->_bf._base;
6046088Sbostic 	}
6146088Sbostic 	return (pos);
622011Swnj }
63