(_IO_default_finish): Call _IO_lock_fini after _IO_un_link, not before it.
[kopensolaris-gnu/glibc.git] / libio / genops.c
1 /* Copyright (C) 1993,1995,1997-2002, 2003, 2004, 2006, 2007
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.
19
20    As a special exception, if you link the code in this file with
21    files compiled with a GNU compiler to produce an executable,
22    that does not cause the resulting executable to be covered by
23    the GNU Lesser General Public License.  This exception does not
24    however invalidate any other reasons why the executable file
25    might be covered by the GNU Lesser General Public License.
26    This exception applies to code released by its copyright holders
27    in files containing the exception.  */
28
29 /* Generic or default I/O operations. */
30
31 #include "libioP.h"
32 #ifdef __STDC__
33 #include <stdlib.h>
34 #endif
35 #include <string.h>
36 #include <stdbool.h>
37 #ifdef _LIBC
38 #include <sched.h>
39 #endif
40
41 #ifdef _IO_MTSAFE_IO
42 static _IO_lock_t list_all_lock = _IO_lock_initializer;
43 #endif
44
45 /* Used to signal modifications to the list of FILE decriptors.  */
46 static int _IO_list_all_stamp;
47
48
49 static _IO_FILE *run_fp;
50
51 static void
52 flush_cleanup (void *not_used)
53 {
54   if (run_fp != NULL)
55     _IO_funlockfile (run_fp);
56 #ifdef _IO_MTSAFE_IO
57   _IO_lock_unlock (list_all_lock);
58 #endif
59 }
60
61 void
62 _IO_un_link (fp)
63      struct _IO_FILE_plus *fp;
64 {
65   if (fp->file._flags & _IO_LINKED)
66     {
67       struct _IO_FILE_plus **f;
68 #ifdef _IO_MTSAFE_IO
69       _IO_cleanup_region_start_noarg (flush_cleanup);
70       _IO_lock_lock (list_all_lock);
71       run_fp = (_IO_FILE *) fp;
72       _IO_flockfile ((_IO_FILE *) fp);
73 #endif
74       for (f = &INTUSE(_IO_list_all); *f;
75            f = (struct _IO_FILE_plus **) &(*f)->file._chain)
76         {
77           if (*f == fp)
78             {
79               *f = (struct _IO_FILE_plus *) fp->file._chain;
80               ++_IO_list_all_stamp;
81               break;
82             }
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 }
93 INTDEF(_IO_un_link)
94
95 void
96 _IO_link_in (fp)
97      struct _IO_FILE_plus *fp;
98 {
99   if ((fp->file._flags & _IO_LINKED) == 0)
100     {
101       fp->file._flags |= _IO_LINKED;
102 #ifdef _IO_MTSAFE_IO
103       _IO_cleanup_region_start_noarg (flush_cleanup);
104       _IO_lock_lock (list_all_lock);
105       run_fp = (_IO_FILE *) fp;
106       _IO_flockfile ((_IO_FILE *) fp);
107 #endif
108       fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
109       INTUSE(_IO_list_all) = fp;
110       ++_IO_list_all_stamp;
111 #ifdef _IO_MTSAFE_IO
112       _IO_funlockfile ((_IO_FILE *) fp);
113       run_fp = NULL;
114       _IO_lock_unlock (list_all_lock);
115       _IO_cleanup_region_end (0);
116 #endif
117     }
118 }
119 INTDEF(_IO_link_in)
120
121 /* Return minimum _pos markers
122    Assumes the current get area is the main get area. */
123 _IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
124
125 _IO_ssize_t
126 _IO_least_marker (fp, end_p)
127      _IO_FILE *fp;
128      char *end_p;
129 {
130   _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
131   struct _IO_marker *mark;
132   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
133     if (mark->_pos < least_so_far)
134       least_so_far = mark->_pos;
135   return least_so_far;
136 }
137
138 /* Switch current get area from backup buffer to (start of) main get area. */
139
140 void
141 _IO_switch_to_main_get_area (fp)
142      _IO_FILE *fp;
143 {
144   char *tmp;
145   fp->_flags &= ~_IO_IN_BACKUP;
146   /* Swap _IO_read_end and _IO_save_end. */
147   tmp = fp->_IO_read_end;
148   fp->_IO_read_end = fp->_IO_save_end;
149   fp->_IO_save_end= tmp;
150   /* Swap _IO_read_base and _IO_save_base. */
151   tmp = fp->_IO_read_base;
152   fp->_IO_read_base = fp->_IO_save_base;
153   fp->_IO_save_base = tmp;
154   /* Set _IO_read_ptr. */
155   fp->_IO_read_ptr = fp->_IO_read_base;
156 }
157
158 /* Switch current get area from main get area to (end of) backup area. */
159
160 void
161 _IO_switch_to_backup_area (fp)
162      _IO_FILE *fp;
163 {
164   char *tmp;
165   fp->_flags |= _IO_IN_BACKUP;
166   /* Swap _IO_read_end and _IO_save_end. */
167   tmp = fp->_IO_read_end;
168   fp->_IO_read_end = fp->_IO_save_end;
169   fp->_IO_save_end = tmp;
170   /* Swap _IO_read_base and _IO_save_base. */
171   tmp = fp->_IO_read_base;
172   fp->_IO_read_base = fp->_IO_save_base;
173   fp->_IO_save_base = tmp;
174   /* Set _IO_read_ptr.  */
175   fp->_IO_read_ptr = fp->_IO_read_end;
176 }
177
178 int
179 _IO_switch_to_get_mode (fp)
180      _IO_FILE *fp;
181 {
182   if (fp->_IO_write_ptr > fp->_IO_write_base)
183     if (_IO_OVERFLOW (fp, EOF) == EOF)
184       return EOF;
185   if (_IO_in_backup (fp))
186     fp->_IO_read_base = fp->_IO_backup_base;
187   else
188     {
189       fp->_IO_read_base = fp->_IO_buf_base;
190       if (fp->_IO_write_ptr > fp->_IO_read_end)
191         fp->_IO_read_end = fp->_IO_write_ptr;
192     }
193   fp->_IO_read_ptr = fp->_IO_write_ptr;
194
195   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
196
197   fp->_flags &= ~_IO_CURRENTLY_PUTTING;
198   return 0;
199 }
200 INTDEF(_IO_switch_to_get_mode)
201
202 void
203 _IO_free_backup_area (fp)
204      _IO_FILE *fp;
205 {
206   if (_IO_in_backup (fp))
207     _IO_switch_to_main_get_area (fp);  /* Just in case. */
208   free (fp->_IO_save_base);
209   fp->_IO_save_base = NULL;
210   fp->_IO_save_end = NULL;
211   fp->_IO_backup_base = NULL;
212 }
213 INTDEF(_IO_free_backup_area)
214
215 #if 0
216 int
217 _IO_switch_to_put_mode (fp)
218      _IO_FILE *fp;
219 {
220   fp->_IO_write_base = fp->_IO_read_ptr;
221   fp->_IO_write_ptr = fp->_IO_read_ptr;
222   /* Following is wrong if line- or un-buffered? */
223   fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
224                        ? fp->_IO_read_end : fp->_IO_buf_end);
225
226   fp->_IO_read_ptr = fp->_IO_read_end;
227   fp->_IO_read_base = fp->_IO_read_end;
228
229   fp->_flags |= _IO_CURRENTLY_PUTTING;
230   return 0;
231 }
232 #endif
233
234 int
235 __overflow (f, ch)
236      _IO_FILE *f;
237      int ch;
238 {
239   /* This is a single-byte stream.  */
240   if (f->_mode == 0)
241     _IO_fwide (f, -1);
242   return _IO_OVERFLOW (f, ch);
243 }
244 libc_hidden_def (__overflow)
245
246 static int save_for_backup (_IO_FILE *fp, char *end_p)
247 #ifdef _LIBC
248      internal_function
249 #endif
250      ;
251
252 static int
253 #ifdef _LIBC
254 internal_function
255 #endif
256 save_for_backup (fp, end_p)
257      _IO_FILE *fp;
258      char *end_p;
259 {
260   /* Append [_IO_read_base..end_p] to backup area. */
261   _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
262   /* needed_size is how much space we need in the backup area. */
263   _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
264   /* FIXME: Dubious arithmetic if pointers are NULL */
265   _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
266   _IO_size_t avail; /* Extra space available for future expansion. */
267   _IO_ssize_t delta;
268   struct _IO_marker *mark;
269   if (needed_size > current_Bsize)
270     {
271       char *new_buffer;
272       avail = 100;
273       new_buffer = (char *) malloc (avail + needed_size);
274       if (new_buffer == NULL)
275         return EOF;             /* FIXME */
276       if (least_mark < 0)
277         {
278 #ifdef _LIBC
279           __mempcpy (__mempcpy (new_buffer + avail,
280                                 fp->_IO_save_end + least_mark,
281                                 -least_mark),
282                      fp->_IO_read_base,
283                      end_p - fp->_IO_read_base);
284 #else
285           memcpy (new_buffer + avail,
286                   fp->_IO_save_end + least_mark,
287                   -least_mark);
288           memcpy (new_buffer + avail - least_mark,
289                   fp->_IO_read_base,
290                   end_p - fp->_IO_read_base);
291 #endif
292         }
293       else
294         memcpy (new_buffer + avail,
295                 fp->_IO_read_base + least_mark,
296                 needed_size);
297       if (fp->_IO_save_base)
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 (INTUSE(_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     INTUSE(_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 (INTUSE(_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     INTUSE(_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 INTDEF(_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   INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
421 }
422 INTDEF(_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 INTDEF(_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 INTDEF(_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 INTDEF(_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 INTDEF(_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         INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
564       }
565     else
566       {
567         fp->_flags &= ~_IO_UNBUFFERED;
568         INTUSE(_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   INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
592   return 1;
593 }
594 INTDEF(_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 INTDEF(_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 #endif
665   fp->_freeres_list = NULL;
666 }
667
668 int
669 _IO_default_sync (fp)
670      _IO_FILE *fp;
671 {
672   return 0;
673 }
674
675 /* The way the C++ classes are mapped into the C functions in the
676    current implementation, this function can get called twice! */
677
678 void
679 _IO_default_finish (fp, dummy)
680      _IO_FILE *fp;
681      int dummy;
682 {
683   struct _IO_marker *mark;
684   if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
685     {
686       FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
687       fp->_IO_buf_base = fp->_IO_buf_end = NULL;
688     }
689
690   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
691     mark->_sbuf = NULL;
692
693   if (fp->_IO_save_base)
694     {
695       free (fp->_IO_save_base);
696       fp->_IO_save_base = NULL;
697     }
698
699   INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
700
701 #ifdef _IO_MTSAFE_IO
702   if (fp->_lock != NULL)
703     _IO_lock_fini (*fp->_lock);
704 #endif
705 }
706 INTDEF(_IO_default_finish)
707
708 _IO_off64_t
709 _IO_default_seekoff (fp, offset, dir, mode)
710      _IO_FILE *fp;
711      _IO_off64_t offset;
712      int dir;
713      int mode;
714 {
715   return _IO_pos_BAD;
716 }
717
718 int
719 _IO_sputbackc (fp, c)
720      _IO_FILE *fp;
721      int c;
722 {
723   int result;
724
725   if (fp->_IO_read_ptr > fp->_IO_read_base
726       && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
727     {
728       fp->_IO_read_ptr--;
729       result = (unsigned char) c;
730     }
731   else
732     result = _IO_PBACKFAIL (fp, c);
733
734   if (result != EOF)
735     fp->_flags &= ~_IO_EOF_SEEN;
736
737   return result;
738 }
739 INTDEF(_IO_sputbackc)
740
741 int
742 _IO_sungetc (fp)
743      _IO_FILE *fp;
744 {
745   int result;
746
747   if (fp->_IO_read_ptr > fp->_IO_read_base)
748     {
749       fp->_IO_read_ptr--;
750       result = (unsigned char) *fp->_IO_read_ptr;
751     }
752   else
753     result = _IO_PBACKFAIL (fp, EOF);
754
755   if (result != EOF)
756     fp->_flags &= ~_IO_EOF_SEEN;
757
758   return result;
759 }
760
761 #if 0 /* Work in progress */
762 /* Seems not to be needed.  */
763 #if 0
764 void
765 _IO_set_column (fp, c)
766      _IO_FILE *fp;
767      int c;
768 {
769   if (c == -1)
770     fp->_column = -1;
771   else
772     fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
773 }
774 #else
775 int
776 _IO_set_column (fp, i)
777      _IO_FILE *fp;
778      int i;
779 {
780   fp->_cur_column = i + 1;
781   return 0;
782 }
783 #endif
784 #endif
785
786
787 unsigned
788 _IO_adjust_column (start, line, count)
789      unsigned start;
790      const char *line;
791      int count;
792 {
793   const char *ptr = line + count;
794   while (ptr > line)
795     if (*--ptr == '\n')
796       return line + count - ptr - 1;
797   return start + count;
798 }
799 INTDEF(_IO_adjust_column)
800
801 #if 0
802 /* Seems not to be needed. --drepper */
803 int
804 _IO_get_column (fp)
805      _IO_FILE *fp;
806 {
807   if (fp->_cur_column)
808     return _IO_adjust_column (fp->_cur_column - 1,
809                               fp->_IO_write_base,
810                               fp->_IO_write_ptr - fp->_IO_write_base);
811   return -1;
812 }
813 #endif
814
815
816 int
817 _IO_flush_all_lockp (int do_lock)
818 {
819   int result = 0;
820   struct _IO_FILE *fp;
821   int last_stamp;
822
823 #ifdef _IO_MTSAFE_IO
824   _IO_cleanup_region_start_noarg (flush_cleanup);
825   if (do_lock)
826     _IO_lock_lock (list_all_lock);
827 #endif
828
829   last_stamp = _IO_list_all_stamp;
830   fp = (_IO_FILE *) INTUSE(_IO_list_all);
831   while (fp != NULL)
832     {
833       run_fp = fp;
834       if (do_lock)
835         _IO_flockfile (fp);
836
837       if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
838 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
839            || (_IO_vtable_offset (fp) == 0
840                && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
841                                     > fp->_wide_data->_IO_write_base))
842 #endif
843            )
844           && _IO_OVERFLOW (fp, EOF) == EOF)
845         result = EOF;
846
847       if (do_lock)
848         _IO_funlockfile (fp);
849       run_fp = NULL;
850
851       if (last_stamp != _IO_list_all_stamp)
852         {
853           /* Something was added to the list.  Start all over again.  */
854           fp = (_IO_FILE *) INTUSE(_IO_list_all);
855           last_stamp = _IO_list_all_stamp;
856         }
857       else
858         fp = fp->_chain;
859     }
860
861 #ifdef _IO_MTSAFE_IO
862   if (do_lock)
863     _IO_lock_unlock (list_all_lock);
864   _IO_cleanup_region_end (0);
865 #endif
866
867   return result;
868 }
869
870
871 int
872 _IO_flush_all ()
873 {
874   /* We want locking.  */
875   return _IO_flush_all_lockp (1);
876 }
877 INTDEF(_IO_flush_all)
878
879 void
880 _IO_flush_all_linebuffered ()
881 {
882   struct _IO_FILE *fp;
883   int last_stamp;
884
885 #ifdef _IO_MTSAFE_IO
886   _IO_cleanup_region_start_noarg (flush_cleanup);
887   _IO_lock_lock (list_all_lock);
888 #endif
889
890   last_stamp = _IO_list_all_stamp;
891   fp = (_IO_FILE *) INTUSE(_IO_list_all);
892   while (fp != NULL)
893     {
894       run_fp = fp;
895       _IO_flockfile (fp);
896
897       if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
898         _IO_OVERFLOW (fp, EOF);
899
900       _IO_funlockfile (fp);
901       run_fp = NULL;
902
903       if (last_stamp != _IO_list_all_stamp)
904         {
905           /* Something was added to the list.  Start all over again.  */
906           fp = (_IO_FILE *) INTUSE(_IO_list_all);
907           last_stamp = _IO_list_all_stamp;
908         }
909       else
910         fp = fp->_chain;
911     }
912
913 #ifdef _IO_MTSAFE_IO
914   _IO_lock_unlock (list_all_lock);
915   _IO_cleanup_region_end (0);
916 #endif
917 }
918 INTDEF(_IO_flush_all_linebuffered)
919 #ifdef _LIBC
920 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
921 #endif
922
923
924 /* The following is a bit tricky.  In general, we want to unbuffer the
925    streams so that all output which follows is seen.  If we are not
926    looking for memory leaks it does not make much sense to free the
927    actual buffer because this will happen anyway once the program
928    terminated.  If we do want to look for memory leaks we have to free
929    the buffers.  Whether something is freed is determined by the
930    function sin the libc_freeres section.  Those are called as part of
931    the atexit routine, just like _IO_cleanup.  The problem is we do
932    not know whether the freeres code is called first or _IO_cleanup.
933    if the former is the case, we set the DEALLOC_BUFFER variable to
934    true and _IO_unbuffer_write will take care of the rest.  If
935    _IO_unbuffer_write is called first we add the streams to a list
936    which the freeres function later can walk through.  */
937 static void _IO_unbuffer_write (void);
938
939 static bool dealloc_buffers;
940 static _IO_FILE *freeres_list;
941
942 static void
943 _IO_unbuffer_write (void)
944 {
945   struct _IO_FILE *fp;
946   for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
947     {
948       if (! (fp->_flags & _IO_UNBUFFERED)
949           && (! (fp->_flags & _IO_NO_WRITES)
950               || (fp->_flags & _IO_IS_APPENDING))
951           /* Iff stream is un-orientated, it wasn't used. */
952           && fp->_mode != 0)
953         {
954           int cnt;
955 #define MAXTRIES 2
956           for (cnt = 0; cnt < MAXTRIES; ++cnt)
957             if (_IO_lock_trylock (*fp->_lock) == 0)
958               break;
959             else
960               /* Give the other thread time to finish up its use of the
961                  stream.  */
962               __sched_yield ();
963
964           if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
965             {
966               fp->_flags |= _IO_USER_BUF;
967
968               fp->_freeres_list = freeres_list;
969               freeres_list = fp;
970               fp->_freeres_buf = fp->_IO_buf_base;
971               fp->_freeres_size = _IO_blen (fp);
972             }
973
974           _IO_SETBUF (fp, NULL, 0);
975
976           if (cnt < MAXTRIES)
977             _IO_lock_unlock (*fp->_lock);
978         }
979
980       /* Make sure that never again the wide char functions can be
981          used.  */
982       fp->_mode = -1;
983     }
984 }
985
986
987 libc_freeres_fn (buffer_free)
988 {
989   dealloc_buffers = true;
990
991   while (freeres_list != NULL)
992     {
993       FREE_BUF (freeres_list->_freeres_buf, freeres_list->_freeres_size);
994
995       freeres_list = freeres_list->_freeres_list;
996     }
997 }
998
999
1000 int
1001 _IO_cleanup ()
1002 {
1003   /* We do *not* want locking.  Some threads might use streams but
1004      that is their problem, we flush them underneath them.  */
1005   int result = _IO_flush_all_lockp (0);
1006
1007   /* We currently don't have a reliable mechanism for making sure that
1008      C++ static destructors are executed in the correct order.
1009      So it is possible that other static destructors might want to
1010      write to cout - and they're supposed to be able to do so.
1011
1012      The following will make the standard streambufs be unbuffered,
1013      which forces any output from late destructors to be written out. */
1014   _IO_unbuffer_write ();
1015
1016   return result;
1017 }
1018
1019
1020 void
1021 _IO_init_marker (marker, fp)
1022      struct _IO_marker *marker;
1023      _IO_FILE *fp;
1024 {
1025   marker->_sbuf = fp;
1026   if (_IO_in_put_mode (fp))
1027     INTUSE(_IO_switch_to_get_mode) (fp);
1028   if (_IO_in_backup (fp))
1029     marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
1030   else
1031     marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
1032
1033   /* Should perhaps sort the chain? */
1034   marker->_next = fp->_markers;
1035   fp->_markers = marker;
1036 }
1037
1038 void
1039 _IO_remove_marker (marker)
1040      struct _IO_marker *marker;
1041 {
1042   /* Unlink from sb's chain. */
1043   struct _IO_marker **ptr = &marker->_sbuf->_markers;
1044   for (; ; ptr = &(*ptr)->_next)
1045     {
1046       if (*ptr == NULL)
1047         break;
1048       else if (*ptr == marker)
1049         {
1050           *ptr = marker->_next;
1051           return;
1052         }
1053     }
1054 #if 0
1055     if _sbuf has a backup area that is no longer needed, should we delete
1056     it now, or wait until the next underflow?
1057 #endif
1058 }
1059
1060 #define BAD_DELTA EOF
1061
1062 int
1063 _IO_marker_difference (mark1, mark2)
1064      struct _IO_marker *mark1;
1065      struct _IO_marker *mark2;
1066 {
1067   return mark1->_pos - mark2->_pos;
1068 }
1069
1070 /* Return difference between MARK and current position of MARK's stream. */
1071 int
1072 _IO_marker_delta (mark)
1073      struct _IO_marker *mark;
1074 {
1075   int cur_pos;
1076   if (mark->_sbuf == NULL)
1077     return BAD_DELTA;
1078   if (_IO_in_backup (mark->_sbuf))
1079     cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1080   else
1081     cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1082   return mark->_pos - cur_pos;
1083 }
1084
1085 int
1086 _IO_seekmark (fp, mark, delta)
1087      _IO_FILE *fp;
1088      struct _IO_marker *mark;
1089      int delta;
1090 {
1091   if (mark->_sbuf != fp)
1092     return EOF;
1093  if (mark->_pos >= 0)
1094     {
1095       if (_IO_in_backup (fp))
1096         _IO_switch_to_main_get_area (fp);
1097       fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1098     }
1099   else
1100     {
1101       if (!_IO_in_backup (fp))
1102         _IO_switch_to_backup_area (fp);
1103       fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1104     }
1105   return 0;
1106 }
1107
1108 void
1109 _IO_unsave_markers (fp)
1110      _IO_FILE *fp;
1111 {
1112   struct _IO_marker *mark = fp->_markers;
1113   if (mark)
1114     {
1115 #ifdef TODO
1116       streampos offset = seekoff (0, ios::cur, ios::in);
1117       if (offset != EOF)
1118         {
1119           offset += eGptr () - Gbase ();
1120           for ( ; mark != NULL; mark = mark->_next)
1121             mark->set_streampos (mark->_pos + offset);
1122         }
1123     else
1124       {
1125         for ( ; mark != NULL; mark = mark->_next)
1126           mark->set_streampos (EOF);
1127       }
1128 #endif
1129       fp->_markers = 0;
1130     }
1131
1132   if (_IO_have_backup (fp))
1133     INTUSE(_IO_free_backup_area) (fp);
1134 }
1135 INTDEF(_IO_unsave_markers)
1136
1137 #if 0
1138 /* Seems not to be needed. --drepper */
1139 int
1140 _IO_nobackup_pbackfail (fp, c)
1141      _IO_FILE *fp;
1142      int c;
1143 {
1144   if (fp->_IO_read_ptr > fp->_IO_read_base)
1145         fp->_IO_read_ptr--;
1146   if (c != EOF && *fp->_IO_read_ptr != c)
1147       *fp->_IO_read_ptr = c;
1148   return (unsigned char) c;
1149 }
1150 #endif
1151
1152 int
1153 _IO_default_pbackfail (fp, c)
1154      _IO_FILE *fp;
1155      int c;
1156 {
1157   if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1158       && (unsigned char) fp->_IO_read_ptr[-1] == c)
1159     --fp->_IO_read_ptr;
1160   else
1161     {
1162       /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1163       if (!_IO_in_backup (fp))
1164         {
1165           /* We need to keep the invariant that the main get area
1166              logically follows the backup area.  */
1167           if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1168             {
1169               if (save_for_backup (fp, fp->_IO_read_ptr))
1170                 return EOF;
1171             }
1172           else if (!_IO_have_backup (fp))
1173             {
1174               /* No backup buffer: allocate one. */
1175               /* Use nshort buffer, if unused? (probably not)  FIXME */
1176               int backup_size = 128;
1177               char *bbuf = (char *) malloc (backup_size);
1178               if (bbuf == NULL)
1179                 return EOF;
1180               fp->_IO_save_base = bbuf;
1181               fp->_IO_save_end = fp->_IO_save_base + backup_size;
1182               fp->_IO_backup_base = fp->_IO_save_end;
1183             }
1184           fp->_IO_read_base = fp->_IO_read_ptr;
1185           _IO_switch_to_backup_area (fp);
1186         }
1187       else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1188         {
1189           /* Increase size of existing backup buffer. */
1190           _IO_size_t new_size;
1191           _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1192           char *new_buf;
1193           new_size = 2 * old_size;
1194           new_buf = (char *) malloc (new_size);
1195           if (new_buf == NULL)
1196             return EOF;
1197           memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1198                   old_size);
1199           free (fp->_IO_read_base);
1200           _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1201                     new_buf + new_size);
1202           fp->_IO_backup_base = fp->_IO_read_ptr;
1203         }
1204
1205       *--fp->_IO_read_ptr = c;
1206     }
1207   return (unsigned char) c;
1208 }
1209 INTDEF(_IO_default_pbackfail)
1210
1211 _IO_off64_t
1212 _IO_default_seek (fp, offset, dir)
1213      _IO_FILE *fp;
1214      _IO_off64_t offset;
1215      int dir;
1216 {
1217   return _IO_pos_BAD;
1218 }
1219
1220 int
1221 _IO_default_stat (fp, st)
1222      _IO_FILE *fp;
1223      void* st;
1224 {
1225   return EOF;
1226 }
1227
1228 _IO_ssize_t
1229 _IO_default_read (fp, data, n)
1230      _IO_FILE* fp;
1231      void *data;
1232      _IO_ssize_t n;
1233 {
1234   return -1;
1235 }
1236
1237 _IO_ssize_t
1238 _IO_default_write (fp, data, n)
1239      _IO_FILE *fp;
1240      const void *data;
1241      _IO_ssize_t n;
1242 {
1243   return 0;
1244 }
1245
1246 int
1247 _IO_default_showmanyc (fp)
1248      _IO_FILE *fp;
1249 {
1250   return -1;
1251 }
1252
1253 void
1254 _IO_default_imbue (fp, locale)
1255      _IO_FILE *fp;
1256      void *locale;
1257 {
1258 }
1259
1260 _IO_ITER
1261 _IO_iter_begin()
1262 {
1263   return (_IO_ITER) INTUSE(_IO_list_all);
1264 }
1265 libc_hidden_def (_IO_iter_begin)
1266
1267 _IO_ITER
1268 _IO_iter_end()
1269 {
1270   return NULL;
1271 }
1272 libc_hidden_def (_IO_iter_end)
1273
1274 _IO_ITER
1275 _IO_iter_next(iter)
1276     _IO_ITER iter;
1277 {
1278   return iter->_chain;
1279 }
1280 libc_hidden_def (_IO_iter_next)
1281
1282 _IO_FILE *
1283 _IO_iter_file(iter)
1284     _IO_ITER iter;
1285 {
1286   return iter;
1287 }
1288 libc_hidden_def (_IO_iter_file)
1289
1290 void
1291 _IO_list_lock()
1292 {
1293 #ifdef _IO_MTSAFE_IO
1294   _IO_lock_lock (list_all_lock);
1295 #endif
1296 }
1297 libc_hidden_def (_IO_list_lock)
1298
1299 void
1300 _IO_list_unlock()
1301 {
1302 #ifdef _IO_MTSAFE_IO
1303   _IO_lock_unlock (list_all_lock);
1304 #endif
1305 }
1306 libc_hidden_def (_IO_list_unlock)
1307
1308 void
1309 _IO_list_resetlock()
1310 {
1311 #ifdef _IO_MTSAFE_IO
1312   _IO_lock_init (list_all_lock);
1313 #endif
1314 }
1315 libc_hidden_def (_IO_list_resetlock)
1316
1317
1318 #ifdef TODO
1319 #if defined(linux)
1320 #define IO_CLEANUP ;
1321 #endif
1322
1323 #ifdef IO_CLEANUP
1324   IO_CLEANUP
1325 #else
1326 struct __io_defs {
1327     __io_defs() { }
1328     ~__io_defs() { _IO_cleanup (); }
1329 };
1330 __io_defs io_defs__;
1331 #endif
1332
1333 #endif /* TODO */
1334
1335 #ifdef text_set_element
1336 text_set_element(__libc_atexit, _IO_cleanup);
1337 #endif