Commit | Line | Data |
---|---|---|
411867e7 KB |
1 | /*- |
2 | * Copyright (c) 1990 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Chris Torek. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
0ad97561 BJ |
9 | */ |
10 | ||
411867e7 | 11 | #if defined(LIBC_SCCS) && !defined(lint) |
d25ccb19 | 12 | static char sccsid[] = "@(#)ftell.c 5.4 (Berkeley) %G%"; |
411867e7 | 13 | #endif /* LIBC_SCCS and not lint */ |
0ad97561 | 14 | |
411867e7 KB |
15 | #include <stdio.h> |
16 | #include <errno.h> | |
17 | #include "local.h" | |
0ad97561 | 18 | |
411867e7 KB |
19 | /* |
20 | * ftell: return current offset. | |
21 | */ | |
22 | long | |
23 | ftell(fp) | |
d25ccb19 | 24 | register const FILE *fp; |
0ad97561 | 25 | { |
411867e7 KB |
26 | register fpos_t pos; |
27 | ||
28 | if (fp->_seek == NULL) { | |
29 | errno = ESPIPE; /* historic practice */ | |
30 | return (-1L); | |
31 | } | |
0ad97561 | 32 | |
411867e7 KB |
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); | |
0ad97561 | 62 | } |