1/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>.
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. */
26
27/* Generic or default I/O operations. */
28
29#include "libioP.h"
30#include <stdlib.h>
31#include <string.h>
32#include <stdbool.h>
33#include <sched.h>
34
35#ifdef _IO_MTSAFE_IO
36static _IO_lock_t list_all_lock = _IO_lock_initializer;
37#endif
38
39static _IO_FILE *run_fp;
40
41#ifdef _IO_MTSAFE_IO
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}
49#endif
50
51void
52_IO_un_link (struct _IO_FILE_plus *fp)
53{
54 if (fp->file._flags & _IO_LINKED)
55 {
56 struct _IO_FILE **f;
57#ifdef _IO_MTSAFE_IO
58 _IO_cleanup_region_start_noarg (flush_cleanup);
59 _IO_lock_lock (list_all_lock);
60 run_fp = (_IO_FILE *) fp;
61 _IO_flockfile ((_IO_FILE *) fp);
62#endif
63 if (_IO_list_all == NULL)
64 ;
65 else if (fp == _IO_list_all)
66 _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
67 else
68 for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
69 if (*f == (_IO_FILE *) fp)
70 {
71 *f = fp->file._chain;
72 break;
73 }
74 fp->file._flags &= ~_IO_LINKED;
75#ifdef _IO_MTSAFE_IO
76 _IO_funlockfile ((_IO_FILE *) fp);
77 run_fp = NULL;
78 _IO_lock_unlock (list_all_lock);
79 _IO_cleanup_region_end (0);
80#endif
81 }
82}
83libc_hidden_def (_IO_un_link)
84
85void
86_IO_link_in (struct _IO_FILE_plus *fp)
87{
88 if ((fp->file._flags & _IO_LINKED) == 0)
89 {
90 fp->file._flags |= _IO_LINKED;
91#ifdef _IO_MTSAFE_IO
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);
96#endif
97 fp->file._chain = (_IO_FILE *) _IO_list_all;
98 _IO_list_all = fp;
99#ifdef _IO_MTSAFE_IO
100 _IO_funlockfile ((_IO_FILE *) fp);
101 run_fp = NULL;
102 _IO_lock_unlock (list_all_lock);
103 _IO_cleanup_region_end (0);
104#endif
105 }
106}
107libc_hidden_def (_IO_link_in)
108
109/* Return minimum _pos markers
110 Assumes the current get area is the main get area. */
111_IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
112
113_IO_ssize_t
114_IO_least_marker (_IO_FILE *fp, char *end_p)
115{
116 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
117 struct _IO_marker *mark;
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
127_IO_switch_to_main_get_area (_IO_FILE *fp)
128{
129 char *tmp;
130 fp->_flags &= ~_IO_IN_BACKUP;
131 /* Swap _IO_read_end and _IO_save_end. */
132 tmp = fp->_IO_read_end;
133 fp->_IO_read_end = fp->_IO_save_end;
134 fp->_IO_save_end= tmp;
135 /* Swap _IO_read_base and _IO_save_base. */
136 tmp = fp->_IO_read_base;
137 fp->_IO_read_base = fp->_IO_save_base;
138 fp->_IO_save_base = tmp;
139 /* Set _IO_read_ptr. */
140 fp->_IO_read_ptr = fp->_IO_read_base;
141}
142
143/* Switch current get area from main get area to (end of) backup area. */
144
145void
146_IO_switch_to_backup_area (_IO_FILE *fp)
147{
148 char *tmp;
149 fp->_flags |= _IO_IN_BACKUP;
150 /* Swap _IO_read_end and _IO_save_end. */
151 tmp = fp->_IO_read_end;
152 fp->_IO_read_end = fp->_IO_save_end;
153 fp->_IO_save_end = tmp;
154 /* Swap _IO_read_base and _IO_save_base. */
155 tmp = fp->_IO_read_base;
156 fp->_IO_read_base = fp->_IO_save_base;
157 fp->_IO_save_base = tmp;
158 /* Set _IO_read_ptr. */
159 fp->_IO_read_ptr = fp->_IO_read_end;
160}
161
162int
163_IO_switch_to_get_mode (_IO_FILE *fp)
164{
165 if (fp->_IO_write_ptr > fp->_IO_write_base)
166 if (_IO_OVERFLOW (fp, EOF) == EOF)
167 return EOF;
168 if (_IO_in_backup (fp))
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}
183libc_hidden_def (_IO_switch_to_get_mode)
184
185void
186_IO_free_backup_area (_IO_FILE *fp)
187{
188 if (_IO_in_backup (fp))
189 _IO_switch_to_main_get_area (fp); /* Just in case. */
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}
195libc_hidden_def (_IO_free_backup_area)
196
197#if 0
198int
199_IO_switch_to_put_mode (_IO_FILE *fp)
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? */
204 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
205 ? fp->_IO_read_end : fp->_IO_buf_end);
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
216__overflow (_IO_FILE *f, int ch)
217{
218 /* This is a single-byte stream. */
219 if (f->_mode == 0)
220 _IO_fwide (f, -1);
221 return _IO_OVERFLOW (f, ch);
222}
223libc_hidden_def (__overflow)
224
225static int
226save_for_backup (_IO_FILE *fp, char *end_p)
227{
228 /* Append [_IO_read_base..end_p] to backup area. */
229 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
230 /* needed_size is how much space we need in the backup area. */
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;
236 struct _IO_marker *mark;
237 if (needed_size > current_Bsize)
238 {
239 char *new_buffer;
240 avail = 100;
241 new_buffer = (char *) malloc (avail + needed_size);
242 if (new_buffer == NULL)
243 return EOF; /* FIXME */
244 if (least_mark < 0)
245 {
246 __mempcpy (__mempcpy (new_buffer + avail,
247 fp->_IO_save_end + least_mark,
248 -least_mark),
249 fp->_IO_read_base,
250 end_p - fp->_IO_read_base);
251 }
252 else
253 memcpy (new_buffer + avail,
254 fp->_IO_read_base + least_mark,
255 needed_size);
256 free (fp->_IO_save_base);
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 {
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,
270 end_p - fp->_IO_read_base);
271 }
272 else if (needed_size > 0)
273 memcpy (fp->_IO_save_base + avail,
274 fp->_IO_read_base + least_mark,
275 needed_size);
276 }
277 fp->_IO_backup_base = fp->_IO_save_base + avail;
278 /* Adjust all the streammarkers. */
279 delta = end_p - fp->_IO_read_base;
280 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
281 mark->_pos -= delta;
282 return 0;
283}
284
285int
286__underflow (_IO_FILE *fp)
287{
288 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
289 return EOF;
290
291 if (fp->_mode == 0)
292 _IO_fwide (fp, -1);
293 if (_IO_in_put_mode (fp))
294 if (_IO_switch_to_get_mode (fp) == EOF)
295 return EOF;
296 if (fp->_IO_read_ptr < fp->_IO_read_end)
297 return *(unsigned char *) fp->_IO_read_ptr;
298 if (_IO_in_backup (fp))
299 {
300 _IO_switch_to_main_get_area (fp);
301 if (fp->_IO_read_ptr < fp->_IO_read_end)
302 return *(unsigned char *) fp->_IO_read_ptr;
303 }
304 if (_IO_have_markers (fp))
305 {
306 if (save_for_backup (fp, fp->_IO_read_end))
307 return EOF;
308 }
309 else if (_IO_have_backup (fp))
310 _IO_free_backup_area (fp);
311 return _IO_UNDERFLOW (fp);
312}
313libc_hidden_def (__underflow)
314
315int
316__uflow (_IO_FILE *fp)
317{
318 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
319 return EOF;
320
321 if (fp->_mode == 0)
322 _IO_fwide (fp, -1);
323 if (_IO_in_put_mode (fp))
324 if (_IO_switch_to_get_mode (fp) == EOF)
325 return EOF;
326 if (fp->_IO_read_ptr < fp->_IO_read_end)
327 return *(unsigned char *) fp->_IO_read_ptr++;
328 if (_IO_in_backup (fp))
329 {
330 _IO_switch_to_main_get_area (fp);
331 if (fp->_IO_read_ptr < fp->_IO_read_end)
332 return *(unsigned char *) fp->_IO_read_ptr++;
333 }
334 if (_IO_have_markers (fp))
335 {
336 if (save_for_backup (fp, fp->_IO_read_end))
337 return EOF;
338 }
339 else if (_IO_have_backup (fp))
340 _IO_free_backup_area (fp);
341 return _IO_UFLOW (fp);
342}
343libc_hidden_def (__uflow)
344
345void
346_IO_setb (_IO_FILE *f, char *b, char *eb, int a)
347{
348 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
349 free (f->_IO_buf_base);
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}
357libc_hidden_def (_IO_setb)
358
359void
360_IO_doallocbuf (_IO_FILE *fp)
361{
362 if (fp->_IO_buf_base)
363 return;
364 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
365 if (_IO_DOALLOCATE (fp) != EOF)
366 return;
367 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
368}
369libc_hidden_def (_IO_doallocbuf)
370
371int
372_IO_default_underflow (_IO_FILE *fp)
373{
374 return EOF;
375}
376
377int
378_IO_default_uflow (_IO_FILE *fp)
379{
380 int ch = _IO_UNDERFLOW (fp);
381 if (ch == EOF)
382 return EOF;
383 return *(unsigned char *) fp->_IO_read_ptr++;
384}
385libc_hidden_def (_IO_default_uflow)
386
387_IO_size_t
388_IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
389{
390 const char *s = (char *) data;
391 _IO_size_t more = n;
392 if (more <= 0)
393 return 0;
394 for (;;)
395 {
396 /* Space available. */
397 if (f->_IO_write_ptr < f->_IO_write_end)
398 {
399 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
400 if (count > more)
401 count = more;
402 if (count > 20)
403 {
404 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
405 s += count;
406 }
407 else if (count)
408 {
409 char *p = f->_IO_write_ptr;
410 _IO_ssize_t i;
411 for (i = count; --i >= 0; )
412 *p++ = *s++;
413 f->_IO_write_ptr = p;
414 }
415 more -= count;
416 }
417 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
418 break;
419 more--;
420 }
421 return n - more;
422}
423libc_hidden_def (_IO_default_xsputn)
424
425_IO_size_t
426_IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n)
427{
428 /* FIXME handle putback buffer here! */
429 return _IO_XSGETN (fp, data, n);
430}
431libc_hidden_def (_IO_sgetn)
432
433_IO_size_t
434_IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
435{
436 _IO_size_t more = n;
437 char *s = (char*) data;
438 for (;;)
439 {
440 /* Data available. */
441 if (fp->_IO_read_ptr < fp->_IO_read_end)
442 {
443 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
444 if (count > more)
445 count = more;
446 if (count > 20)
447 {
448 s = __mempcpy (s, fp->_IO_read_ptr, count);
449 fp->_IO_read_ptr += count;
450 }
451 else if (count)
452 {
453 char *p = fp->_IO_read_ptr;
454 int i = (int) count;
455 while (--i >= 0)
456 *s++ = *p++;
457 fp->_IO_read_ptr = p;
458 }
459 more -= count;
460 }
461 if (more == 0 || __underflow (fp) == EOF)
462 break;
463 }
464 return n - more;
465}
466libc_hidden_def (_IO_default_xsgetn)
467
468#if 0
469/* Seems not to be needed. --drepper */
470int
471_IO_sync (_IO_FILE *fp)
472{
473 return 0;
474}
475#endif
476
477_IO_FILE *
478_IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
479{
480 if (_IO_SYNC (fp) == EOF)
481 return NULL;
482 if (p == NULL || len == 0)
483 {
484 fp->_flags |= _IO_UNBUFFERED;
485 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
486 }
487 else
488 {
489 fp->_flags &= ~_IO_UNBUFFERED;
490 _IO_setb (fp, p, p+len, 0);
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
497_IO_off64_t
498_IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode)
499{
500 return _IO_SEEKOFF (fp, pos, 0, mode);
501}
502
503int
504_IO_default_doallocate (_IO_FILE *fp)
505{
506 char *buf;
507
508 buf = malloc(_IO_BUFSIZ);
509 if (__glibc_unlikely (buf == NULL))
510 return EOF;
511
512 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
513 return 1;
514}
515libc_hidden_def (_IO_default_doallocate)
516
517void
518_IO_init_internal (_IO_FILE *fp, int flags)
519{
520 _IO_no_init (fp, flags, -1, NULL, NULL);
521}
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}
529
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
556void
557_IO_old_init (_IO_FILE *fp, int flags)
558{
559 fp->_flags = _IO_MAGIC|flags;
560 fp->_flags2 = 0;
561 if (stdio_needs_locking)
562 fp->_flags2 |= _IO_FLAGS2_NEED_LOCK;
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;
578#if _IO_JUMPS_OFFSET
579 fp->_vtable_offset = 0;
580#endif
581#ifdef _IO_MTSAFE_IO
582 if (fp->_lock != NULL)
583 _IO_lock_init (*fp->_lock);
584#endif
585}
586
587void
588_IO_no_init (_IO_FILE *fp, int flags, int orientation,
589 struct _IO_wide_data *wd, const struct _IO_jump_t *jmp)
590{
591 _IO_old_init (fp, flags);
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 }
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;
614 fp->_freeres_list = NULL;
615}
616
617int
618_IO_default_sync (_IO_FILE *fp)
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
627_IO_default_finish (_IO_FILE *fp, int dummy)
628{
629 struct _IO_marker *mark;
630 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
631 {
632 free (fp->_IO_buf_base);
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
645 _IO_un_link ((struct _IO_FILE_plus *) fp);
646
647#ifdef _IO_MTSAFE_IO
648 if (fp->_lock != NULL)
649 _IO_lock_fini (*fp->_lock);
650#endif
651}
652libc_hidden_def (_IO_default_finish)
653
654_IO_off64_t
655_IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
656{
657 return _IO_pos_BAD;
658}
659
660int
661_IO_sputbackc (_IO_FILE *fp, int c)
662{
663 int result;
664
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--;
669 result = (unsigned char) c;
670 }
671 else
672 result = _IO_PBACKFAIL (fp, c);
673
674 if (result != EOF)
675 fp->_flags &= ~_IO_EOF_SEEN;
676
677 return result;
678}
679libc_hidden_def (_IO_sputbackc)
680
681int
682_IO_sungetc (_IO_FILE *fp)
683{
684 int result;
685
686 if (fp->_IO_read_ptr > fp->_IO_read_base)
687 {
688 fp->_IO_read_ptr--;
689 result = (unsigned char) *fp->_IO_read_ptr;
690 }
691 else
692 result = _IO_PBACKFAIL (fp, EOF);
693
694 if (result != EOF)
695 fp->_flags &= ~_IO_EOF_SEEN;
696
697 return result;
698}
699
700#if 0 /* Work in progress */
701/* Seems not to be needed. */
702#if 0
703void
704_IO_set_column (_IO_FILE *fp, int c)
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
713_IO_set_column (_IO_FILE *fp, int i)
714{
715 fp->_cur_column = i + 1;
716 return 0;
717}
718#endif
719#endif
720
721
722unsigned
723_IO_adjust_column (unsigned start, const char *line, int count)
724{
725 const char *ptr = line + count;
726 while (ptr > line)
727 if (*--ptr == '\n')
728 return line + count - ptr - 1;
729 return start + count;
730}
731libc_hidden_def (_IO_adjust_column)
732
733#if 0
734/* Seems not to be needed. --drepper */
735int
736_IO_get_column (_IO_FILE *fp)
737{
738 if (fp->_cur_column)
739 return _IO_adjust_column (fp->_cur_column - 1,
740 fp->_IO_write_base,
741 fp->_IO_write_ptr - fp->_IO_write_base);
742 return -1;
743}
744#endif
745
746
747int
748_IO_flush_all_lockp (int do_lock)
749{
750 int result = 0;
751 struct _IO_FILE *fp;
752
753#ifdef _IO_MTSAFE_IO
754 _IO_cleanup_region_start_noarg (flush_cleanup);
755 _IO_lock_lock (list_all_lock);
756#endif
757
758 for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
759 {
760 run_fp = fp;
761 if (do_lock)
762 _IO_flockfile (fp);
763
764 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
765 || (_IO_vtable_offset (fp) == 0
766 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
767 > fp->_wide_data->_IO_write_base))
768 )
769 && _IO_OVERFLOW (fp, EOF) == EOF)
770 result = EOF;
771
772 if (do_lock)
773 _IO_funlockfile (fp);
774 run_fp = NULL;
775 }
776
777#ifdef _IO_MTSAFE_IO
778 _IO_lock_unlock (list_all_lock);
779 _IO_cleanup_region_end (0);
780#endif
781
782 return result;
783}
784
785
786int
787_IO_flush_all (void)
788{
789 /* We want locking. */
790 return _IO_flush_all_lockp (1);
791}
792libc_hidden_def (_IO_flush_all)
793
794void
795_IO_flush_all_linebuffered (void)
796{
797 struct _IO_FILE *fp;
798
799#ifdef _IO_MTSAFE_IO
800 _IO_cleanup_region_start_noarg (flush_cleanup);
801 _IO_lock_lock (list_all_lock);
802#endif
803
804 for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
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;
814 }
815
816#ifdef _IO_MTSAFE_IO
817 _IO_lock_unlock (list_all_lock);
818 _IO_cleanup_region_end (0);
819#endif
820}
821libc_hidden_def (_IO_flush_all_linebuffered)
822weak_alias (_IO_flush_all_linebuffered, _flushlbf)
823
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
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
837 which the freeres function later can walk through. */
838static void _IO_unbuffer_all (void);
839
840static bool dealloc_buffers;
841static _IO_FILE *freeres_list;
842
843static void
844_IO_unbuffer_all (void)
845{
846 struct _IO_FILE *fp;
847
848#ifdef _IO_MTSAFE_IO
849 _IO_cleanup_region_start_noarg (flush_cleanup);
850 _IO_lock_lock (list_all_lock);
851#endif
852
853 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
854 {
855 int legacy = 0;
856
857#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
858 if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
859 legacy = 1;
860#endif
861
862 if (! (fp->_flags & _IO_UNBUFFERED)
863 /* Iff stream is un-orientated, it wasn't used. */
864 && (legacy || fp->_mode != 0))
865 {
866#ifdef _IO_MTSAFE_IO
867 int cnt;
868#define MAXTRIES 2
869 for (cnt = 0; cnt < MAXTRIES; ++cnt)
870 if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
871 break;
872 else
873 /* Give the other thread time to finish up its use of the
874 stream. */
875 __sched_yield ();
876#endif
877
878 if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
879 {
880 fp->_flags |= _IO_USER_BUF;
881
882 fp->_freeres_list = freeres_list;
883 freeres_list = fp;
884 fp->_freeres_buf = fp->_IO_buf_base;
885 }
886
887 _IO_SETBUF (fp, NULL, 0);
888
889 if (! legacy && fp->_mode > 0)
890 _IO_wsetb (fp, NULL, NULL, 0);
891
892#ifdef _IO_MTSAFE_IO
893 if (cnt < MAXTRIES && fp->_lock != NULL)
894 _IO_lock_unlock (*fp->_lock);
895#endif
896 }
897
898 /* Make sure that never again the wide char functions can be
899 used. */
900 if (! legacy)
901 fp->_mode = -1;
902 }
903
904#ifdef _IO_MTSAFE_IO
905 _IO_lock_unlock (list_all_lock);
906 _IO_cleanup_region_end (0);
907#endif
908}
909
910
911libc_freeres_fn (buffer_free)
912{
913 dealloc_buffers = true;
914
915 while (freeres_list != NULL)
916 {
917 free (freeres_list->_freeres_buf);
918
919 freeres_list = freeres_list->_freeres_list;
920 }
921}
922
923
924int
925_IO_cleanup (void)
926{
927 /* We do *not* want locking. Some threads might use streams but
928 that is their problem, we flush them underneath them. */
929 int result = _IO_flush_all_lockp (0);
930
931 /* We currently don't have a reliable mechanism for making sure that
932 C++ static destructors are executed in the correct order.
933 So it is possible that other static destructors might want to
934 write to cout - and they're supposed to be able to do so.
935
936 The following will make the standard streambufs be unbuffered,
937 which forces any output from late destructors to be written out. */
938 _IO_unbuffer_all ();
939
940 return result;
941}
942
943
944void
945_IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp)
946{
947 marker->_sbuf = fp;
948 if (_IO_in_put_mode (fp))
949 _IO_switch_to_get_mode (fp);
950 if (_IO_in_backup (fp))
951 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
952 else
953 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
954
955 /* Should perhaps sort the chain? */
956 marker->_next = fp->_markers;
957 fp->_markers = marker;
958}
959
960void
961_IO_remove_marker (struct _IO_marker *marker)
962{
963 /* Unlink from sb's chain. */
964 struct _IO_marker **ptr = &marker->_sbuf->_markers;
965 for (; ; ptr = &(*ptr)->_next)
966 {
967 if (*ptr == NULL)
968 break;
969 else if (*ptr == marker)
970 {
971 *ptr = marker->_next;
972 return;
973 }
974 }
975#if 0
976 if _sbuf has a backup area that is no longer needed, should we delete
977 it now, or wait until the next underflow?
978#endif
979}
980
981#define BAD_DELTA EOF
982
983int
984_IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2)
985{
986 return mark1->_pos - mark2->_pos;
987}
988
989/* Return difference between MARK and current position of MARK's stream. */
990int
991_IO_marker_delta (struct _IO_marker *mark)
992{
993 int cur_pos;
994 if (mark->_sbuf == NULL)
995 return BAD_DELTA;
996 if (_IO_in_backup (mark->_sbuf))
997 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
998 else
999 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1000 return mark->_pos - cur_pos;
1001}
1002
1003int
1004_IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta)
1005{
1006 if (mark->_sbuf != fp)
1007 return EOF;
1008 if (mark->_pos >= 0)
1009 {
1010 if (_IO_in_backup (fp))
1011 _IO_switch_to_main_get_area (fp);
1012 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1013 }
1014 else
1015 {
1016 if (!_IO_in_backup (fp))
1017 _IO_switch_to_backup_area (fp);
1018 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1019 }
1020 return 0;
1021}
1022
1023void
1024_IO_unsave_markers (_IO_FILE *fp)
1025{
1026 struct _IO_marker *mark = fp->_markers;
1027 if (mark)
1028 {
1029#ifdef TODO
1030 streampos offset = seekoff (0, ios::cur, ios::in);
1031 if (offset != EOF)
1032 {
1033 offset += eGptr () - Gbase ();
1034 for ( ; mark != NULL; mark = mark->_next)
1035 mark->set_streampos (mark->_pos + offset);
1036 }
1037 else
1038 {
1039 for ( ; mark != NULL; mark = mark->_next)
1040 mark->set_streampos (EOF);
1041 }
1042#endif
1043 fp->_markers = 0;
1044 }
1045
1046 if (_IO_have_backup (fp))
1047 _IO_free_backup_area (fp);
1048}
1049libc_hidden_def (_IO_unsave_markers)
1050
1051#if 0
1052/* Seems not to be needed. --drepper */
1053int
1054_IO_nobackup_pbackfail (_IO_FILE *fp, int c)
1055{
1056 if (fp->_IO_read_ptr > fp->_IO_read_base)
1057 fp->_IO_read_ptr--;
1058 if (c != EOF && *fp->_IO_read_ptr != c)
1059 *fp->_IO_read_ptr = c;
1060 return (unsigned char) c;
1061}
1062#endif
1063
1064int
1065_IO_default_pbackfail (_IO_FILE *fp, int c)
1066{
1067 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1068 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1069 --fp->_IO_read_ptr;
1070 else
1071 {
1072 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1073 if (!_IO_in_backup (fp))
1074 {
1075 /* We need to keep the invariant that the main get area
1076 logically follows the backup area. */
1077 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1078 {
1079 if (save_for_backup (fp, fp->_IO_read_ptr))
1080 return EOF;
1081 }
1082 else if (!_IO_have_backup (fp))
1083 {
1084 /* No backup buffer: allocate one. */
1085 /* Use nshort buffer, if unused? (probably not) FIXME */
1086 int backup_size = 128;
1087 char *bbuf = (char *) malloc (backup_size);
1088 if (bbuf == NULL)
1089 return EOF;
1090 fp->_IO_save_base = bbuf;
1091 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1092 fp->_IO_backup_base = fp->_IO_save_end;
1093 }
1094 fp->_IO_read_base = fp->_IO_read_ptr;
1095 _IO_switch_to_backup_area (fp);
1096 }
1097 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1098 {
1099 /* Increase size of existing backup buffer. */
1100 _IO_size_t new_size;
1101 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1102 char *new_buf;
1103 new_size = 2 * old_size;
1104 new_buf = (char *) malloc (new_size);
1105 if (new_buf == NULL)
1106 return EOF;
1107 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1108 old_size);
1109 free (fp->_IO_read_base);
1110 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1111 new_buf + new_size);
1112 fp->_IO_backup_base = fp->_IO_read_ptr;
1113 }
1114
1115 *--fp->_IO_read_ptr = c;
1116 }
1117 return (unsigned char) c;
1118}
1119libc_hidden_def (_IO_default_pbackfail)
1120
1121_IO_off64_t
1122_IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1123{
1124 return _IO_pos_BAD;
1125}
1126
1127int
1128_IO_default_stat (_IO_FILE *fp, void *st)
1129{
1130 return EOF;
1131}
1132
1133_IO_ssize_t
1134_IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n)
1135{
1136 return -1;
1137}
1138
1139_IO_ssize_t
1140_IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n)
1141{
1142 return 0;
1143}
1144
1145int
1146_IO_default_showmanyc (_IO_FILE *fp)
1147{
1148 return -1;
1149}
1150
1151void
1152_IO_default_imbue (_IO_FILE *fp, void *locale)
1153{
1154}
1155
1156_IO_ITER
1157_IO_iter_begin (void)
1158{
1159 return (_IO_ITER) _IO_list_all;
1160}
1161libc_hidden_def (_IO_iter_begin)
1162
1163_IO_ITER
1164_IO_iter_end (void)
1165{
1166 return NULL;
1167}
1168libc_hidden_def (_IO_iter_end)
1169
1170_IO_ITER
1171_IO_iter_next (_IO_ITER iter)
1172{
1173 return iter->_chain;
1174}
1175libc_hidden_def (_IO_iter_next)
1176
1177_IO_FILE *
1178_IO_iter_file (_IO_ITER iter)
1179{
1180 return iter;
1181}
1182libc_hidden_def (_IO_iter_file)
1183
1184void
1185_IO_list_lock (void)
1186{
1187#ifdef _IO_MTSAFE_IO
1188 _IO_lock_lock (list_all_lock);
1189#endif
1190}
1191libc_hidden_def (_IO_list_lock)
1192
1193void
1194_IO_list_unlock (void)
1195{
1196#ifdef _IO_MTSAFE_IO
1197 _IO_lock_unlock (list_all_lock);
1198#endif
1199}
1200libc_hidden_def (_IO_list_unlock)
1201
1202void
1203_IO_list_resetlock (void)
1204{
1205#ifdef _IO_MTSAFE_IO
1206 _IO_lock_init (list_all_lock);
1207#endif
1208}
1209libc_hidden_def (_IO_list_resetlock)
1210
1211
1212#ifdef TODO
1213#if defined(linux)
1214#define IO_CLEANUP ;
1215#endif
1216
1217#ifdef IO_CLEANUP
1218 IO_CLEANUP
1219#else
1220struct __io_defs {
1221 __io_defs() { }
1222 ~__io_defs() { _IO_cleanup (); }
1223};
1224__io_defs io_defs__;
1225#endif
1226
1227#endif /* TODO */
1228
1229#ifdef text_set_element
1230text_set_element(__libc_atexit, _IO_cleanup);
1231#endif
1232