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