Deleted Added
full compact
1/*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 25 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38#if 0
39static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 5/4/95";
40#endif
41static const char rcsid[] =
42 "$FreeBSD: head/lib/libc/stdio/ftell.c 82684 2001-08-31 20:36:19Z ache $";
42 "$FreeBSD: head/lib/libc/stdio/ftell.c 82709 2001-09-01 01:56:54Z ache $";
43#endif /* LIBC_SCCS and not lint */
44
45#include "namespace.h"
46#include <sys/types.h>
47#include <errno.h>
48#include <limits.h>
49#include <stdio.h>
50#include "un-namespace.h"

--- 19 unchanged lines hidden (view full) ---

70
71/*
72 * ftello: return current offset.
73 */
74off_t
75ftello(fp)
76 register FILE *fp;
77{
78 register off_t rv;
78 fpos_t rv;
79 int ret;
80
81 /* make sure stdio is set up */
82 if (!__sdidinit)
83 __sinit();
84
85 FLOCKFILE(fp);
85 rv = _ftello(fp);
86 ret = _ftello(fp, &rv);
87 FUNLOCKFILE(fp);
88 if (ret)
89 return (-1);
90 if (rv < 0) /* Unspecified value because of ungetc() at 0 */
91 rv = 0;
92 return (rv);
93}
94
90off_t
91_ftello(fp)
95int
96_ftello(fp, offset)
97 register FILE *fp;
98 fpos_t *offset;
99{
100 register fpos_t pos, spos;
101 size_t n;
102
103 if (fp->_seek == NULL) {
104 errno = ESPIPE; /* historic practice */
99 return (-1);
105 return (1);
106 }
107
108 /*
109 * Find offset of underlying I/O object, then
110 * adjust for buffered bytes.
111 */
112 if (fp->_flags & __SOFF) {
113 pos = fp->_offset;
114 spos = -1;
115 } else {
116get_real_pos:
117 spos = pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
118 if (pos == -1)
113 return (-1);
119 return (1);
120 }
121 if (fp->_flags & __SRD) {
122 /*
123 * Reading. Any unread characters (including
124 * those from ungetc) cause the position to be
125 * smaller than that in the underlying object.
126 */
121 if ((pos -= fp->_r) < 0 ||
122 (HASUB(fp) && (pos -= fp->_ur) < 0)) {
123 fp->_p = fp->_bf._base;
124 fp->_r = 0;
125 if (HASUB(fp))
126 FREEUB(fp);
127 if ((pos -= (HASUB(fp) ? fp->_ur : fp->_r)) < 0) {
128 /* Lost position, resync. */
129 if (HASUB(fp)) {
130 fp->_extra->_up = fp->_bf._base;
131 fp->_ur = 0;
132 } else {
133 fp->_p = fp->_bf._base;
134 fp->_r = 0;
135 }
136 if (spos == -1)
137 goto get_real_pos;
138 pos = spos;
139 }
140 if (HASUB(fp))
141 pos -= fp->_r; /* Can be negative at this point. */
142 } else if ((fp->_flags & __SWR) && fp->_p != NULL) {
143 /*
144 * Writing. Any buffered characters cause the
145 * position to be greater than that in the
146 * underlying object.
147 */
148 n = fp->_p - fp->_bf._base;
149 if (pos > OFF_MAX - n) {
150 errno = EOVERFLOW;
140 return (-1);
151 return (1);
152 }
153 pos += n;
154 }
144 return (pos);
155 *offset = pos;
156 return (0);
157}