* libio/genops.c (_IO_unbuffer_write): Don't always free the
[glibc.git] / libio / genops.c
blob3deb044a084ecc371f60f4318b92671e32706cc3
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.
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.
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.
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.
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. */
29 /* Generic or default I/O operations. */
31 #include "libioP.h"
32 #ifdef __STDC__
33 #include <stdlib.h>
34 #endif
35 #include <string.h>
37 #ifdef _IO_MTSAFE_IO
38 static _IO_lock_t list_all_lock = _IO_lock_initializer;
39 #endif
41 /* Used to signal modifications to the list of FILE decriptors. */
42 static int _IO_list_all_stamp;
45 static _IO_FILE *run_fp;
47 static void
48 flush_cleanup (void *not_used)
50 if (run_fp != NULL)
51 _IO_funlockfile (run_fp);
52 #ifdef _IO_MTSAFE_IO
53 _IO_lock_unlock (list_all_lock);
54 #endif
57 void
58 _IO_un_link (fp)
59 struct _IO_FILE_plus *fp;
61 if (fp->file._flags & _IO_LINKED)
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)
73 if (*f == fp)
75 *f = (struct _IO_FILE_plus *) fp->file._chain;
76 ++_IO_list_all_stamp;
77 break;
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
89 INTDEF(_IO_un_link)
91 void
92 _IO_link_in (fp)
93 struct _IO_FILE_plus *fp;
95 if ((fp->file._flags & _IO_LINKED) == 0)
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
115 INTDEF(_IO_link_in)
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);
121 _IO_ssize_t
122 _IO_least_marker (fp, end_p)
123 _IO_FILE *fp;
124 char *end_p;
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;
134 /* Switch current get area from backup buffer to (start of) main get area. */
136 void
137 _IO_switch_to_main_get_area (fp)
138 _IO_FILE *fp;
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;
154 /* Switch current get area from main get area to (end of) backup area. */
156 void
157 _IO_switch_to_backup_area (fp)
158 _IO_FILE *fp;
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;
175 _IO_switch_to_get_mode (fp)
176 _IO_FILE *fp;
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
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;
189 fp->_IO_read_ptr = fp->_IO_write_ptr;
191 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
193 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
194 return 0;
196 INTDEF(_IO_switch_to_get_mode)
198 void
199 _IO_free_backup_area (fp)
200 _IO_FILE *fp;
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;
209 INTDEF(_IO_free_backup_area)
211 #if 0
213 _IO_switch_to_put_mode (fp)
214 _IO_FILE *fp;
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);
222 fp->_IO_read_ptr = fp->_IO_read_end;
223 fp->_IO_read_base = fp->_IO_read_end;
225 fp->_flags |= _IO_CURRENTLY_PUTTING;
226 return 0;
228 #endif
231 __overflow (f, ch)
232 _IO_FILE *f;
233 int ch;
235 /* This is a single-byte stream. */
236 if (f->_mode == 0)
237 _IO_fwide (f, -1);
238 return _IO_OVERFLOW (f, ch);
240 libc_hidden_def (__overflow)
242 static int save_for_backup (_IO_FILE *fp, char *end_p)
243 #ifdef _LIBC
244 internal_function
245 #endif
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;
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)
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)
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
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;
298 else
300 avail = current_Bsize - needed_size;
301 if (least_mark < 0)
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);
310 else if (needed_size > 0)
311 memcpy (fp->_IO_save_base + avail,
312 fp->_IO_read_base + least_mark,
313 needed_size);
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;
324 __underflow (fp)
325 _IO_FILE *fp;
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
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))
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;
345 if (_IO_have_markers (fp))
347 if (save_for_backup (fp, fp->_IO_read_end))
348 return EOF;
350 else if (_IO_have_backup (fp))
351 INTUSE(_IO_free_backup_area) (fp);
352 return _IO_UNDERFLOW (fp);
354 libc_hidden_def (__underflow)
357 __uflow (fp)
358 _IO_FILE *fp;
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
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))
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++;
378 if (_IO_have_markers (fp))
380 if (save_for_backup (fp, fp->_IO_read_end))
381 return EOF;
383 else if (_IO_have_backup (fp))
384 INTUSE(_IO_free_backup_area) (fp);
385 return _IO_UFLOW (fp);
387 libc_hidden_def (__uflow)
389 void
390 _IO_setb (f, b, eb, a)
391 _IO_FILE *f;
392 char *b;
393 char *eb;
394 int a;
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;
405 INTDEF(_IO_setb)
407 void
408 _IO_doallocbuf (fp)
409 _IO_FILE *fp;
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);
418 INTDEF(_IO_doallocbuf)
421 _IO_default_underflow (fp)
422 _IO_FILE *fp;
424 return EOF;
428 _IO_default_uflow (fp)
429 _IO_FILE *fp;
431 int ch = _IO_UNDERFLOW (fp);
432 if (ch == EOF)
433 return EOF;
434 return *(unsigned char *) fp->_IO_read_ptr++;
436 INTDEF(_IO_default_uflow)
438 _IO_size_t
439 _IO_default_xsputn (f, data, n)
440 _IO_FILE *f;
441 const void *data;
442 _IO_size_t n;
444 const char *s = (char *) data;
445 _IO_size_t more = n;
446 if (more <= 0)
447 return 0;
448 for (;;)
450 /* Space available. */
451 if (f->_IO_write_ptr < f->_IO_write_end)
453 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
454 if (count > more)
455 count = more;
456 if (count > 20)
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;
466 else if (count)
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;
474 more -= count;
476 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
477 break;
478 more--;
480 return n - more;
482 INTDEF(_IO_default_xsputn)
484 _IO_size_t
485 _IO_sgetn (fp, data, n)
486 _IO_FILE *fp;
487 void *data;
488 _IO_size_t n;
490 /* FIXME handle putback buffer here! */
491 return _IO_XSGETN (fp, data, n);
493 INTDEF(_IO_sgetn)
495 _IO_size_t
496 _IO_default_xsgetn (fp, data, n)
497 _IO_FILE *fp;
498 void *data;
499 _IO_size_t n;
501 _IO_size_t more = n;
502 char *s = (char*) data;
503 for (;;)
505 /* Data available. */
506 if (fp->_IO_read_ptr < fp->_IO_read_end)
508 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
509 if (count > more)
510 count = more;
511 if (count > 20)
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;
521 else if (count)
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;
529 more -= count;
531 if (more == 0 || __underflow (fp) == EOF)
532 break;
534 return n - more;
536 INTDEF(_IO_default_xsgetn)
538 #if 0
539 /* Seems not to be needed. --drepper */
541 _IO_sync (fp)
542 _IO_FILE *fp;
544 return 0;
546 #endif
548 _IO_FILE *
549 _IO_default_setbuf (fp, p, len)
550 _IO_FILE *fp;
551 char *p;
552 _IO_ssize_t len;
554 if (_IO_SYNC (fp) == EOF)
555 return NULL;
556 if (p == NULL || len == 0)
558 fp->_flags |= _IO_UNBUFFERED;
559 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
561 else
563 fp->_flags &= ~_IO_UNBUFFERED;
564 INTUSE(_IO_setb) (fp, p, p+len, 0);
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;
571 _IO_off64_t
572 _IO_default_seekpos (fp, pos, mode)
573 _IO_FILE *fp;
574 _IO_off64_t pos;
575 int mode;
577 return _IO_SEEKOFF (fp, pos, 0, mode);
581 _IO_default_doallocate (fp)
582 _IO_FILE *fp;
584 char *buf;
586 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
587 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
588 return 1;
590 INTDEF(_IO_default_doallocate)
592 void
593 _IO_init (fp, flags)
594 _IO_FILE *fp;
595 int flags;
597 _IO_no_init (fp, flags, -1, NULL, NULL);
599 INTDEF(_IO_init)
601 void
602 _IO_old_init (fp, flags)
603 _IO_FILE *fp;
604 int flags;
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. */
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
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;
640 _IO_old_init (fp, flags);
641 fp->_mode = orientation;
642 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
643 if (orientation >= 0)
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;
658 fp->_wide_data->_wide_vtable = jmp;
660 #endif
661 fp->_freeres_list = NULL;
665 _IO_default_sync (fp)
666 _IO_FILE *fp;
668 return 0;
671 /* The way the C++ classes are mapped into the C functions in the
672 current implementation, this function can get called twice! */
674 void
675 _IO_default_finish (fp, dummy)
676 _IO_FILE *fp;
677 int dummy;
679 struct _IO_marker *mark;
680 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
682 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
683 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
686 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
687 mark->_sbuf = NULL;
689 if (fp->_IO_save_base)
691 free (fp->_IO_save_base);
692 fp->_IO_save_base = NULL;
695 #ifdef _IO_MTSAFE_IO
696 if (fp->_lock != NULL)
697 _IO_lock_fini (*fp->_lock);
698 #endif
700 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
702 INTDEF(_IO_default_finish)
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;
711 return _IO_pos_BAD;
715 _IO_sputbackc (fp, c)
716 _IO_FILE *fp;
717 int c;
719 int result;
721 if (fp->_IO_read_ptr > fp->_IO_read_base
722 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
724 fp->_IO_read_ptr--;
725 result = (unsigned char) c;
727 else
728 result = _IO_PBACKFAIL (fp, c);
730 if (result != EOF)
731 fp->_flags &= ~_IO_EOF_SEEN;
733 return result;
735 INTDEF(_IO_sputbackc)
738 _IO_sungetc (fp)
739 _IO_FILE *fp;
741 int result;
743 if (fp->_IO_read_ptr > fp->_IO_read_base)
745 fp->_IO_read_ptr--;
746 result = (unsigned char) *fp->_IO_read_ptr;
748 else
749 result = _IO_PBACKFAIL (fp, EOF);
751 if (result != EOF)
752 fp->_flags &= ~_IO_EOF_SEEN;
754 return result;
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;
765 if (c == -1)
766 fp->_column = -1;
767 else
768 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
770 #else
772 _IO_set_column (fp, i)
773 _IO_FILE *fp;
774 int i;
776 fp->_cur_column = i + 1;
777 return 0;
779 #endif
780 #endif
783 unsigned
784 _IO_adjust_column (start, line, count)
785 unsigned start;
786 const char *line;
787 int count;
789 const char *ptr = line + count;
790 while (ptr > line)
791 if (*--ptr == '\n')
792 return line + count - ptr - 1;
793 return start + count;
795 INTDEF(_IO_adjust_column)
797 #if 0
798 /* Seems not to be needed. --drepper */
800 _IO_get_column (fp)
801 _IO_FILE *fp;
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;
809 #endif
813 _IO_flush_all_lockp (int do_lock)
815 int result = 0;
816 struct _IO_FILE *fp;
817 int last_stamp;
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
825 last_stamp = _IO_list_all_stamp;
826 fp = (_IO_FILE *) INTUSE(_IO_list_all);
827 while (fp != NULL)
829 run_fp = fp;
830 if (do_lock)
831 _IO_flockfile (fp);
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
840 && _IO_OVERFLOW (fp, EOF) == EOF)
841 result = EOF;
843 if (do_lock)
844 _IO_funlockfile (fp);
845 run_fp = NULL;
847 if (last_stamp != _IO_list_all_stamp)
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;
853 else
854 fp = fp->_chain;
857 #ifdef _IO_MTSAFE_IO
858 if (do_lock)
859 _IO_lock_unlock (list_all_lock);
860 _IO_cleanup_region_end (0);
861 #endif
863 return result;
868 _IO_flush_all ()
870 /* We want locking. */
871 return _IO_flush_all_lockp (1);
873 INTDEF(_IO_flush_all)
875 void
876 _IO_flush_all_linebuffered ()
878 struct _IO_FILE *fp;
879 int last_stamp;
881 #ifdef _IO_MTSAFE_IO
882 _IO_cleanup_region_start_noarg (flush_cleanup);
883 _IO_lock_lock (list_all_lock);
884 #endif
886 last_stamp = _IO_list_all_stamp;
887 fp = (_IO_FILE *) INTUSE(_IO_list_all);
888 while (fp != NULL)
890 run_fp = fp;
891 _IO_flockfile (fp);
893 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
894 _IO_OVERFLOW (fp, EOF);
896 _IO_funlockfile (fp);
897 run_fp = NULL;
899 if (last_stamp != _IO_list_all_stamp)
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;
905 else
906 fp = fp->_chain;
909 #ifdef _IO_MTSAFE_IO
910 _IO_lock_unlock (list_all_lock);
911 _IO_cleanup_region_end (0);
912 #endif
914 INTDEF(_IO_flush_all_linebuffered)
915 #ifdef _LIBC
916 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
917 #endif
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);
935 static bool dealloc_buffers;
936 static _IO_FILE *freeres_list;
938 static void
939 _IO_unbuffer_write (void)
941 struct _IO_FILE *fp;
942 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
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)
950 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
952 fp->_flags |= _IO_USER_BUF;
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);
960 _IO_SETBUF (fp, NULL, 0);
963 /* Make sure that never again the wide char functions can be
964 used. */
965 fp->_mode = -1;
970 libc_freeres_fn (buffer_free)
972 dealloc_buffers = true;
974 while (freeres_list != NULL)
976 FREE_BUF (freeres_list->_freeres_buf, freeres_list->_freeres_size);
978 freeres_list = freeres_list->_freeres_list;
984 _IO_cleanup ()
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);
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.
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 ();
999 return result;
1003 void
1004 _IO_init_marker (marker, fp)
1005 struct _IO_marker *marker;
1006 _IO_FILE *fp;
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;
1016 /* Should perhaps sort the chain? */
1017 marker->_next = fp->_markers;
1018 fp->_markers = marker;
1021 void
1022 _IO_remove_marker (marker)
1023 struct _IO_marker *marker;
1025 /* Unlink from sb's chain. */
1026 struct _IO_marker **ptr = &marker->_sbuf->_markers;
1027 for (; ; ptr = &(*ptr)->_next)
1029 if (*ptr == NULL)
1030 break;
1031 else if (*ptr == marker)
1033 *ptr = marker->_next;
1034 return;
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
1043 #define BAD_DELTA EOF
1046 _IO_marker_difference (mark1, mark2)
1047 struct _IO_marker *mark1;
1048 struct _IO_marker *mark2;
1050 return mark1->_pos - mark2->_pos;
1053 /* Return difference between MARK and current position of MARK's stream. */
1055 _IO_marker_delta (mark)
1056 struct _IO_marker *mark;
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;
1069 _IO_seekmark (fp, mark, delta)
1070 _IO_FILE *fp;
1071 struct _IO_marker *mark;
1072 int delta;
1074 if (mark->_sbuf != fp)
1075 return EOF;
1076 if (mark->_pos >= 0)
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;
1082 else
1084 if (!_IO_in_backup (fp))
1085 _IO_switch_to_backup_area (fp);
1086 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1088 return 0;
1091 void
1092 _IO_unsave_markers (fp)
1093 _IO_FILE *fp;
1095 struct _IO_marker *mark = fp->_markers;
1096 if (mark)
1098 #ifdef TODO
1099 streampos offset = seekoff (0, ios::cur, ios::in);
1100 if (offset != EOF)
1102 offset += eGptr () - Gbase ();
1103 for ( ; mark != NULL; mark = mark->_next)
1104 mark->set_streampos (mark->_pos + offset);
1106 else
1108 for ( ; mark != NULL; mark = mark->_next)
1109 mark->set_streampos (EOF);
1111 #endif
1112 fp->_markers = 0;
1115 if (_IO_have_backup (fp))
1116 INTUSE(_IO_free_backup_area) (fp);
1118 INTDEF(_IO_unsave_markers)
1120 #if 0
1121 /* Seems not to be needed. --drepper */
1123 _IO_nobackup_pbackfail (fp, c)
1124 _IO_FILE *fp;
1125 int c;
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;
1133 #endif
1136 _IO_default_pbackfail (fp, c)
1137 _IO_FILE *fp;
1138 int c;
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
1145 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1146 if (!_IO_in_backup (fp))
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))
1152 if (save_for_backup (fp, fp->_IO_read_ptr))
1153 return EOF;
1155 else if (!_IO_have_backup (fp))
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;
1167 fp->_IO_read_base = fp->_IO_read_ptr;
1168 _IO_switch_to_backup_area (fp);
1170 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
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;
1188 *--fp->_IO_read_ptr = c;
1190 return (unsigned char) c;
1192 INTDEF(_IO_default_pbackfail)
1194 _IO_off64_t
1195 _IO_default_seek (fp, offset, dir)
1196 _IO_FILE *fp;
1197 _IO_off64_t offset;
1198 int dir;
1200 return _IO_pos_BAD;
1204 _IO_default_stat (fp, st)
1205 _IO_FILE *fp;
1206 void* st;
1208 return EOF;
1211 _IO_ssize_t
1212 _IO_default_read (fp, data, n)
1213 _IO_FILE* fp;
1214 void *data;
1215 _IO_ssize_t n;
1217 return -1;
1220 _IO_ssize_t
1221 _IO_default_write (fp, data, n)
1222 _IO_FILE *fp;
1223 const void *data;
1224 _IO_ssize_t n;
1226 return 0;
1230 _IO_default_showmanyc (fp)
1231 _IO_FILE *fp;
1233 return -1;
1236 void
1237 _IO_default_imbue (fp, locale)
1238 _IO_FILE *fp;
1239 void *locale;
1243 _IO_ITER
1244 _IO_iter_begin()
1246 return (_IO_ITER) INTUSE(_IO_list_all);
1248 libc_hidden_def (_IO_iter_begin)
1250 _IO_ITER
1251 _IO_iter_end()
1253 return NULL;
1255 libc_hidden_def (_IO_iter_end)
1257 _IO_ITER
1258 _IO_iter_next(iter)
1259 _IO_ITER iter;
1261 return iter->_chain;
1263 libc_hidden_def (_IO_iter_next)
1265 _IO_FILE *
1266 _IO_iter_file(iter)
1267 _IO_ITER iter;
1269 return iter;
1271 libc_hidden_def (_IO_iter_file)
1273 void
1274 _IO_list_lock()
1276 #ifdef _IO_MTSAFE_IO
1277 _IO_lock_lock (list_all_lock);
1278 #endif
1280 libc_hidden_def (_IO_list_lock)
1282 void
1283 _IO_list_unlock()
1285 #ifdef _IO_MTSAFE_IO
1286 _IO_lock_unlock (list_all_lock);
1287 #endif
1289 libc_hidden_def (_IO_list_unlock)
1291 void
1292 _IO_list_resetlock()
1294 #ifdef _IO_MTSAFE_IO
1295 _IO_lock_init (list_all_lock);
1296 #endif
1298 libc_hidden_def (_IO_list_resetlock)
1301 #ifdef TODO
1302 #if defined(linux)
1303 #define IO_CLEANUP ;
1304 #endif
1306 #ifdef IO_CLEANUP
1307 IO_CLEANUP
1308 #else
1309 struct __io_defs {
1310 __io_defs() { }
1311 ~__io_defs() { _IO_cleanup (); }
1313 __io_defs io_defs__;
1314 #endif
1316 #endif /* TODO */
1318 #ifdef text_set_element
1319 text_set_element(__libc_atexit, _IO_cleanup);
1320 #endif