]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/genops.c
In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
[thirdparty/glibc.git] / libio / genops.c
CommitLineData
b168057a 1/* Copyright (C) 1993-2015 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
40a55d20 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.
40a55d20 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
RM
26
27/* Generic or default I/O operations. */
28
29#include "libioP.h"
96aa2d94 30#include <stdlib.h>
96aa2d94 31#include <string.h>
8d24de8b 32#include <stdbool.h>
e2c7e1de
RM
33#ifdef _LIBC
34#include <sched.h>
35#endif
96aa2d94 36
51e176c2 37#ifdef _IO_MTSAFE_IO
118bad87 38static _IO_lock_t list_all_lock = _IO_lock_initializer;
51e176c2 39#endif
118bad87 40
3afd9491
UD
41/* Used to signal modifications to the list of FILE decriptors. */
42static int _IO_list_all_stamp;
43
beafb752
UD
44
45static _IO_FILE *run_fp;
46
bea9b193 47#ifdef _IO_MTSAFE_IO
beafb752
UD
48static void
49flush_cleanup (void *not_used)
50{
51 if (run_fp != NULL)
52 _IO_funlockfile (run_fp);
53 _IO_lock_unlock (list_all_lock);
54}
bea9b193 55#endif
beafb752 56
96aa2d94 57void
40a55d20 58_IO_un_link (fp)
2ca8b1ee 59 struct _IO_FILE_plus *fp;
40a55d20 60{
2ca8b1ee 61 if (fp->file._flags & _IO_LINKED)
40a55d20 62 {
cedb4109 63 struct _IO_FILE **f;
d328b80b 64#ifdef _IO_MTSAFE_IO
beafb752 65 _IO_cleanup_region_start_noarg (flush_cleanup);
118bad87 66 _IO_lock_lock (list_all_lock);
beafb752
UD
67 run_fp = (_IO_FILE *) fp;
68 _IO_flockfile ((_IO_FILE *) fp);
51e176c2 69#endif
d18ea0c5 70 if (_IO_list_all == NULL)
cedb4109 71 ;
d18ea0c5 72 else if (fp == _IO_list_all)
40a55d20 73 {
d18ea0c5 74 _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
cedb4109
UD
75 ++_IO_list_all_stamp;
76 }
77 else
d18ea0c5 78 for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
cedb4109 79 if (*f == (_IO_FILE *) fp)
40a55d20 80 {
cedb4109 81 *f = fp->file._chain;
3afd9491 82 ++_IO_list_all_stamp;
40a55d20
UD
83 break;
84 }
beafb752 85 fp->file._flags &= ~_IO_LINKED;
51e176c2 86#ifdef _IO_MTSAFE_IO
beafb752
UD
87 _IO_funlockfile ((_IO_FILE *) fp);
88 run_fp = NULL;
118bad87 89 _IO_lock_unlock (list_all_lock);
beafb752 90 _IO_cleanup_region_end (0);
51e176c2 91#endif
96aa2d94 92 }
96aa2d94 93}
d18ea0c5 94libc_hidden_def (_IO_un_link)
96aa2d94
RM
95
96void
40a55d20 97_IO_link_in (fp)
2ca8b1ee 98 struct _IO_FILE_plus *fp;
96aa2d94 99{
beafb752
UD
100 if ((fp->file._flags & _IO_LINKED) == 0)
101 {
102 fp->file._flags |= _IO_LINKED;
51e176c2 103#ifdef _IO_MTSAFE_IO
beafb752
UD
104 _IO_cleanup_region_start_noarg (flush_cleanup);
105 _IO_lock_lock (list_all_lock);
106 run_fp = (_IO_FILE *) fp;
107 _IO_flockfile ((_IO_FILE *) fp);
51e176c2 108#endif
d18ea0c5
AS
109 fp->file._chain = (_IO_FILE *) _IO_list_all;
110 _IO_list_all = fp;
beafb752 111 ++_IO_list_all_stamp;
51e176c2 112#ifdef _IO_MTSAFE_IO
beafb752
UD
113 _IO_funlockfile ((_IO_FILE *) fp);
114 run_fp = NULL;
115 _IO_lock_unlock (list_all_lock);
116 _IO_cleanup_region_end (0);
51e176c2 117#endif
beafb752 118 }
96aa2d94 119}
d18ea0c5 120libc_hidden_def (_IO_link_in)
96aa2d94
RM
121
122/* Return minimum _pos markers
123 Assumes the current get area is the main get area. */
79937577 124_IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
96aa2d94 125
d64b6ad0 126_IO_ssize_t
05f732b3 127_IO_least_marker (fp, end_p)
40a55d20 128 _IO_FILE *fp;
05f732b3 129 char *end_p;
96aa2d94 130{
05f732b3 131 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
40a55d20 132 struct _IO_marker *mark;
96aa2d94
RM
133 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
134 if (mark->_pos < least_so_far)
135 least_so_far = mark->_pos;
136 return least_so_far;
137}
138
139/* Switch current get area from backup buffer to (start of) main get area. */
140
141void
40a55d20
UD
142_IO_switch_to_main_get_area (fp)
143 _IO_FILE *fp;
96aa2d94
RM
144{
145 char *tmp;
146 fp->_flags &= ~_IO_IN_BACKUP;
147 /* Swap _IO_read_end and _IO_save_end. */
40a55d20
UD
148 tmp = fp->_IO_read_end;
149 fp->_IO_read_end = fp->_IO_save_end;
150 fp->_IO_save_end= tmp;
96aa2d94 151 /* Swap _IO_read_base and _IO_save_base. */
40a55d20
UD
152 tmp = fp->_IO_read_base;
153 fp->_IO_read_base = fp->_IO_save_base;
154 fp->_IO_save_base = tmp;
05f732b3
UD
155 /* Set _IO_read_ptr. */
156 fp->_IO_read_ptr = fp->_IO_read_base;
96aa2d94
RM
157}
158
159/* Switch current get area from main get area to (end of) backup area. */
160
161void
40a55d20
UD
162_IO_switch_to_backup_area (fp)
163 _IO_FILE *fp;
96aa2d94
RM
164{
165 char *tmp;
166 fp->_flags |= _IO_IN_BACKUP;
167 /* Swap _IO_read_end and _IO_save_end. */
40a55d20
UD
168 tmp = fp->_IO_read_end;
169 fp->_IO_read_end = fp->_IO_save_end;
170 fp->_IO_save_end = tmp;
05f732b3 171 /* Swap _IO_read_base and _IO_save_base. */
40a55d20
UD
172 tmp = fp->_IO_read_base;
173 fp->_IO_read_base = fp->_IO_save_base;
174 fp->_IO_save_base = tmp;
05f732b3 175 /* Set _IO_read_ptr. */
96aa2d94
RM
176 fp->_IO_read_ptr = fp->_IO_read_end;
177}
178
179int
40a55d20
UD
180_IO_switch_to_get_mode (fp)
181 _IO_FILE *fp;
96aa2d94
RM
182{
183 if (fp->_IO_write_ptr > fp->_IO_write_base)
184 if (_IO_OVERFLOW (fp, EOF) == EOF)
185 return EOF;
40a55d20 186 if (_IO_in_backup (fp))
96aa2d94
RM
187 fp->_IO_read_base = fp->_IO_backup_base;
188 else
189 {
190 fp->_IO_read_base = fp->_IO_buf_base;
191 if (fp->_IO_write_ptr > fp->_IO_read_end)
192 fp->_IO_read_end = fp->_IO_write_ptr;
193 }
194 fp->_IO_read_ptr = fp->_IO_write_ptr;
195
196 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
197
198 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
199 return 0;
200}
d18ea0c5 201libc_hidden_def (_IO_switch_to_get_mode)
96aa2d94
RM
202
203void
40a55d20
UD
204_IO_free_backup_area (fp)
205 _IO_FILE *fp;
96aa2d94
RM
206{
207 if (_IO_in_backup (fp))
40a55d20 208 _IO_switch_to_main_get_area (fp); /* Just in case. */
96aa2d94
RM
209 free (fp->_IO_save_base);
210 fp->_IO_save_base = NULL;
211 fp->_IO_save_end = NULL;
212 fp->_IO_backup_base = NULL;
213}
d18ea0c5 214libc_hidden_def (_IO_free_backup_area)
96aa2d94
RM
215
216#if 0
217int
40a55d20
UD
218_IO_switch_to_put_mode (fp)
219 _IO_FILE *fp;
96aa2d94
RM
220{
221 fp->_IO_write_base = fp->_IO_read_ptr;
222 fp->_IO_write_ptr = fp->_IO_read_ptr;
223 /* Following is wrong if line- or un-buffered? */
40a55d20
UD
224 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
225 ? fp->_IO_read_end : fp->_IO_buf_end);
96aa2d94
RM
226
227 fp->_IO_read_ptr = fp->_IO_read_end;
228 fp->_IO_read_base = fp->_IO_read_end;
229
230 fp->_flags |= _IO_CURRENTLY_PUTTING;
231 return 0;
232}
233#endif
234
235int
40a55d20
UD
236__overflow (f, ch)
237 _IO_FILE *f;
238 int ch;
96aa2d94 239{
6f98fd7e
UD
240 /* This is a single-byte stream. */
241 if (f->_mode == 0)
242 _IO_fwide (f, -1);
96aa2d94
RM
243 return _IO_OVERFLOW (f, ch);
244}
37ba7d66 245libc_hidden_def (__overflow)
96aa2d94 246
79937577 247static int save_for_backup (_IO_FILE *fp, char *end_p)
dfd2257a
UD
248#ifdef _LIBC
249 internal_function
250#endif
251 ;
40a55d20 252
05f732b3 253static int
dfd2257a 254#ifdef _LIBC
05f732b3 255internal_function
dfd2257a 256#endif
05f732b3 257save_for_backup (fp, end_p)
40a55d20 258 _IO_FILE *fp;
05f732b3 259 char *end_p;
96aa2d94 260{
05f732b3
UD
261 /* Append [_IO_read_base..end_p] to backup area. */
262 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
96aa2d94 263 /* needed_size is how much space we need in the backup area. */
05f732b3
UD
264 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
265 /* FIXME: Dubious arithmetic if pointers are NULL */
266 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
267 _IO_size_t avail; /* Extra space available for future expansion. */
268 _IO_ssize_t delta;
96aa2d94
RM
269 struct _IO_marker *mark;
270 if (needed_size > current_Bsize)
271 {
272 char *new_buffer;
273 avail = 100;
40a55d20 274 new_buffer = (char *) malloc (avail + needed_size);
96aa2d94
RM
275 if (new_buffer == NULL)
276 return EOF; /* FIXME */
277 if (least_mark < 0)
278 {
86187531
UD
279#ifdef _LIBC
280 __mempcpy (__mempcpy (new_buffer + avail,
281 fp->_IO_save_end + least_mark,
282 -least_mark),
283 fp->_IO_read_base,
05f732b3 284 end_p - fp->_IO_read_base);
86187531 285#else
40a55d20
UD
286 memcpy (new_buffer + avail,
287 fp->_IO_save_end + least_mark,
288 -least_mark);
289 memcpy (new_buffer + avail - least_mark,
290 fp->_IO_read_base,
05f732b3 291 end_p - fp->_IO_read_base);
86187531 292#endif
96aa2d94
RM
293 }
294 else
40a55d20
UD
295 memcpy (new_buffer + avail,
296 fp->_IO_read_base + least_mark,
297 needed_size);
72e6cdfa 298 free (fp->_IO_save_base);
96aa2d94
RM
299 fp->_IO_save_base = new_buffer;
300 fp->_IO_save_end = new_buffer + avail + needed_size;
301 }
302 else
303 {
304 avail = current_Bsize - needed_size;
305 if (least_mark < 0)
306 {
40a55d20
UD
307 memmove (fp->_IO_save_base + avail,
308 fp->_IO_save_end + least_mark,
309 -least_mark);
310 memcpy (fp->_IO_save_base + avail - least_mark,
311 fp->_IO_read_base,
05f732b3 312 end_p - fp->_IO_read_base);
96aa2d94
RM
313 }
314 else if (needed_size > 0)
40a55d20
UD
315 memcpy (fp->_IO_save_base + avail,
316 fp->_IO_read_base + least_mark,
317 needed_size);
96aa2d94 318 }
96aa2d94
RM
319 fp->_IO_backup_base = fp->_IO_save_base + avail;
320 /* Adjust all the streammarkers. */
05f732b3 321 delta = end_p - fp->_IO_read_base;
96aa2d94
RM
322 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
323 mark->_pos -= delta;
324 return 0;
325}
326
327int
40a55d20
UD
328__underflow (fp)
329 _IO_FILE *fp;
96aa2d94 330{
319d719d 331#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
bbdef797 332 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
d64b6ad0 333 return EOF;
319d719d 334#endif
d64b6ad0 335
6f98fd7e
UD
336 if (fp->_mode == 0)
337 _IO_fwide (fp, -1);
40a55d20 338 if (_IO_in_put_mode (fp))
d18ea0c5 339 if (_IO_switch_to_get_mode (fp) == EOF)
40a55d20 340 return EOF;
96aa2d94 341 if (fp->_IO_read_ptr < fp->_IO_read_end)
40a55d20
UD
342 return *(unsigned char *) fp->_IO_read_ptr;
343 if (_IO_in_backup (fp))
96aa2d94 344 {
40a55d20 345 _IO_switch_to_main_get_area (fp);
96aa2d94 346 if (fp->_IO_read_ptr < fp->_IO_read_end)
31f7410f 347 return *(unsigned char *) fp->_IO_read_ptr;
96aa2d94 348 }
40a55d20 349 if (_IO_have_markers (fp))
96aa2d94 350 {
05f732b3 351 if (save_for_backup (fp, fp->_IO_read_end))
96aa2d94
RM
352 return EOF;
353 }
40a55d20 354 else if (_IO_have_backup (fp))
d18ea0c5 355 _IO_free_backup_area (fp);
96aa2d94
RM
356 return _IO_UNDERFLOW (fp);
357}
a20d8dbe 358libc_hidden_def (__underflow)
96aa2d94
RM
359
360int
40a55d20
UD
361__uflow (fp)
362 _IO_FILE *fp;
96aa2d94 363{
319d719d 364#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
bbdef797 365 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
d64b6ad0 366 return EOF;
319d719d 367#endif
d64b6ad0 368
6f98fd7e 369 if (fp->_mode == 0)
1e88bd0f 370 _IO_fwide (fp, -1);
40a55d20 371 if (_IO_in_put_mode (fp))
d18ea0c5 372 if (_IO_switch_to_get_mode (fp) == EOF)
40a55d20 373 return EOF;
96aa2d94 374 if (fp->_IO_read_ptr < fp->_IO_read_end)
40a55d20
UD
375 return *(unsigned char *) fp->_IO_read_ptr++;
376 if (_IO_in_backup (fp))
96aa2d94 377 {
40a55d20 378 _IO_switch_to_main_get_area (fp);
96aa2d94 379 if (fp->_IO_read_ptr < fp->_IO_read_end)
31f7410f 380 return *(unsigned char *) fp->_IO_read_ptr++;
96aa2d94 381 }
40a55d20 382 if (_IO_have_markers (fp))
96aa2d94 383 {
05f732b3 384 if (save_for_backup (fp, fp->_IO_read_end))
96aa2d94
RM
385 return EOF;
386 }
40a55d20 387 else if (_IO_have_backup (fp))
d18ea0c5 388 _IO_free_backup_area (fp);
96aa2d94
RM
389 return _IO_UFLOW (fp);
390}
3ba06713 391libc_hidden_def (__uflow)
96aa2d94
RM
392
393void
40a55d20
UD
394_IO_setb (f, b, eb, a)
395 _IO_FILE *f;
3ba06713 396 char *b;
40a55d20
UD
397 char *eb;
398 int a;
96aa2d94
RM
399{
400 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
40a55d20 401 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
96aa2d94
RM
402 f->_IO_buf_base = b;
403 f->_IO_buf_end = eb;
404 if (a)
405 f->_flags &= ~_IO_USER_BUF;
406 else
407 f->_flags |= _IO_USER_BUF;
408}
d18ea0c5 409libc_hidden_def (_IO_setb)
96aa2d94
RM
410
411void
40a55d20
UD
412_IO_doallocbuf (fp)
413 _IO_FILE *fp;
96aa2d94
RM
414{
415 if (fp->_IO_buf_base)
416 return;
655de5fd 417 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
96aa2d94
RM
418 if (_IO_DOALLOCATE (fp) != EOF)
419 return;
d18ea0c5 420 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
96aa2d94 421}
d18ea0c5 422libc_hidden_def (_IO_doallocbuf)
96aa2d94
RM
423
424int
40a55d20
UD
425_IO_default_underflow (fp)
426 _IO_FILE *fp;
96aa2d94
RM
427{
428 return EOF;
429}
430
431int
40a55d20
UD
432_IO_default_uflow (fp)
433 _IO_FILE *fp;
96aa2d94
RM
434{
435 int ch = _IO_UNDERFLOW (fp);
436 if (ch == EOF)
437 return EOF;
40a55d20 438 return *(unsigned char *) fp->_IO_read_ptr++;
96aa2d94 439}
d18ea0c5 440libc_hidden_def (_IO_default_uflow)
96aa2d94
RM
441
442_IO_size_t
40a55d20
UD
443_IO_default_xsputn (f, data, n)
444 _IO_FILE *f;
445 const void *data;
446 _IO_size_t n;
96aa2d94 447{
40a55d20
UD
448 const char *s = (char *) data;
449 _IO_size_t more = n;
96aa2d94
RM
450 if (more <= 0)
451 return 0;
452 for (;;)
453 {
40a55d20 454 /* Space available. */
f7803f51 455 if (f->_IO_write_ptr < f->_IO_write_end)
96aa2d94 456 {
f7803f51
UD
457 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
458 if (count > more)
96aa2d94
RM
459 count = more;
460 if (count > 20)
461 {
86187531
UD
462#ifdef _LIBC
463 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
464#else
40a55d20 465 memcpy (f->_IO_write_ptr, s, count);
96aa2d94 466 f->_IO_write_ptr += count;
86187531
UD
467#endif
468 s += count;
f22e1074 469 }
f7803f51 470 else if (count)
96aa2d94 471 {
40a55d20
UD
472 char *p = f->_IO_write_ptr;
473 _IO_ssize_t i;
474 for (i = count; --i >= 0; )
475 *p++ = *s++;
96aa2d94 476 f->_IO_write_ptr = p;
f22e1074 477 }
96aa2d94 478 more -= count;
f22e1074 479 }
9202ffe3 480 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
96aa2d94
RM
481 break;
482 more--;
483 }
484 return n - more;
485}
d18ea0c5 486libc_hidden_def (_IO_default_xsputn)
96aa2d94
RM
487
488_IO_size_t
40a55d20
UD
489_IO_sgetn (fp, data, n)
490 _IO_FILE *fp;
491 void *data;
492 _IO_size_t n;
96aa2d94
RM
493{
494 /* FIXME handle putback buffer here! */
495 return _IO_XSGETN (fp, data, n);
496}
d18ea0c5 497libc_hidden_def (_IO_sgetn)
96aa2d94
RM
498
499_IO_size_t
40a55d20
UD
500_IO_default_xsgetn (fp, data, n)
501 _IO_FILE *fp;
502 void *data;
503 _IO_size_t n;
96aa2d94 504{
40a55d20
UD
505 _IO_size_t more = n;
506 char *s = (char*) data;
96aa2d94
RM
507 for (;;)
508 {
40a55d20 509 /* Data available. */
f7803f51 510 if (fp->_IO_read_ptr < fp->_IO_read_end)
96aa2d94 511 {
f7803f51
UD
512 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
513 if (count > more)
96aa2d94
RM
514 count = more;
515 if (count > 20)
516 {
86187531
UD
517#ifdef _LIBC
518 s = __mempcpy (s, fp->_IO_read_ptr, count);
519#else
40a55d20 520 memcpy (s, fp->_IO_read_ptr, count);
96aa2d94 521 s += count;
86187531 522#endif
96aa2d94
RM
523 fp->_IO_read_ptr += count;
524 }
f7803f51 525 else if (count)
96aa2d94 526 {
40a55d20
UD
527 char *p = fp->_IO_read_ptr;
528 int i = (int) count;
529 while (--i >= 0)
530 *s++ = *p++;
96aa2d94 531 fp->_IO_read_ptr = p;
f22e1074
UD
532 }
533 more -= count;
534 }
40a55d20 535 if (more == 0 || __underflow (fp) == EOF)
96aa2d94
RM
536 break;
537 }
538 return n - more;
539}
d18ea0c5 540libc_hidden_def (_IO_default_xsgetn)
96aa2d94 541
40a55d20
UD
542#if 0
543/* Seems not to be needed. --drepper */
96aa2d94 544int
40a55d20
UD
545_IO_sync (fp)
546 _IO_FILE *fp;
96aa2d94
RM
547{
548 return 0;
549}
40a55d20 550#endif
96aa2d94 551
40a55d20
UD
552_IO_FILE *
553_IO_default_setbuf (fp, p, len)
554 _IO_FILE *fp;
555 char *p;
556 _IO_ssize_t len;
96aa2d94
RM
557{
558 if (_IO_SYNC (fp) == EOF)
559 return NULL;
560 if (p == NULL || len == 0)
561 {
562 fp->_flags |= _IO_UNBUFFERED;
d18ea0c5 563 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
96aa2d94
RM
564 }
565 else
566 {
567 fp->_flags &= ~_IO_UNBUFFERED;
d18ea0c5 568 _IO_setb (fp, p, p+len, 0);
96aa2d94
RM
569 }
570 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
571 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
572 return fp;
573}
574
d64b6ad0 575_IO_off64_t
40a55d20
UD
576_IO_default_seekpos (fp, pos, mode)
577 _IO_FILE *fp;
d64b6ad0 578 _IO_off64_t pos;
40a55d20 579 int mode;
96aa2d94 580{
d64b6ad0 581 return _IO_SEEKOFF (fp, pos, 0, mode);
96aa2d94
RM
582}
583
584int
40a55d20
UD
585_IO_default_doallocate (fp)
586 _IO_FILE *fp;
96aa2d94 587{
f8b87ef0
UD
588 char *buf;
589
40a55d20 590 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
d18ea0c5 591 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
96aa2d94
RM
592 return 1;
593}
d18ea0c5 594libc_hidden_def (_IO_default_doallocate)
96aa2d94
RM
595
596void
40a55d20
UD
597_IO_init (fp, flags)
598 _IO_FILE *fp;
599 int flags;
d64b6ad0
UD
600{
601 _IO_no_init (fp, flags, -1, NULL, NULL);
602}
d18ea0c5 603libc_hidden_def (_IO_init)
d64b6ad0
UD
604
605void
14a2bd4b 606_IO_old_init (fp, flags)
d64b6ad0
UD
607 _IO_FILE *fp;
608 int flags;
96aa2d94
RM
609{
610 fp->_flags = _IO_MAGIC|flags;
dd0ee2e1 611 fp->_flags2 = 0;
96aa2d94
RM
612 fp->_IO_buf_base = NULL;
613 fp->_IO_buf_end = NULL;
614 fp->_IO_read_base = NULL;
615 fp->_IO_read_ptr = NULL;
616 fp->_IO_read_end = NULL;
617 fp->_IO_write_base = NULL;
618 fp->_IO_write_ptr = NULL;
619 fp->_IO_write_end = NULL;
620 fp->_chain = NULL; /* Not necessary. */
621
622 fp->_IO_save_base = NULL;
623 fp->_IO_backup_base = NULL;
624 fp->_IO_save_end = NULL;
625 fp->_markers = NULL;
626 fp->_cur_column = 0;
c15cf13a 627#if _IO_JUMPS_OFFSET
bd355af0
UD
628 fp->_vtable_offset = 0;
629#endif
7c713e28 630#ifdef _IO_MTSAFE_IO
c020d48c
UD
631 if (fp->_lock != NULL)
632 _IO_lock_init (*fp->_lock);
7c713e28 633#endif
14a2bd4b
UD
634}
635
636void
637_IO_no_init (fp, flags, orientation, wd, jmp)
638 _IO_FILE *fp;
639 int flags;
640 int orientation;
641 struct _IO_wide_data *wd;
b2637a22 642 const struct _IO_jump_t *jmp;
14a2bd4b
UD
643{
644 _IO_old_init (fp, flags);
d64b6ad0 645 fp->_mode = orientation;
319d719d 646#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
d64b6ad0
UD
647 if (orientation >= 0)
648 {
649 fp->_wide_data = wd;
650 fp->_wide_data->_IO_buf_base = NULL;
651 fp->_wide_data->_IO_buf_end = NULL;
652 fp->_wide_data->_IO_read_base = NULL;
653 fp->_wide_data->_IO_read_ptr = NULL;
654 fp->_wide_data->_IO_read_end = NULL;
655 fp->_wide_data->_IO_write_base = NULL;
656 fp->_wide_data->_IO_write_ptr = NULL;
657 fp->_wide_data->_IO_write_end = NULL;
658 fp->_wide_data->_IO_save_base = NULL;
659 fp->_wide_data->_IO_backup_base = NULL;
660 fp->_wide_data->_IO_save_end = NULL;
661
662 fp->_wide_data->_wide_vtable = jmp;
663 }
bae143d2
OB
664 else
665 /* Cause predictable crash when a wide function is called on a byte
666 stream. */
667 fp->_wide_data = (struct _IO_wide_data *) -1L;
319d719d 668#endif
78762723 669 fp->_freeres_list = NULL;
96aa2d94
RM
670}
671
672int
40a55d20
UD
673_IO_default_sync (fp)
674 _IO_FILE *fp;
96aa2d94
RM
675{
676 return 0;
677}
678
679/* The way the C++ classes are mapped into the C functions in the
680 current implementation, this function can get called twice! */
681
682void
40a55d20
UD
683_IO_default_finish (fp, dummy)
684 _IO_FILE *fp;
685 int dummy;
96aa2d94
RM
686{
687 struct _IO_marker *mark;
688 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
689 {
40a55d20 690 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
96aa2d94
RM
691 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
692 }
693
694 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
695 mark->_sbuf = NULL;
696
697 if (fp->_IO_save_base)
698 {
699 free (fp->_IO_save_base);
700 fp->_IO_save_base = NULL;
701 }
702
d18ea0c5 703 _IO_un_link ((struct _IO_FILE_plus *) fp);
993a5d66 704
7c713e28 705#ifdef _IO_MTSAFE_IO
c020d48c
UD
706 if (fp->_lock != NULL)
707 _IO_lock_fini (*fp->_lock);
7c713e28 708#endif
96aa2d94 709}
d18ea0c5 710libc_hidden_def (_IO_default_finish)
96aa2d94 711
d64b6ad0 712_IO_off64_t
40a55d20
UD
713_IO_default_seekoff (fp, offset, dir, mode)
714 _IO_FILE *fp;
dfd2257a 715 _IO_off64_t offset;
40a55d20
UD
716 int dir;
717 int mode;
96aa2d94 718{
c020d48c 719 return _IO_pos_BAD;
96aa2d94
RM
720}
721
722int
40a55d20
UD
723_IO_sputbackc (fp, c)
724 _IO_FILE *fp;
725 int c;
96aa2d94 726{
19bc17a9 727 int result;
adfa2078 728
96aa2d94
RM
729 if (fp->_IO_read_ptr > fp->_IO_read_base
730 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
731 {
732 fp->_IO_read_ptr--;
40a55d20 733 result = (unsigned char) c;
96aa2d94 734 }
19bc17a9
RM
735 else
736 result = _IO_PBACKFAIL (fp, c);
737
738 if (result != EOF)
739 fp->_flags &= ~_IO_EOF_SEEN;
740
741 return result;
96aa2d94 742}
d18ea0c5 743libc_hidden_def (_IO_sputbackc)
96aa2d94
RM
744
745int
40a55d20
UD
746_IO_sungetc (fp)
747 _IO_FILE *fp;
96aa2d94 748{
19bc17a9 749 int result;
adfa2078 750
96aa2d94
RM
751 if (fp->_IO_read_ptr > fp->_IO_read_base)
752 {
753 fp->_IO_read_ptr--;
40a55d20 754 result = (unsigned char) *fp->_IO_read_ptr;
96aa2d94
RM
755 }
756 else
19bc17a9
RM
757 result = _IO_PBACKFAIL (fp, EOF);
758
759 if (result != EOF)
760 fp->_flags &= ~_IO_EOF_SEEN;
761
762 return result;
96aa2d94
RM
763}
764
765#if 0 /* Work in progress */
40a55d20
UD
766/* Seems not to be needed. */
767#if 0
96aa2d94 768void
40a55d20
UD
769_IO_set_column (fp, c)
770 _IO_FILE *fp;
771 int c;
96aa2d94
RM
772{
773 if (c == -1)
774 fp->_column = -1;
775 else
776 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
777}
778#else
779int
40a55d20
UD
780_IO_set_column (fp, i)
781 _IO_FILE *fp;
782 int i;
96aa2d94 783{
40a55d20 784 fp->_cur_column = i + 1;
96aa2d94
RM
785 return 0;
786}
787#endif
40a55d20 788#endif
96aa2d94
RM
789
790
791unsigned
40a55d20
UD
792_IO_adjust_column (start, line, count)
793 unsigned start;
794 const char *line;
795 int count;
96aa2d94 796{
40a55d20 797 const char *ptr = line + count;
96aa2d94
RM
798 while (ptr > line)
799 if (*--ptr == '\n')
800 return line + count - ptr - 1;
801 return start + count;
802}
d18ea0c5 803libc_hidden_def (_IO_adjust_column)
96aa2d94 804
40a55d20
UD
805#if 0
806/* Seems not to be needed. --drepper */
96aa2d94 807int
40a55d20
UD
808_IO_get_column (fp)
809 _IO_FILE *fp;
96aa2d94 810{
adfa2078 811 if (fp->_cur_column)
40a55d20 812 return _IO_adjust_column (fp->_cur_column - 1,
96aa2d94
RM
813 fp->_IO_write_base,
814 fp->_IO_write_ptr - fp->_IO_write_base);
815 return -1;
816}
40a55d20 817#endif
96aa2d94 818
3afd9491 819
96aa2d94 820int
c6baa867 821_IO_flush_all_lockp (int do_lock)
96aa2d94
RM
822{
823 int result = 0;
73c115ed 824 struct _IO_FILE *fp;
3afd9491
UD
825 int last_stamp;
826
827#ifdef _IO_MTSAFE_IO
341dd673 828 __libc_cleanup_region_start (do_lock, flush_cleanup, NULL);
c6baa867
UD
829 if (do_lock)
830 _IO_lock_lock (list_all_lock);
3afd9491
UD
831#endif
832
833 last_stamp = _IO_list_all_stamp;
d18ea0c5 834 fp = (_IO_FILE *) _IO_list_all;
3afd9491
UD
835 while (fp != NULL)
836 {
837 run_fp = fp;
c6baa867
UD
838 if (do_lock)
839 _IO_flockfile (fp);
3afd9491
UD
840
841 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
319d719d 842#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
bbdef797 843 || (_IO_vtable_offset (fp) == 0
3afd9491
UD
844 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
845 > fp->_wide_data->_IO_write_base))
319d719d 846#endif
3afd9491
UD
847 )
848 && _IO_OVERFLOW (fp, EOF) == EOF)
849 result = EOF;
850
c6baa867
UD
851 if (do_lock)
852 _IO_funlockfile (fp);
3afd9491
UD
853 run_fp = NULL;
854
855 if (last_stamp != _IO_list_all_stamp)
856 {
857 /* Something was added to the list. Start all over again. */
d18ea0c5 858 fp = (_IO_FILE *) _IO_list_all;
3afd9491
UD
859 last_stamp = _IO_list_all_stamp;
860 }
861 else
862 fp = fp->_chain;
863 }
864
865#ifdef _IO_MTSAFE_IO
c6baa867
UD
866 if (do_lock)
867 _IO_lock_unlock (list_all_lock);
7583a88d 868 __libc_cleanup_region_end (0);
3afd9491
UD
869#endif
870
96aa2d94
RM
871 return result;
872}
873
c6baa867
UD
874
875int
60d2f8f3 876_IO_flush_all (void)
c6baa867
UD
877{
878 /* We want locking. */
879 return _IO_flush_all_lockp (1);
880}
d18ea0c5 881libc_hidden_def (_IO_flush_all)
c6baa867 882
96aa2d94 883void
60d2f8f3 884_IO_flush_all_linebuffered (void)
96aa2d94 885{
73c115ed 886 struct _IO_FILE *fp;
3afd9491
UD
887 int last_stamp;
888
889#ifdef _IO_MTSAFE_IO
890 _IO_cleanup_region_start_noarg (flush_cleanup);
891 _IO_lock_lock (list_all_lock);
892#endif
893
894 last_stamp = _IO_list_all_stamp;
d18ea0c5 895 fp = (_IO_FILE *) _IO_list_all;
3afd9491
UD
896 while (fp != NULL)
897 {
898 run_fp = fp;
899 _IO_flockfile (fp);
900
901 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
902 _IO_OVERFLOW (fp, EOF);
903
904 _IO_funlockfile (fp);
905 run_fp = NULL;
906
907 if (last_stamp != _IO_list_all_stamp)
908 {
909 /* Something was added to the list. Start all over again. */
d18ea0c5 910 fp = (_IO_FILE *) _IO_list_all;
3afd9491
UD
911 last_stamp = _IO_list_all_stamp;
912 }
913 else
914 fp = fp->_chain;
915 }
916
917#ifdef _IO_MTSAFE_IO
918 _IO_lock_unlock (list_all_lock);
919 _IO_cleanup_region_end (0);
920#endif
96aa2d94 921}
d18ea0c5 922libc_hidden_def (_IO_flush_all_linebuffered)
a91d3cd3
UD
923#ifdef _LIBC
924weak_alias (_IO_flush_all_linebuffered, _flushlbf)
925#endif
96aa2d94 926
78762723
UD
927
928/* The following is a bit tricky. In general, we want to unbuffer the
929 streams so that all output which follows is seen. If we are not
930 looking for memory leaks it does not make much sense to free the
931 actual buffer because this will happen anyway once the program
932 terminated. If we do want to look for memory leaks we have to free
933 the buffers. Whether something is freed is determined by the
934 function sin the libc_freeres section. Those are called as part of
935 the atexit routine, just like _IO_cleanup. The problem is we do
936 not know whether the freeres code is called first or _IO_cleanup.
937 if the former is the case, we set the DEALLOC_BUFFER variable to
18d26750
PP
938 true and _IO_unbuffer_all will take care of the rest. If
939 _IO_unbuffer_all is called first we add the streams to a list
78762723 940 which the freeres function later can walk through. */
18d26750 941static void _IO_unbuffer_all (void);
40a55d20 942
78762723
UD
943static bool dealloc_buffers;
944static _IO_FILE *freeres_list;
945
40a55d20 946static void
18d26750 947_IO_unbuffer_all (void)
96aa2d94 948{
73c115ed 949 struct _IO_FILE *fp;
d18ea0c5 950 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
6906cea4
UD
951 {
952 if (! (fp->_flags & _IO_UNBUFFERED)
6906cea4
UD
953 /* Iff stream is un-orientated, it wasn't used. */
954 && fp->_mode != 0)
78762723 955 {
b2e1c562 956#ifdef _IO_MTSAFE_IO
af047cff
UD
957 int cnt;
958#define MAXTRIES 2
959 for (cnt = 0; cnt < MAXTRIES; ++cnt)
f22e1074 960 if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
af047cff
UD
961 break;
962 else
963 /* Give the other thread time to finish up its use of the
964 stream. */
965 __sched_yield ();
b2e1c562 966#endif
af047cff 967
78762723
UD
968 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
969 {
970 fp->_flags |= _IO_USER_BUF;
971
972 fp->_freeres_list = freeres_list;
973 freeres_list = fp;
974 fp->_freeres_buf = fp->_IO_buf_base;
975 fp->_freeres_size = _IO_blen (fp);
976 }
977
978 _IO_SETBUF (fp, NULL, 0);
af047cff 979
a601b74d
PP
980 if (fp->_mode > 0)
981 _IO_wsetb (fp, NULL, NULL, 0);
982
b2e1c562 983#ifdef _IO_MTSAFE_IO
f22e1074 984 if (cnt < MAXTRIES && fp->_lock != NULL)
af047cff 985 _IO_lock_unlock (*fp->_lock);
b2e1c562 986#endif
78762723 987 }
6906cea4
UD
988
989 /* Make sure that never again the wide char functions can be
990 used. */
991 fp->_mode = -1;
992 }
96aa2d94
RM
993}
994
78762723
UD
995
996libc_freeres_fn (buffer_free)
997{
998 dealloc_buffers = true;
999
1000 while (freeres_list != NULL)
1001 {
1002 FREE_BUF (freeres_list->_freeres_buf, freeres_list->_freeres_size);
1003
1004 freeres_list = freeres_list->_freeres_list;
1005 }
1006}
1007
1008
310b3460 1009int
60d2f8f3 1010_IO_cleanup (void)
96aa2d94 1011{
64f01020 1012 /* We do *not* want locking. Some threads might use streams but
78762723 1013 that is their problem, we flush them underneath them. */
64f01020 1014 int result = _IO_flush_all_lockp (0);
96aa2d94
RM
1015
1016 /* We currently don't have a reliable mechanism for making sure that
1017 C++ static destructors are executed in the correct order.
6d52618b 1018 So it is possible that other static destructors might want to
96aa2d94
RM
1019 write to cout - and they're supposed to be able to do so.
1020
adfa2078 1021 The following will make the standard streambufs be unbuffered,
96aa2d94 1022 which forces any output from late destructors to be written out. */
18d26750 1023 _IO_unbuffer_all ();
310b3460
UD
1024
1025 return result;
96aa2d94
RM
1026}
1027
f2ea0f5b 1028
96aa2d94 1029void
40a55d20
UD
1030_IO_init_marker (marker, fp)
1031 struct _IO_marker *marker;
1032 _IO_FILE *fp;
96aa2d94
RM
1033{
1034 marker->_sbuf = fp;
40a55d20 1035 if (_IO_in_put_mode (fp))
d18ea0c5 1036 _IO_switch_to_get_mode (fp);
40a55d20 1037 if (_IO_in_backup (fp))
96aa2d94
RM
1038 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
1039 else
1040 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
adfa2078 1041
96aa2d94
RM
1042 /* Should perhaps sort the chain? */
1043 marker->_next = fp->_markers;
1044 fp->_markers = marker;
1045}
1046
1047void
40a55d20
UD
1048_IO_remove_marker (marker)
1049 struct _IO_marker *marker;
96aa2d94
RM
1050{
1051 /* Unlink from sb's chain. */
40a55d20 1052 struct _IO_marker **ptr = &marker->_sbuf->_markers;
96aa2d94
RM
1053 for (; ; ptr = &(*ptr)->_next)
1054 {
1055 if (*ptr == NULL)
1056 break;
1057 else if (*ptr == marker)
1058 {
1059 *ptr = marker->_next;
1060 return;
1061 }
1062 }
1063#if 0
1064 if _sbuf has a backup area that is no longer needed, should we delete
1065 it now, or wait until the next underflow?
1066#endif
1067}
1068
1069#define BAD_DELTA EOF
1070
1071int
40a55d20
UD
1072_IO_marker_difference (mark1, mark2)
1073 struct _IO_marker *mark1;
1074 struct _IO_marker *mark2;
96aa2d94
RM
1075{
1076 return mark1->_pos - mark2->_pos;
1077}
1078
6d52618b 1079/* Return difference between MARK and current position of MARK's stream. */
96aa2d94 1080int
40a55d20
UD
1081_IO_marker_delta (mark)
1082 struct _IO_marker *mark;
96aa2d94
RM
1083{
1084 int cur_pos;
1085 if (mark->_sbuf == NULL)
1086 return BAD_DELTA;
40a55d20 1087 if (_IO_in_backup (mark->_sbuf))
96aa2d94
RM
1088 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1089 else
1090 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1091 return mark->_pos - cur_pos;
1092}
1093
1094int
40a55d20
UD
1095_IO_seekmark (fp, mark, delta)
1096 _IO_FILE *fp;
1097 struct _IO_marker *mark;
1098 int delta;
96aa2d94
RM
1099{
1100 if (mark->_sbuf != fp)
1101 return EOF;
1102 if (mark->_pos >= 0)
1103 {
40a55d20
UD
1104 if (_IO_in_backup (fp))
1105 _IO_switch_to_main_get_area (fp);
96aa2d94
RM
1106 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1107 }
1108 else
1109 {
40a55d20 1110 if (!_IO_in_backup (fp))
05f732b3 1111 _IO_switch_to_backup_area (fp);
96aa2d94
RM
1112 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1113 }
1114 return 0;
1115}
1116
1117void
40a55d20
UD
1118_IO_unsave_markers (fp)
1119 _IO_FILE *fp;
96aa2d94 1120{
40a55d20 1121 struct _IO_marker *mark = fp->_markers;
96aa2d94
RM
1122 if (mark)
1123 {
1124#ifdef TODO
40a55d20 1125 streampos offset = seekoff (0, ios::cur, ios::in);
96aa2d94
RM
1126 if (offset != EOF)
1127 {
40a55d20 1128 offset += eGptr () - Gbase ();
96aa2d94 1129 for ( ; mark != NULL; mark = mark->_next)
40a55d20 1130 mark->set_streampos (mark->_pos + offset);
96aa2d94
RM
1131 }
1132 else
1133 {
1134 for ( ; mark != NULL; mark = mark->_next)
40a55d20 1135 mark->set_streampos (EOF);
96aa2d94
RM
1136 }
1137#endif
1138 fp->_markers = 0;
1139 }
1140
40a55d20 1141 if (_IO_have_backup (fp))
d18ea0c5 1142 _IO_free_backup_area (fp);
96aa2d94 1143}
d18ea0c5 1144libc_hidden_def (_IO_unsave_markers)
96aa2d94 1145
40a55d20
UD
1146#if 0
1147/* Seems not to be needed. --drepper */
96aa2d94 1148int
40a55d20
UD
1149_IO_nobackup_pbackfail (fp, c)
1150 _IO_FILE *fp;
1151 int c;
96aa2d94
RM
1152{
1153 if (fp->_IO_read_ptr > fp->_IO_read_base)
1154 fp->_IO_read_ptr--;
1155 if (c != EOF && *fp->_IO_read_ptr != c)
1156 *fp->_IO_read_ptr = c;
40a55d20 1157 return (unsigned char) c;
96aa2d94 1158}
40a55d20 1159#endif
96aa2d94
RM
1160
1161int
40a55d20
UD
1162_IO_default_pbackfail (fp, c)
1163 _IO_FILE *fp;
1164 int c;
96aa2d94 1165{
00bc5db0 1166 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
c94a8080 1167 && (unsigned char) fp->_IO_read_ptr[-1] == c)
00bc5db0
UD
1168 --fp->_IO_read_ptr;
1169 else
40a55d20
UD
1170 {
1171 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
05f732b3 1172 if (!_IO_in_backup (fp))
40a55d20 1173 {
05f732b3
UD
1174 /* We need to keep the invariant that the main get area
1175 logically follows the backup area. */
1176 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1177 {
1178 if (save_for_backup (fp, fp->_IO_read_ptr))
1179 return EOF;
1180 }
1181 else if (!_IO_have_backup (fp))
1182 {
1183 /* No backup buffer: allocate one. */
1184 /* Use nshort buffer, if unused? (probably not) FIXME */
1185 int backup_size = 128;
1186 char *bbuf = (char *) malloc (backup_size);
1187 if (bbuf == NULL)
1188 return EOF;
1189 fp->_IO_save_base = bbuf;
1190 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1191 fp->_IO_backup_base = fp->_IO_save_end;
1192 }
1193 fp->_IO_read_base = fp->_IO_read_ptr;
40a55d20
UD
1194 _IO_switch_to_backup_area (fp);
1195 }
1196 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1197 {
1198 /* Increase size of existing backup buffer. */
1199 _IO_size_t new_size;
1200 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1201 char *new_buf;
1202 new_size = 2 * old_size;
1203 new_buf = (char *) malloc (new_size);
1204 if (new_buf == NULL)
1205 return EOF;
1206 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1207 old_size);
1208 free (fp->_IO_read_base);
1209 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1210 new_buf + new_size);
1211 fp->_IO_backup_base = fp->_IO_read_ptr;
1212 }
00bc5db0
UD
1213
1214 *--fp->_IO_read_ptr = c;
40a55d20 1215 }
00bc5db0 1216 return (unsigned char) c;
96aa2d94 1217}
d18ea0c5 1218libc_hidden_def (_IO_default_pbackfail)
96aa2d94 1219
d64b6ad0 1220_IO_off64_t
40a55d20
UD
1221_IO_default_seek (fp, offset, dir)
1222 _IO_FILE *fp;
dfd2257a 1223 _IO_off64_t offset;
40a55d20 1224 int dir;
96aa2d94
RM
1225{
1226 return _IO_pos_BAD;
1227}
1228
1229int
40a55d20
UD
1230_IO_default_stat (fp, st)
1231 _IO_FILE *fp;
1232 void* st;
96aa2d94
RM
1233{
1234 return EOF;
1235}
1236
1237_IO_ssize_t
40a55d20
UD
1238_IO_default_read (fp, data, n)
1239 _IO_FILE* fp;
1240 void *data;
1241 _IO_ssize_t n;
96aa2d94
RM
1242{
1243 return -1;
1244}
1245
1246_IO_ssize_t
40a55d20
UD
1247_IO_default_write (fp, data, n)
1248 _IO_FILE *fp;
1249 const void *data;
1250 _IO_ssize_t n;
96aa2d94
RM
1251{
1252 return 0;
1253}
1254
319d719d 1255int
dfd2257a
UD
1256_IO_default_showmanyc (fp)
1257 _IO_FILE *fp;
1258{
1259 return -1;
1260}
1261
1262void
1263_IO_default_imbue (fp, locale)
1264 _IO_FILE *fp;
1265 void *locale;
1266{
1267}
1268
3fc9ca4e 1269_IO_ITER
60d2f8f3 1270_IO_iter_begin (void)
3fc9ca4e 1271{
d18ea0c5 1272 return (_IO_ITER) _IO_list_all;
3fc9ca4e 1273}
1d2b6e0c 1274libc_hidden_def (_IO_iter_begin)
3fc9ca4e
UD
1275
1276_IO_ITER
60d2f8f3 1277_IO_iter_end (void)
3fc9ca4e 1278{
2ca8b1ee 1279 return NULL;
3fc9ca4e 1280}
1d2b6e0c 1281libc_hidden_def (_IO_iter_end)
3fc9ca4e
UD
1282
1283_IO_ITER
1284_IO_iter_next(iter)
1285 _IO_ITER iter;
1286{
73c115ed 1287 return iter->_chain;
3fc9ca4e 1288}
1d2b6e0c 1289libc_hidden_def (_IO_iter_next)
3fc9ca4e
UD
1290
1291_IO_FILE *
1292_IO_iter_file(iter)
1293 _IO_ITER iter;
1294{
73c115ed 1295 return iter;
3fc9ca4e 1296}
1d2b6e0c 1297libc_hidden_def (_IO_iter_file)
3fc9ca4e
UD
1298
1299void
60d2f8f3 1300_IO_list_lock (void)
3fc9ca4e 1301{
92cfdd8a 1302#ifdef _IO_MTSAFE_IO
3fc9ca4e 1303 _IO_lock_lock (list_all_lock);
92cfdd8a 1304#endif
3fc9ca4e 1305}
245eab02 1306libc_hidden_def (_IO_list_lock)
3fc9ca4e
UD
1307
1308void
60d2f8f3 1309_IO_list_unlock (void)
3fc9ca4e 1310{
92cfdd8a
AJ
1311#ifdef _IO_MTSAFE_IO
1312 _IO_lock_unlock (list_all_lock);
1313#endif
3fc9ca4e 1314}
245eab02 1315libc_hidden_def (_IO_list_unlock)
3fc9ca4e
UD
1316
1317void
60d2f8f3 1318_IO_list_resetlock (void)
3fc9ca4e 1319{
92cfdd8a 1320#ifdef _IO_MTSAFE_IO
3fc9ca4e 1321 _IO_lock_init (list_all_lock);
92cfdd8a 1322#endif
3fc9ca4e 1323}
245eab02 1324libc_hidden_def (_IO_list_resetlock)
3fc9ca4e 1325
96aa2d94
RM
1326
1327#ifdef TODO
1328#if defined(linux)
1329#define IO_CLEANUP ;
1330#endif
1331
1332#ifdef IO_CLEANUP
1333 IO_CLEANUP
1334#else
1335struct __io_defs {
1336 __io_defs() { }
40a55d20 1337 ~__io_defs() { _IO_cleanup (); }
adfa2078 1338};
96aa2d94
RM
1339__io_defs io_defs__;
1340#endif
1341
1342#endif /* TODO */
adfa2078 1343
f65fd747 1344#ifdef text_set_element
f5bf21a7 1345text_set_element(__libc_atexit, _IO_cleanup);
f65fd747 1346#endif