* posix/execl.c: Fix last argument of memcpy. Reported by Brian
[glibc/pb-stable.git] / libio / genops.c
blobd786ebca577566c96943a31dddcafc48a292ee75
1 /* Copyright (C) 1993,1995,1997-1999,2000,2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
28 /* Generic or default I/O operations. */
30 #include "libioP.h"
31 #ifdef __STDC__
32 #include <stdlib.h>
33 #endif
34 #include <string.h>
36 #ifdef _IO_MTSAFE_IO
37 static _IO_lock_t list_all_lock = _IO_lock_initializer;
38 #endif
40 /* Used to signal modifications to the list of FILE decriptors. */
41 static int _IO_list_all_stamp;
44 static _IO_FILE *run_fp;
46 static void
47 flush_cleanup (void *not_used)
49 if (run_fp != NULL)
50 _IO_funlockfile (run_fp);
51 #ifdef _IO_MTSAFE_IO
52 _IO_lock_unlock (list_all_lock);
53 #endif
56 void
57 _IO_un_link (fp)
58 struct _IO_FILE_plus *fp;
60 if (fp->file._flags & _IO_LINKED)
62 struct _IO_FILE_plus **f;
63 #ifdef _IO_MTSAFE_IO
64 _IO_cleanup_region_start_noarg (flush_cleanup);
65 _IO_lock_lock (list_all_lock);
66 run_fp = (_IO_FILE *) fp;
67 _IO_flockfile ((_IO_FILE *) fp);
68 #endif
69 for (f = &_IO_list_all; *f; f = (struct _IO_FILE_plus **) &(*f)->file._chain)
71 if (*f == fp)
73 *f = (struct _IO_FILE_plus *) fp->file._chain;
74 ++_IO_list_all_stamp;
75 break;
78 fp->file._flags &= ~_IO_LINKED;
79 #ifdef _IO_MTSAFE_IO
80 _IO_funlockfile ((_IO_FILE *) fp);
81 run_fp = NULL;
82 _IO_lock_unlock (list_all_lock);
83 _IO_cleanup_region_end (0);
84 #endif
88 void
89 _IO_link_in (fp)
90 struct _IO_FILE_plus *fp;
92 if ((fp->file._flags & _IO_LINKED) == 0)
94 fp->file._flags |= _IO_LINKED;
95 #ifdef _IO_MTSAFE_IO
96 _IO_cleanup_region_start_noarg (flush_cleanup);
97 _IO_lock_lock (list_all_lock);
98 run_fp = (_IO_FILE *) fp;
99 _IO_flockfile ((_IO_FILE *) fp);
100 #endif
101 fp->file._chain = (_IO_FILE *) _IO_list_all;
102 _IO_list_all = fp;
103 ++_IO_list_all_stamp;
104 #ifdef _IO_MTSAFE_IO
105 _IO_funlockfile ((_IO_FILE *) fp);
106 run_fp = NULL;
107 _IO_lock_unlock (list_all_lock);
108 _IO_cleanup_region_end (0);
109 #endif
113 /* Return minimum _pos markers
114 Assumes the current get area is the main get area. */
115 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
117 _IO_ssize_t
118 _IO_least_marker (fp, end_p)
119 _IO_FILE *fp;
120 char *end_p;
122 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
123 struct _IO_marker *mark;
124 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
125 if (mark->_pos < least_so_far)
126 least_so_far = mark->_pos;
127 return least_so_far;
130 /* Switch current get area from backup buffer to (start of) main get area. */
132 void
133 _IO_switch_to_main_get_area (fp)
134 _IO_FILE *fp;
136 char *tmp;
137 fp->_flags &= ~_IO_IN_BACKUP;
138 /* Swap _IO_read_end and _IO_save_end. */
139 tmp = fp->_IO_read_end;
140 fp->_IO_read_end = fp->_IO_save_end;
141 fp->_IO_save_end= tmp;
142 /* Swap _IO_read_base and _IO_save_base. */
143 tmp = fp->_IO_read_base;
144 fp->_IO_read_base = fp->_IO_save_base;
145 fp->_IO_save_base = tmp;
146 /* Set _IO_read_ptr. */
147 fp->_IO_read_ptr = fp->_IO_read_base;
150 /* Switch current get area from main get area to (end of) backup area. */
152 void
153 _IO_switch_to_backup_area (fp)
154 _IO_FILE *fp;
156 char *tmp;
157 fp->_flags |= _IO_IN_BACKUP;
158 /* Swap _IO_read_end and _IO_save_end. */
159 tmp = fp->_IO_read_end;
160 fp->_IO_read_end = fp->_IO_save_end;
161 fp->_IO_save_end = tmp;
162 /* Swap _IO_read_base and _IO_save_base. */
163 tmp = fp->_IO_read_base;
164 fp->_IO_read_base = fp->_IO_save_base;
165 fp->_IO_save_base = tmp;
166 /* Set _IO_read_ptr. */
167 fp->_IO_read_ptr = fp->_IO_read_end;
171 _IO_switch_to_get_mode (fp)
172 _IO_FILE *fp;
174 if (fp->_IO_write_ptr > fp->_IO_write_base)
175 if (_IO_OVERFLOW (fp, EOF) == EOF)
176 return EOF;
177 if (_IO_in_backup (fp))
178 fp->_IO_read_base = fp->_IO_backup_base;
179 else
181 fp->_IO_read_base = fp->_IO_buf_base;
182 if (fp->_IO_write_ptr > fp->_IO_read_end)
183 fp->_IO_read_end = fp->_IO_write_ptr;
185 fp->_IO_read_ptr = fp->_IO_write_ptr;
187 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
189 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
190 return 0;
193 void
194 _IO_free_backup_area (fp)
195 _IO_FILE *fp;
197 if (_IO_in_backup (fp))
198 _IO_switch_to_main_get_area (fp); /* Just in case. */
199 free (fp->_IO_save_base);
200 fp->_IO_save_base = NULL;
201 fp->_IO_save_end = NULL;
202 fp->_IO_backup_base = NULL;
205 #if 0
207 _IO_switch_to_put_mode (fp)
208 _IO_FILE *fp;
210 fp->_IO_write_base = fp->_IO_read_ptr;
211 fp->_IO_write_ptr = fp->_IO_read_ptr;
212 /* Following is wrong if line- or un-buffered? */
213 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
214 ? fp->_IO_read_end : fp->_IO_buf_end);
216 fp->_IO_read_ptr = fp->_IO_read_end;
217 fp->_IO_read_base = fp->_IO_read_end;
219 fp->_flags |= _IO_CURRENTLY_PUTTING;
220 return 0;
222 #endif
225 __overflow (f, ch)
226 _IO_FILE *f;
227 int ch;
229 /* This is a single-byte stream. */
230 if (f->_mode == 0)
231 _IO_fwide (f, -1);
232 return _IO_OVERFLOW (f, ch);
235 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
236 #ifdef _LIBC
237 internal_function
238 #endif
241 static int
242 #ifdef _LIBC
243 internal_function
244 #endif
245 save_for_backup (fp, end_p)
246 _IO_FILE *fp;
247 char *end_p;
249 /* Append [_IO_read_base..end_p] to backup area. */
250 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
251 /* needed_size is how much space we need in the backup area. */
252 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
253 /* FIXME: Dubious arithmetic if pointers are NULL */
254 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
255 _IO_size_t avail; /* Extra space available for future expansion. */
256 _IO_ssize_t delta;
257 struct _IO_marker *mark;
258 if (needed_size > current_Bsize)
260 char *new_buffer;
261 avail = 100;
262 new_buffer = (char *) malloc (avail + needed_size);
263 if (new_buffer == NULL)
264 return EOF; /* FIXME */
265 if (least_mark < 0)
267 #ifdef _LIBC
268 __mempcpy (__mempcpy (new_buffer + avail,
269 fp->_IO_save_end + least_mark,
270 -least_mark),
271 fp->_IO_read_base,
272 end_p - fp->_IO_read_base);
273 #else
274 memcpy (new_buffer + avail,
275 fp->_IO_save_end + least_mark,
276 -least_mark);
277 memcpy (new_buffer + avail - least_mark,
278 fp->_IO_read_base,
279 end_p - fp->_IO_read_base);
280 #endif
282 else
283 memcpy (new_buffer + avail,
284 fp->_IO_read_base + least_mark,
285 needed_size);
286 if (fp->_IO_save_base)
287 free (fp->_IO_save_base);
288 fp->_IO_save_base = new_buffer;
289 fp->_IO_save_end = new_buffer + avail + needed_size;
291 else
293 avail = current_Bsize - needed_size;
294 if (least_mark < 0)
296 memmove (fp->_IO_save_base + avail,
297 fp->_IO_save_end + least_mark,
298 -least_mark);
299 memcpy (fp->_IO_save_base + avail - least_mark,
300 fp->_IO_read_base,
301 end_p - fp->_IO_read_base);
303 else if (needed_size > 0)
304 memcpy (fp->_IO_save_base + avail,
305 fp->_IO_read_base + least_mark,
306 needed_size);
308 fp->_IO_backup_base = fp->_IO_save_base + avail;
309 /* Adjust all the streammarkers. */
310 delta = end_p - fp->_IO_read_base;
311 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
312 mark->_pos -= delta;
313 return 0;
317 __underflow (fp)
318 _IO_FILE *fp;
320 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
321 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
322 return EOF;
323 #endif
325 if (fp->_mode == 0)
326 _IO_fwide (fp, -1);
327 if (_IO_in_put_mode (fp))
328 if (_IO_switch_to_get_mode (fp) == EOF)
329 return EOF;
330 if (fp->_IO_read_ptr < fp->_IO_read_end)
331 return *(unsigned char *) fp->_IO_read_ptr;
332 if (_IO_in_backup (fp))
334 _IO_switch_to_main_get_area (fp);
335 if (fp->_IO_read_ptr < fp->_IO_read_end)
336 return *(unsigned char *) fp->_IO_read_ptr;
338 if (_IO_have_markers (fp))
340 if (save_for_backup (fp, fp->_IO_read_end))
341 return EOF;
343 else if (_IO_have_backup (fp))
344 _IO_free_backup_area (fp);
345 return _IO_UNDERFLOW (fp);
349 __uflow (fp)
350 _IO_FILE *fp;
352 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
353 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
354 return EOF;
355 #endif
357 if (fp->_mode == 0)
358 _IO_fwide (fp, -11);
359 if (_IO_in_put_mode (fp))
360 if (_IO_switch_to_get_mode (fp) == EOF)
361 return EOF;
362 if (fp->_IO_read_ptr < fp->_IO_read_end)
363 return *(unsigned char *) fp->_IO_read_ptr++;
364 if (_IO_in_backup (fp))
366 _IO_switch_to_main_get_area (fp);
367 if (fp->_IO_read_ptr < fp->_IO_read_end)
368 return *(unsigned char *) fp->_IO_read_ptr++;
370 if (_IO_have_markers (fp))
372 if (save_for_backup (fp, fp->_IO_read_end))
373 return EOF;
375 else if (_IO_have_backup (fp))
376 _IO_free_backup_area (fp);
377 return _IO_UFLOW (fp);
380 void
381 _IO_setb (f, b, eb, a)
382 _IO_FILE *f;
383 char *b;
384 char *eb;
385 int a;
387 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
388 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
389 f->_IO_buf_base = b;
390 f->_IO_buf_end = eb;
391 if (a)
392 f->_flags &= ~_IO_USER_BUF;
393 else
394 f->_flags |= _IO_USER_BUF;
397 void
398 _IO_doallocbuf (fp)
399 _IO_FILE *fp;
401 if (fp->_IO_buf_base)
402 return;
403 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
404 if (_IO_DOALLOCATE (fp) != EOF)
405 return;
406 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
410 _IO_default_underflow (fp)
411 _IO_FILE *fp;
413 return EOF;
417 _IO_default_uflow (fp)
418 _IO_FILE *fp;
420 int ch = _IO_UNDERFLOW (fp);
421 if (ch == EOF)
422 return EOF;
423 return *(unsigned char *) fp->_IO_read_ptr++;
426 _IO_size_t
427 _IO_default_xsputn (f, data, n)
428 _IO_FILE *f;
429 const void *data;
430 _IO_size_t n;
432 const char *s = (char *) data;
433 _IO_size_t more = n;
434 if (more <= 0)
435 return 0;
436 for (;;)
438 /* Space available. */
439 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
440 if (count > 0)
442 if ((_IO_size_t) count > more)
443 count = more;
444 if (count > 20)
446 #ifdef _LIBC
447 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
448 #else
449 memcpy (f->_IO_write_ptr, s, count);
450 f->_IO_write_ptr += count;
451 #endif
452 s += count;
454 else if (count <= 0)
455 count = 0;
456 else
458 char *p = f->_IO_write_ptr;
459 _IO_ssize_t i;
460 for (i = count; --i >= 0; )
461 *p++ = *s++;
462 f->_IO_write_ptr = p;
464 more -= count;
466 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
467 break;
468 more--;
470 return n - more;
473 _IO_size_t
474 _IO_sgetn (fp, data, n)
475 _IO_FILE *fp;
476 void *data;
477 _IO_size_t n;
479 /* FIXME handle putback buffer here! */
480 return _IO_XSGETN (fp, data, n);
483 _IO_size_t
484 _IO_default_xsgetn (fp, data, n)
485 _IO_FILE *fp;
486 void *data;
487 _IO_size_t n;
489 _IO_size_t more = n;
490 char *s = (char*) data;
491 for (;;)
493 /* Data available. */
494 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
495 if (count > 0)
497 if ((_IO_size_t) count > more)
498 count = more;
499 if (count > 20)
501 #ifdef _LIBC
502 s = __mempcpy (s, fp->_IO_read_ptr, count);
503 #else
504 memcpy (s, fp->_IO_read_ptr, count);
505 s += count;
506 #endif
507 fp->_IO_read_ptr += count;
509 else if (count <= 0)
510 count = 0;
511 else
513 char *p = fp->_IO_read_ptr;
514 int i = (int) count;
515 while (--i >= 0)
516 *s++ = *p++;
517 fp->_IO_read_ptr = p;
519 more -= count;
521 if (more == 0 || __underflow (fp) == EOF)
522 break;
524 return n - more;
527 #if 0
528 /* Seems not to be needed. --drepper */
530 _IO_sync (fp)
531 _IO_FILE *fp;
533 return 0;
535 #endif
537 _IO_FILE *
538 _IO_default_setbuf (fp, p, len)
539 _IO_FILE *fp;
540 char *p;
541 _IO_ssize_t len;
543 if (_IO_SYNC (fp) == EOF)
544 return NULL;
545 if (p == NULL || len == 0)
547 fp->_flags |= _IO_UNBUFFERED;
548 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
550 else
552 fp->_flags &= ~_IO_UNBUFFERED;
553 _IO_setb (fp, p, p+len, 0);
555 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
556 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
557 return fp;
560 _IO_off64_t
561 _IO_default_seekpos (fp, pos, mode)
562 _IO_FILE *fp;
563 _IO_off64_t pos;
564 int mode;
566 return _IO_SEEKOFF (fp, pos, 0, mode);
570 _IO_default_doallocate (fp)
571 _IO_FILE *fp;
573 char *buf;
575 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
576 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
577 return 1;
580 void
581 _IO_init (fp, flags)
582 _IO_FILE *fp;
583 int flags;
585 _IO_no_init (fp, flags, -1, NULL, NULL);
588 void
589 _IO_no_init (fp, flags, orientation, wd, jmp)
590 _IO_FILE *fp;
591 int flags;
592 int orientation;
593 struct _IO_wide_data *wd;
594 struct _IO_jump_t *jmp;
596 fp->_flags = _IO_MAGIC|flags;
597 fp->_IO_buf_base = NULL;
598 fp->_IO_buf_end = NULL;
599 fp->_IO_read_base = NULL;
600 fp->_IO_read_ptr = NULL;
601 fp->_IO_read_end = NULL;
602 fp->_IO_write_base = NULL;
603 fp->_IO_write_ptr = NULL;
604 fp->_IO_write_end = NULL;
605 fp->_chain = NULL; /* Not necessary. */
607 fp->_IO_save_base = NULL;
608 fp->_IO_backup_base = NULL;
609 fp->_IO_save_end = NULL;
610 fp->_markers = NULL;
611 fp->_cur_column = 0;
612 #if _IO_JUMPS_OFFSET
613 fp->_vtable_offset = 0;
614 #endif
615 #ifdef _IO_MTSAFE_IO
616 if (fp->_lock != NULL)
617 _IO_lock_init (*fp->_lock);
618 #endif
619 fp->_mode = orientation;
620 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
621 if (orientation >= 0)
623 fp->_wide_data = wd;
624 fp->_wide_data->_IO_buf_base = NULL;
625 fp->_wide_data->_IO_buf_end = NULL;
626 fp->_wide_data->_IO_read_base = NULL;
627 fp->_wide_data->_IO_read_ptr = NULL;
628 fp->_wide_data->_IO_read_end = NULL;
629 fp->_wide_data->_IO_write_base = NULL;
630 fp->_wide_data->_IO_write_ptr = NULL;
631 fp->_wide_data->_IO_write_end = NULL;
632 fp->_wide_data->_IO_save_base = NULL;
633 fp->_wide_data->_IO_backup_base = NULL;
634 fp->_wide_data->_IO_save_end = NULL;
636 fp->_wide_data->_wide_vtable = jmp;
638 #endif
642 _IO_default_sync (fp)
643 _IO_FILE *fp;
645 return 0;
648 /* The way the C++ classes are mapped into the C functions in the
649 current implementation, this function can get called twice! */
651 void
652 _IO_default_finish (fp, dummy)
653 _IO_FILE *fp;
654 int dummy;
656 struct _IO_marker *mark;
657 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
659 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
660 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
663 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
664 mark->_sbuf = NULL;
666 if (fp->_IO_save_base)
668 free (fp->_IO_save_base);
669 fp->_IO_save_base = NULL;
672 #ifdef _IO_MTSAFE_IO
673 if (fp->_lock != NULL)
674 _IO_lock_fini (*fp->_lock);
675 #endif
677 _IO_un_link ((struct _IO_FILE_plus *) fp);
680 _IO_off64_t
681 _IO_default_seekoff (fp, offset, dir, mode)
682 _IO_FILE *fp;
683 _IO_off64_t offset;
684 int dir;
685 int mode;
687 return _IO_pos_BAD;
691 _IO_sputbackc (fp, c)
692 _IO_FILE *fp;
693 int c;
695 int result;
697 if (fp->_IO_read_ptr > fp->_IO_read_base
698 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
700 fp->_IO_read_ptr--;
701 result = (unsigned char) c;
703 else
704 result = _IO_PBACKFAIL (fp, c);
706 if (result != EOF)
707 fp->_flags &= ~_IO_EOF_SEEN;
709 return result;
713 _IO_sungetc (fp)
714 _IO_FILE *fp;
716 int result;
718 if (fp->_IO_read_ptr > fp->_IO_read_base)
720 fp->_IO_read_ptr--;
721 result = (unsigned char) *fp->_IO_read_ptr;
723 else
724 result = _IO_PBACKFAIL (fp, EOF);
726 if (result != EOF)
727 fp->_flags &= ~_IO_EOF_SEEN;
729 return result;
732 #if 0 /* Work in progress */
733 /* Seems not to be needed. */
734 #if 0
735 void
736 _IO_set_column (fp, c)
737 _IO_FILE *fp;
738 int c;
740 if (c == -1)
741 fp->_column = -1;
742 else
743 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
745 #else
747 _IO_set_column (fp, i)
748 _IO_FILE *fp;
749 int i;
751 fp->_cur_column = i + 1;
752 return 0;
754 #endif
755 #endif
758 unsigned
759 _IO_adjust_column (start, line, count)
760 unsigned start;
761 const char *line;
762 int count;
764 const char *ptr = line + count;
765 while (ptr > line)
766 if (*--ptr == '\n')
767 return line + count - ptr - 1;
768 return start + count;
771 #if 0
772 /* Seems not to be needed. --drepper */
774 _IO_get_column (fp)
775 _IO_FILE *fp;
777 if (fp->_cur_column)
778 return _IO_adjust_column (fp->_cur_column - 1,
779 fp->_IO_write_base,
780 fp->_IO_write_ptr - fp->_IO_write_base);
781 return -1;
783 #endif
787 _IO_flush_all ()
789 int result = 0;
790 struct _IO_FILE *fp;
791 int last_stamp;
793 #ifdef _IO_MTSAFE_IO
794 _IO_cleanup_region_start_noarg (flush_cleanup);
795 _IO_lock_lock (list_all_lock);
796 #endif
798 last_stamp = _IO_list_all_stamp;
799 fp = (_IO_FILE *) _IO_list_all;
800 while (fp != NULL)
802 run_fp = fp;
803 _IO_flockfile (fp);
805 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
806 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
807 || (fp->_vtable_offset == 0
808 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
809 > fp->_wide_data->_IO_write_base))
810 #endif
812 && _IO_OVERFLOW (fp, EOF) == EOF)
813 result = EOF;
815 _IO_funlockfile (fp);
816 run_fp = NULL;
818 if (last_stamp != _IO_list_all_stamp)
820 /* Something was added to the list. Start all over again. */
821 fp = (_IO_FILE *) _IO_list_all;
822 last_stamp = _IO_list_all_stamp;
824 else
825 fp = fp->_chain;
828 #ifdef _IO_MTSAFE_IO
829 _IO_lock_unlock (list_all_lock);
830 _IO_cleanup_region_end (0);
831 #endif
833 return result;
836 void
837 _IO_flush_all_linebuffered ()
839 struct _IO_FILE *fp;
840 int last_stamp;
842 #ifdef _IO_MTSAFE_IO
843 _IO_cleanup_region_start_noarg (flush_cleanup);
844 _IO_lock_lock (list_all_lock);
845 #endif
847 last_stamp = _IO_list_all_stamp;
848 fp = (_IO_FILE *) _IO_list_all;
849 while (fp != NULL)
851 run_fp = fp;
852 _IO_flockfile (fp);
854 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
855 _IO_OVERFLOW (fp, EOF);
857 _IO_funlockfile (fp);
858 run_fp = NULL;
860 if (last_stamp != _IO_list_all_stamp)
862 /* Something was added to the list. Start all over again. */
863 fp = (_IO_FILE *) _IO_list_all;
864 last_stamp = _IO_list_all_stamp;
866 else
867 fp = fp->_chain;
870 #ifdef _IO_MTSAFE_IO
871 _IO_lock_unlock (list_all_lock);
872 _IO_cleanup_region_end (0);
873 #endif
875 #ifdef _LIBC
876 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
877 #endif
879 static void _IO_unbuffer_write __P ((void));
881 static void
882 _IO_unbuffer_write ()
884 struct _IO_FILE *fp;
885 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
887 if (! (fp->_flags & _IO_UNBUFFERED)
888 && (! (fp->_flags & _IO_NO_WRITES)
889 || (fp->_flags & _IO_IS_APPENDING))
890 /* Iff stream is un-orientated, it wasn't used. */
891 && fp->_mode != 0)
892 _IO_SETBUF (fp, NULL, 0);
894 /* Make sure that never again the wide char functions can be
895 used. */
896 fp->_mode = -1;
901 _IO_cleanup ()
903 int result = _IO_flush_all ();
905 /* We currently don't have a reliable mechanism for making sure that
906 C++ static destructors are executed in the correct order.
907 So it is possible that other static destructors might want to
908 write to cout - and they're supposed to be able to do so.
910 The following will make the standard streambufs be unbuffered,
911 which forces any output from late destructors to be written out. */
912 _IO_unbuffer_write ();
914 return result;
918 void
919 _IO_init_marker (marker, fp)
920 struct _IO_marker *marker;
921 _IO_FILE *fp;
923 marker->_sbuf = fp;
924 if (_IO_in_put_mode (fp))
925 _IO_switch_to_get_mode (fp);
926 if (_IO_in_backup (fp))
927 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
928 else
929 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
931 /* Should perhaps sort the chain? */
932 marker->_next = fp->_markers;
933 fp->_markers = marker;
936 void
937 _IO_remove_marker (marker)
938 struct _IO_marker *marker;
940 /* Unlink from sb's chain. */
941 struct _IO_marker **ptr = &marker->_sbuf->_markers;
942 for (; ; ptr = &(*ptr)->_next)
944 if (*ptr == NULL)
945 break;
946 else if (*ptr == marker)
948 *ptr = marker->_next;
949 return;
952 #if 0
953 if _sbuf has a backup area that is no longer needed, should we delete
954 it now, or wait until the next underflow?
955 #endif
958 #define BAD_DELTA EOF
961 _IO_marker_difference (mark1, mark2)
962 struct _IO_marker *mark1;
963 struct _IO_marker *mark2;
965 return mark1->_pos - mark2->_pos;
968 /* Return difference between MARK and current position of MARK's stream. */
970 _IO_marker_delta (mark)
971 struct _IO_marker *mark;
973 int cur_pos;
974 if (mark->_sbuf == NULL)
975 return BAD_DELTA;
976 if (_IO_in_backup (mark->_sbuf))
977 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
978 else
979 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
980 return mark->_pos - cur_pos;
984 _IO_seekmark (fp, mark, delta)
985 _IO_FILE *fp;
986 struct _IO_marker *mark;
987 int delta;
989 if (mark->_sbuf != fp)
990 return EOF;
991 if (mark->_pos >= 0)
993 if (_IO_in_backup (fp))
994 _IO_switch_to_main_get_area (fp);
995 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
997 else
999 if (!_IO_in_backup (fp))
1000 _IO_switch_to_backup_area (fp);
1001 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1003 return 0;
1006 void
1007 _IO_unsave_markers (fp)
1008 _IO_FILE *fp;
1010 struct _IO_marker *mark = fp->_markers;
1011 if (mark)
1013 #ifdef TODO
1014 streampos offset = seekoff (0, ios::cur, ios::in);
1015 if (offset != EOF)
1017 offset += eGptr () - Gbase ();
1018 for ( ; mark != NULL; mark = mark->_next)
1019 mark->set_streampos (mark->_pos + offset);
1021 else
1023 for ( ; mark != NULL; mark = mark->_next)
1024 mark->set_streampos (EOF);
1026 #endif
1027 fp->_markers = 0;
1030 if (_IO_have_backup (fp))
1031 _IO_free_backup_area (fp);
1034 #if 0
1035 /* Seems not to be needed. --drepper */
1037 _IO_nobackup_pbackfail (fp, c)
1038 _IO_FILE *fp;
1039 int c;
1041 if (fp->_IO_read_ptr > fp->_IO_read_base)
1042 fp->_IO_read_ptr--;
1043 if (c != EOF && *fp->_IO_read_ptr != c)
1044 *fp->_IO_read_ptr = c;
1045 return (unsigned char) c;
1047 #endif
1050 _IO_default_pbackfail (fp, c)
1051 _IO_FILE *fp;
1052 int c;
1054 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1055 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1056 --fp->_IO_read_ptr;
1057 else
1059 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1060 if (!_IO_in_backup (fp))
1062 /* We need to keep the invariant that the main get area
1063 logically follows the backup area. */
1064 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1066 if (save_for_backup (fp, fp->_IO_read_ptr))
1067 return EOF;
1069 else if (!_IO_have_backup (fp))
1071 /* No backup buffer: allocate one. */
1072 /* Use nshort buffer, if unused? (probably not) FIXME */
1073 int backup_size = 128;
1074 char *bbuf = (char *) malloc (backup_size);
1075 if (bbuf == NULL)
1076 return EOF;
1077 fp->_IO_save_base = bbuf;
1078 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1079 fp->_IO_backup_base = fp->_IO_save_end;
1081 fp->_IO_read_base = fp->_IO_read_ptr;
1082 _IO_switch_to_backup_area (fp);
1084 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1086 /* Increase size of existing backup buffer. */
1087 _IO_size_t new_size;
1088 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1089 char *new_buf;
1090 new_size = 2 * old_size;
1091 new_buf = (char *) malloc (new_size);
1092 if (new_buf == NULL)
1093 return EOF;
1094 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1095 old_size);
1096 free (fp->_IO_read_base);
1097 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1098 new_buf + new_size);
1099 fp->_IO_backup_base = fp->_IO_read_ptr;
1102 *--fp->_IO_read_ptr = c;
1104 return (unsigned char) c;
1107 _IO_off64_t
1108 _IO_default_seek (fp, offset, dir)
1109 _IO_FILE *fp;
1110 _IO_off64_t offset;
1111 int dir;
1113 return _IO_pos_BAD;
1117 _IO_default_stat (fp, st)
1118 _IO_FILE *fp;
1119 void* st;
1121 return EOF;
1124 _IO_ssize_t
1125 _IO_default_read (fp, data, n)
1126 _IO_FILE* fp;
1127 void *data;
1128 _IO_ssize_t n;
1130 return -1;
1133 _IO_ssize_t
1134 _IO_default_write (fp, data, n)
1135 _IO_FILE *fp;
1136 const void *data;
1137 _IO_ssize_t n;
1139 return 0;
1143 _IO_default_showmanyc (fp)
1144 _IO_FILE *fp;
1146 return -1;
1149 void
1150 _IO_default_imbue (fp, locale)
1151 _IO_FILE *fp;
1152 void *locale;
1156 _IO_ITER
1157 _IO_iter_begin()
1159 return (_IO_ITER) _IO_list_all;
1162 _IO_ITER
1163 _IO_iter_end()
1165 return NULL;
1168 _IO_ITER
1169 _IO_iter_next(iter)
1170 _IO_ITER iter;
1172 return iter->_chain;
1175 _IO_FILE *
1176 _IO_iter_file(iter)
1177 _IO_ITER iter;
1179 return iter;
1182 void
1183 _IO_list_lock()
1185 #ifdef _IO_MTSAFE_IO
1186 _IO_lock_lock (list_all_lock);
1187 #endif
1190 void
1191 _IO_list_unlock()
1193 #ifdef _IO_MTSAFE_IO
1194 _IO_lock_unlock (list_all_lock);
1195 #endif
1198 void
1199 _IO_list_resetlock()
1201 #ifdef _IO_MTSAFE_IO
1202 _IO_lock_init (list_all_lock);
1203 #endif
1207 #ifdef TODO
1208 #if defined(linux)
1209 #define IO_CLEANUP ;
1210 #endif
1212 #ifdef IO_CLEANUP
1213 IO_CLEANUP
1214 #else
1215 struct __io_defs {
1216 __io_defs() { }
1217 ~__io_defs() { _IO_cleanup (); }
1219 __io_defs io_defs__;
1220 #endif
1222 #endif /* TODO */
1224 #ifdef weak_alias
1225 weak_alias (_IO_cleanup, _cleanup)
1226 #endif
1228 #ifdef text_set_element
1229 text_set_element(__libc_atexit, _cleanup);
1230 #endif