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