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