]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/strops.c
Fix trailing space.
[thirdparty/glibc.git] / libio / strops.c
CommitLineData
b168057a 1/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
96aa2d94 3
41bdb6e2
AJ
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
96aa2d94 8
41bdb6e2
AJ
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
40a55d20 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2
AJ
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>.
41bdb6e2
AJ
17
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
96aa2d94 26
107b8a92 27#include <assert.h>
96aa2d94
RM
28#include "strfile.h"
29#include "libioP.h"
30#include <string.h>
0d875352 31#include <stdio_ext.h>
96aa2d94 32
96aa2d94 33void
40a54e4d 34_IO_str_init_static_internal (sf, ptr, size, pstart)
2ca8b1ee 35 _IO_strfile *sf;
40a55d20 36 char *ptr;
40a54e4d 37 _IO_size_t size;
40a55d20 38 char *pstart;
96aa2d94 39{
2ca8b1ee 40 _IO_FILE *fp = &sf->_sbf._f;
40a54e4d 41 char *end;
2ca8b1ee 42
96aa2d94 43 if (size == 0)
40a54e4d
UD
44 end = __rawmemchr (ptr, '\0');
45 else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr)
46 end = ptr + size;
47 else
48 end = (char *) -1;
d18ea0c5 49 _IO_setb (fp, ptr, end, 0);
96aa2d94
RM
50
51 fp->_IO_write_base = ptr;
52 fp->_IO_read_base = ptr;
53 fp->_IO_read_ptr = ptr;
54 if (pstart)
55 {
56 fp->_IO_write_ptr = pstart;
40a54e4d 57 fp->_IO_write_end = end;
96aa2d94
RM
58 fp->_IO_read_end = pstart;
59 }
60 else
61 {
62 fp->_IO_write_ptr = ptr;
63 fp->_IO_write_end = ptr;
40a54e4d 64 fp->_IO_read_end = end;
96aa2d94 65 }
96aa2d94 66 /* A null _allocate_buffer function flags the strfile as being static. */
2ca8b1ee 67 sf->_s._allocate_buffer = (_IO_alloc_type) 0;
96aa2d94 68}
40a54e4d
UD
69
70void
71_IO_str_init_static (sf, ptr, size, pstart)
72 _IO_strfile *sf;
73 char *ptr;
74 int size;
75 char *pstart;
76{
77 return _IO_str_init_static_internal (sf, ptr, size < 0 ? -1 : size, pstart);
78}
96aa2d94
RM
79
80void
2ca8b1ee
GM
81_IO_str_init_readonly (sf, ptr, size)
82 _IO_strfile *sf;
40a55d20
UD
83 const char *ptr;
84 int size;
96aa2d94 85{
40a54e4d 86 _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL);
2ca8b1ee 87 sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
96aa2d94
RM
88}
89
90int
40a55d20
UD
91_IO_str_overflow (fp, c)
92 _IO_FILE *fp;
93 int c;
96aa2d94
RM
94{
95 int flush_only = c == EOF;
8a523922 96 _IO_size_t pos;
96aa2d94
RM
97 if (fp->_flags & _IO_NO_WRITES)
98 return flush_only ? 0 : EOF;
96aa2d94
RM
99 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
100 {
96aa2d94 101 fp->_flags |= _IO_CURRENTLY_PUTTING;
8a523922
UD
102 fp->_IO_write_ptr = fp->_IO_read_ptr;
103 fp->_IO_read_ptr = fp->_IO_read_end;
96aa2d94 104 }
107b8a92 105 pos = fp->_IO_write_ptr - fp->_IO_write_base;
40a55d20 106 if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
96aa2d94
RM
107 {
108 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
8a523922 109 return EOF;
96aa2d94
RM
110 else
111 {
112 char *new_buf;
8a523922 113 char *old_buf = fp->_IO_buf_base;
107b8a92
UD
114 size_t old_blen = _IO_blen (fp);
115 _IO_size_t new_size = 2 * old_blen + 100;
116 if (new_size < old_blen)
117 return EOF;
96aa2d94 118 new_buf
40a55d20 119 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
96aa2d94
RM
120 if (new_buf == NULL)
121 {
122 /* __ferror(fp) = 1; */
123 return EOF;
124 }
d64b6ad0 125 if (old_buf)
96aa2d94 126 {
107b8a92 127 memcpy (new_buf, old_buf, old_blen);
d64b6ad0 128 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
96aa2d94
RM
129 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
130 fp->_IO_buf_base = NULL;
131 }
107b8a92
UD
132 memset (new_buf + old_blen, '\0', new_size - old_blen);
133
d18ea0c5 134 _IO_setb (fp, new_buf, new_buf + new_size, 1);
8a523922
UD
135 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
136 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
137 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
138 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
139
96aa2d94 140 fp->_IO_write_base = new_buf;
f21acc89 141 fp->_IO_write_end = fp->_IO_buf_end;
96aa2d94 142 }
96aa2d94
RM
143 }
144
96aa2d94
RM
145 if (!flush_only)
146 *fp->_IO_write_ptr++ = (unsigned char) c;
8a523922
UD
147 if (fp->_IO_write_ptr > fp->_IO_read_end)
148 fp->_IO_read_end = fp->_IO_write_ptr;
96aa2d94
RM
149 return c;
150}
d18ea0c5 151libc_hidden_def (_IO_str_overflow)
96aa2d94
RM
152
153int
40a55d20
UD
154_IO_str_underflow (fp)
155 _IO_FILE *fp;
96aa2d94 156{
8a523922
UD
157 if (fp->_IO_write_ptr > fp->_IO_read_end)
158 fp->_IO_read_end = fp->_IO_write_ptr;
96aa2d94
RM
159 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
160 {
161 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
8a523922 162 fp->_IO_read_ptr = fp->_IO_write_ptr;
96aa2d94
RM
163 fp->_IO_write_ptr = fp->_IO_write_end;
164 }
96aa2d94 165 if (fp->_IO_read_ptr < fp->_IO_read_end)
195d0dd4 166 return *((unsigned char *) fp->_IO_read_ptr);
96aa2d94 167 else
0923a2c8 168 return EOF;
96aa2d94 169}
d18ea0c5 170libc_hidden_def (_IO_str_underflow)
96aa2d94 171
8a523922
UD
172/* The size of the valid part of the buffer. */
173
96aa2d94 174_IO_ssize_t
40a55d20
UD
175_IO_str_count (fp)
176 _IO_FILE *fp;
96aa2d94 177{
2604afb1
UD
178 return ((fp->_IO_write_ptr > fp->_IO_read_end
179 ? fp->_IO_write_ptr : fp->_IO_read_end)
40a55d20 180 - fp->_IO_read_base);
a68b0d31 181}
96aa2d94 182
107b8a92
UD
183
184static int
185enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
186{
187 if ((_IO_ssize_t) offset <= _IO_blen (fp))
188 return 0;
189
190 _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base;
191
192 /* Try to enlarge the buffer. */
193 if (fp->_flags & _IO_USER_BUF)
194 /* User-provided buffer. */
195 return 1;
196
197 _IO_size_t newsize = offset + 100;
198 char *oldbuf = fp->_IO_buf_base;
199 char *newbuf
200 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
201 if (newbuf == NULL)
202 return 1;
203
204 if (oldbuf != NULL)
205 {
206 memcpy (newbuf, oldbuf, _IO_blen (fp));
207 (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
208 /* Make sure _IO_setb won't try to delete
209 _IO_buf_base. */
210 fp->_IO_buf_base = NULL;
211 }
212
d18ea0c5 213 _IO_setb (fp, newbuf, newbuf + newsize, 1);
107b8a92
UD
214
215 if (reading)
216 {
217 fp->_IO_write_base = newbuf + (fp->_IO_write_base - oldbuf);
218 fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
219 fp->_IO_write_end = newbuf + (fp->_IO_write_end - oldbuf);
220 fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
221
222 fp->_IO_read_base = newbuf;
223 fp->_IO_read_end = fp->_IO_buf_end;
224 }
225 else
226 {
227 fp->_IO_read_base = newbuf + (fp->_IO_read_base - oldbuf);
228 fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
229 fp->_IO_read_end = newbuf + (fp->_IO_read_end - oldbuf);
230 fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
231
232 fp->_IO_write_base = newbuf;
233 fp->_IO_write_end = fp->_IO_buf_end;
234 }
235
236 /* Clear the area between the last write position and th
237 new position. */
238 assert (offset >= oldend);
239 if (reading)
240 memset (fp->_IO_read_base + oldend, '\0', offset - oldend);
241 else
242 memset (fp->_IO_write_base + oldend, '\0', offset - oldend);
243
244 return 0;
245}
246
247
d64b6ad0 248_IO_off64_t
40a55d20
UD
249_IO_str_seekoff (fp, offset, dir, mode)
250 _IO_FILE *fp;
dfd2257a 251 _IO_off64_t offset;
40a55d20
UD
252 int dir;
253 int mode;
96aa2d94 254{
d64b6ad0 255 _IO_off64_t new_pos;
96aa2d94 256
dd7d45e8
UD
257 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
258 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
259
2eb45444 260 if (mode == 0)
96aa2d94 261 {
2eb45444
UD
262 /* Don't move any pointers. But there is no clear indication what
263 mode FP is in. Let's guess. */
264 if (fp->_IO_file_flags & _IO_NO_WRITES)
265 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
266 else
267 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
268 }
269 else
270 {
271 _IO_ssize_t cur_size = _IO_str_count(fp);
272 new_pos = EOF;
273
274 /* Move the get pointer, if requested. */
275 if (mode & _IOS_INPUT)
96aa2d94 276 {
2eb45444
UD
277 switch (dir)
278 {
279 case _IO_seek_end:
280 offset += cur_size;
281 break;
282 case _IO_seek_cur:
283 offset += fp->_IO_read_ptr - fp->_IO_read_base;
284 break;
285 default: /* case _IO_seek_set: */
286 break;
287 }
107b8a92
UD
288 if (offset < 0)
289 return EOF;
290 if ((_IO_ssize_t) offset > cur_size
291 && enlarge_userbuf (fp, offset, 1) != 0)
2eb45444
UD
292 return EOF;
293 fp->_IO_read_ptr = fp->_IO_read_base + offset;
294 fp->_IO_read_end = fp->_IO_read_base + cur_size;
295 new_pos = offset;
96aa2d94 296 }
96aa2d94 297
2eb45444
UD
298 /* Move the put pointer, if requested. */
299 if (mode & _IOS_OUTPUT)
96aa2d94 300 {
2eb45444
UD
301 switch (dir)
302 {
303 case _IO_seek_end:
304 offset += cur_size;
305 break;
306 case _IO_seek_cur:
307 offset += fp->_IO_write_ptr - fp->_IO_write_base;
308 break;
309 default: /* case _IO_seek_set: */
310 break;
311 }
107b8a92
UD
312 if (offset < 0)
313 return EOF;
314 if ((_IO_ssize_t) offset > cur_size
315 && enlarge_userbuf (fp, offset, 0) != 0)
2eb45444
UD
316 return EOF;
317 fp->_IO_write_ptr = fp->_IO_write_base + offset;
318 new_pos = offset;
96aa2d94 319 }
96aa2d94
RM
320 }
321 return new_pos;
322}
d18ea0c5 323libc_hidden_def (_IO_str_seekoff)
96aa2d94
RM
324
325int
40a55d20
UD
326_IO_str_pbackfail (fp, c)
327 _IO_FILE *fp;
328 int c;
96aa2d94
RM
329{
330 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
331 return EOF;
d18ea0c5 332 return _IO_default_pbackfail (fp, c);
96aa2d94 333}
d18ea0c5 334libc_hidden_def (_IO_str_pbackfail)
96aa2d94
RM
335
336void
40a55d20
UD
337_IO_str_finish (fp, dummy)
338 _IO_FILE *fp;
339 int dummy;
96aa2d94
RM
340{
341 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
40a55d20 342 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
96aa2d94
RM
343 fp->_IO_buf_base = NULL;
344
d18ea0c5 345 _IO_default_finish (fp, 0);
96aa2d94
RM
346}
347
b2637a22 348const struct _IO_jump_t _IO_str_jumps =
40a55d20 349{
96aa2d94
RM
350 JUMP_INIT_DUMMY,
351 JUMP_INIT(finish, _IO_str_finish),
d18ea0c5
AS
352 JUMP_INIT(overflow, _IO_str_overflow),
353 JUMP_INIT(underflow, _IO_str_underflow),
354 JUMP_INIT(uflow, _IO_default_uflow),
355 JUMP_INIT(pbackfail, _IO_str_pbackfail),
356 JUMP_INIT(xsputn, _IO_default_xsputn),
357 JUMP_INIT(xsgetn, _IO_default_xsgetn),
358 JUMP_INIT(seekoff, _IO_str_seekoff),
96aa2d94
RM
359 JUMP_INIT(seekpos, _IO_default_seekpos),
360 JUMP_INIT(setbuf, _IO_default_setbuf),
361 JUMP_INIT(sync, _IO_default_sync),
d18ea0c5 362 JUMP_INIT(doallocate, _IO_default_doallocate),
96aa2d94
RM
363 JUMP_INIT(read, _IO_default_read),
364 JUMP_INIT(write, _IO_default_write),
365 JUMP_INIT(seek, _IO_default_seek),
366 JUMP_INIT(close, _IO_default_close),
dfd2257a
UD
367 JUMP_INIT(stat, _IO_default_stat),
368 JUMP_INIT(showmanyc, _IO_default_showmanyc),
369 JUMP_INIT(imbue, _IO_default_imbue)
96aa2d94 370};