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