xref: /csrg-svn/lib/libc/stdio/ftell.c (revision 46088)
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