1 /* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
24 /* Move the file position of STREAM to OFFSET
25 bytes from the beginning of the file if WHENCE
26 is SEEK_SET, the end of the file is it is SEEK_END,
27 or the current position if it is SEEK_CUR. */
29 DEFUN(fseek
, (stream
, offset
, whence
),
30 register FILE *stream AND
long int offset AND
int whence
)
34 if (!__validfp (stream
))
40 /* Write out any pending data. */
41 if (stream
->__mode
.__write
&& __flshfp (stream
, EOF
) == EOF
)
44 /* Make sure we know the current offset info. */
45 if (__stdio_check_offset (stream
) == EOF
)
48 /* We are moving the file position, so we are no longer at EOF. */
51 if (stream
->__pushed_back
)
53 /* Discard the character pushed back by ungetc. */
54 stream
->__bufp
= stream
->__pushback_bufp
;
55 stream
->__pushed_back
= 0;
58 /* Check the WHENCE argument for validity, and process OFFSET
59 into an absolute position in O. By the end of this switch,
60 either we have returned, or O contains an absolute position. */
69 /* We don't know where the end of the file is,
70 so seek to the position in the file the user asked
71 for, and then look where that is. */
72 if (stream
->__io_funcs
.__seek
== NULL
)
79 fpos_t pos
= (fpos_t) o
;
80 if ((*stream
->__io_funcs
.__seek
)
81 (stream
->__cookie
, &pos
, SEEK_END
) < 0)
84 stream
->__io_funcs
.__seek
= NULL
;
87 stream
->__offset
= pos
;
88 /* Make O be absolute, rather than
89 relative to the end of the file. */
93 /* Fall through to try an absolute seek. */
96 /* Make O be relative to the buffer. */
97 o
-= stream
->__target
;
98 /* Make O be relative to the current position in the buffer. */
99 o
-= stream
->__bufp
- stream
->__buffer
;
101 /* Fall through to see if we can do it by
102 moving the pointer around in the buffer. */
105 /* If the offset is small enough, we can just
106 move the pointer around in the buffer. */
108 #if 0 /* Why did I think this would ever work??? */
109 if (stream
->__put_limit
> stream
->__buffer
)
111 /* We are writing. */
112 if (stream
->__bufp
+ o
>= stream
->__buffer
&&
113 stream
->__put_limit
> stream
->__bufp
+ o
&&
114 stream
->__get_limit
> stream
->__bufp
+ o
)
116 /* We have read all the data we will change soon.
117 We can just move the pointer around. */
123 /* Flush the buffer. */
124 if (__flshfp(stream
, EOF
) == EOF
)
130 (-o
<= stream
->__bufp
- stream
->__buffer
) :
131 (o
<= stream
->__get_limit
- stream
->__bufp
))
137 /* Turn it into an absolute seek. */
138 o
+= stream
->__bufp
- stream
->__buffer
;
139 o
+= stream
->__target
;
145 /* Negative file position is meaningless. */
150 /* O is now an absolute position, the new target. */
151 stream
->__target
= o
;
153 /* Set bufp and both end pointers to the beginning of the buffer.
154 The next i/o will force a call to the input/output room function. */
156 = stream
->__get_limit
= stream
->__put_limit
= stream
->__buffer
;
158 /* Make sure __flshfp doesn't think the put_limit is at the beginning
159 of the buffer because of line-buffering magic. */
160 stream
->__linebuf_active
= 0;
162 /* If there is no seek function, seeks always fail. */
163 if (stream
->__io_funcs
.__seek
== NULL
)
165 /* This is preemptive, since we don't actually do the seeking.
166 But it makes more sense for fseek to to fail with ESPIPE
167 than for the next reading or writing operation to fail
173 /* Don't actually seek. The next reading or writing operation
174 will force a call to the input or output room function,
175 which will move to the target file position before reading or writing. */