* sysdeps/unix/sysv/linux/opensock.c: Include <string.h>.
[glibc.git] / libio / genops.c
blob2398cff684476052f7b9f4f0addf731362c01e87
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_lockp (int do_lock)
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 if (do_lock)
796 _IO_lock_lock (list_all_lock);
797 #endif
799 last_stamp = _IO_list_all_stamp;
800 fp = (_IO_FILE *) _IO_list_all;
801 while (fp != NULL)
803 run_fp = fp;
804 if (do_lock)
805 _IO_flockfile (fp);
807 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
808 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
809 || (fp->_vtable_offset == 0
810 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
811 > fp->_wide_data->_IO_write_base))
812 #endif
814 && _IO_OVERFLOW (fp, EOF) == EOF)
815 result = EOF;
817 if (do_lock)
818 _IO_funlockfile (fp);
819 run_fp = NULL;
821 if (last_stamp != _IO_list_all_stamp)
823 /* Something was added to the list. Start all over again. */
824 fp = (_IO_FILE *) _IO_list_all;
825 last_stamp = _IO_list_all_stamp;
827 else
828 fp = fp->_chain;
831 #ifdef _IO_MTSAFE_IO
832 if (do_lock)
833 _IO_lock_unlock (list_all_lock);
834 _IO_cleanup_region_end (0);
835 #endif
837 return result;
842 _IO_flush_all ()
844 /* We want locking. */
845 return _IO_flush_all_lockp (1);
848 void
849 _IO_flush_all_linebuffered ()
851 struct _IO_FILE *fp;
852 int last_stamp;
854 #ifdef _IO_MTSAFE_IO
855 _IO_cleanup_region_start_noarg (flush_cleanup);
856 _IO_lock_lock (list_all_lock);
857 #endif
859 last_stamp = _IO_list_all_stamp;
860 fp = (_IO_FILE *) _IO_list_all;
861 while (fp != NULL)
863 run_fp = fp;
864 _IO_flockfile (fp);
866 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
867 _IO_OVERFLOW (fp, EOF);
869 _IO_funlockfile (fp);
870 run_fp = NULL;
872 if (last_stamp != _IO_list_all_stamp)
874 /* Something was added to the list. Start all over again. */
875 fp = (_IO_FILE *) _IO_list_all;
876 last_stamp = _IO_list_all_stamp;
878 else
879 fp = fp->_chain;
882 #ifdef _IO_MTSAFE_IO
883 _IO_lock_unlock (list_all_lock);
884 _IO_cleanup_region_end (0);
885 #endif
887 #ifdef _LIBC
888 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
889 #endif
891 static void _IO_unbuffer_write __P ((void));
893 static void
894 _IO_unbuffer_write ()
896 struct _IO_FILE *fp;
897 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
899 if (! (fp->_flags & _IO_UNBUFFERED)
900 && (! (fp->_flags & _IO_NO_WRITES)
901 || (fp->_flags & _IO_IS_APPENDING))
902 /* Iff stream is un-orientated, it wasn't used. */
903 && fp->_mode != 0)
904 _IO_SETBUF (fp, NULL, 0);
906 /* Make sure that never again the wide char functions can be
907 used. */
908 fp->_mode = -1;
913 _IO_cleanup ()
915 int result = _IO_flush_all ();
917 /* We currently don't have a reliable mechanism for making sure that
918 C++ static destructors are executed in the correct order.
919 So it is possible that other static destructors might want to
920 write to cout - and they're supposed to be able to do so.
922 The following will make the standard streambufs be unbuffered,
923 which forces any output from late destructors to be written out. */
924 _IO_unbuffer_write ();
926 return result;
930 void
931 _IO_init_marker (marker, fp)
932 struct _IO_marker *marker;
933 _IO_FILE *fp;
935 marker->_sbuf = fp;
936 if (_IO_in_put_mode (fp))
937 _IO_switch_to_get_mode (fp);
938 if (_IO_in_backup (fp))
939 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
940 else
941 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
943 /* Should perhaps sort the chain? */
944 marker->_next = fp->_markers;
945 fp->_markers = marker;
948 void
949 _IO_remove_marker (marker)
950 struct _IO_marker *marker;
952 /* Unlink from sb's chain. */
953 struct _IO_marker **ptr = &marker->_sbuf->_markers;
954 for (; ; ptr = &(*ptr)->_next)
956 if (*ptr == NULL)
957 break;
958 else if (*ptr == marker)
960 *ptr = marker->_next;
961 return;
964 #if 0
965 if _sbuf has a backup area that is no longer needed, should we delete
966 it now, or wait until the next underflow?
967 #endif
970 #define BAD_DELTA EOF
973 _IO_marker_difference (mark1, mark2)
974 struct _IO_marker *mark1;
975 struct _IO_marker *mark2;
977 return mark1->_pos - mark2->_pos;
980 /* Return difference between MARK and current position of MARK's stream. */
982 _IO_marker_delta (mark)
983 struct _IO_marker *mark;
985 int cur_pos;
986 if (mark->_sbuf == NULL)
987 return BAD_DELTA;
988 if (_IO_in_backup (mark->_sbuf))
989 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
990 else
991 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
992 return mark->_pos - cur_pos;
996 _IO_seekmark (fp, mark, delta)
997 _IO_FILE *fp;
998 struct _IO_marker *mark;
999 int delta;
1001 if (mark->_sbuf != fp)
1002 return EOF;
1003 if (mark->_pos >= 0)
1005 if (_IO_in_backup (fp))
1006 _IO_switch_to_main_get_area (fp);
1007 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1009 else
1011 if (!_IO_in_backup (fp))
1012 _IO_switch_to_backup_area (fp);
1013 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1015 return 0;
1018 void
1019 _IO_unsave_markers (fp)
1020 _IO_FILE *fp;
1022 struct _IO_marker *mark = fp->_markers;
1023 if (mark)
1025 #ifdef TODO
1026 streampos offset = seekoff (0, ios::cur, ios::in);
1027 if (offset != EOF)
1029 offset += eGptr () - Gbase ();
1030 for ( ; mark != NULL; mark = mark->_next)
1031 mark->set_streampos (mark->_pos + offset);
1033 else
1035 for ( ; mark != NULL; mark = mark->_next)
1036 mark->set_streampos (EOF);
1038 #endif
1039 fp->_markers = 0;
1042 if (_IO_have_backup (fp))
1043 _IO_free_backup_area (fp);
1046 #if 0
1047 /* Seems not to be needed. --drepper */
1049 _IO_nobackup_pbackfail (fp, c)
1050 _IO_FILE *fp;
1051 int c;
1053 if (fp->_IO_read_ptr > fp->_IO_read_base)
1054 fp->_IO_read_ptr--;
1055 if (c != EOF && *fp->_IO_read_ptr != c)
1056 *fp->_IO_read_ptr = c;
1057 return (unsigned char) c;
1059 #endif
1062 _IO_default_pbackfail (fp, c)
1063 _IO_FILE *fp;
1064 int c;
1066 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1067 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1068 --fp->_IO_read_ptr;
1069 else
1071 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1072 if (!_IO_in_backup (fp))
1074 /* We need to keep the invariant that the main get area
1075 logically follows the backup area. */
1076 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1078 if (save_for_backup (fp, fp->_IO_read_ptr))
1079 return EOF;
1081 else if (!_IO_have_backup (fp))
1083 /* No backup buffer: allocate one. */
1084 /* Use nshort buffer, if unused? (probably not) FIXME */
1085 int backup_size = 128;
1086 char *bbuf = (char *) malloc (backup_size);
1087 if (bbuf == NULL)
1088 return EOF;
1089 fp->_IO_save_base = bbuf;
1090 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1091 fp->_IO_backup_base = fp->_IO_save_end;
1093 fp->_IO_read_base = fp->_IO_read_ptr;
1094 _IO_switch_to_backup_area (fp);
1096 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1098 /* Increase size of existing backup buffer. */
1099 _IO_size_t new_size;
1100 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1101 char *new_buf;
1102 new_size = 2 * old_size;
1103 new_buf = (char *) malloc (new_size);
1104 if (new_buf == NULL)
1105 return EOF;
1106 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1107 old_size);
1108 free (fp->_IO_read_base);
1109 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1110 new_buf + new_size);
1111 fp->_IO_backup_base = fp->_IO_read_ptr;
1114 *--fp->_IO_read_ptr = c;
1116 return (unsigned char) c;
1119 _IO_off64_t
1120 _IO_default_seek (fp, offset, dir)
1121 _IO_FILE *fp;
1122 _IO_off64_t offset;
1123 int dir;
1125 return _IO_pos_BAD;
1129 _IO_default_stat (fp, st)
1130 _IO_FILE *fp;
1131 void* st;
1133 return EOF;
1136 _IO_ssize_t
1137 _IO_default_read (fp, data, n)
1138 _IO_FILE* fp;
1139 void *data;
1140 _IO_ssize_t n;
1142 return -1;
1145 _IO_ssize_t
1146 _IO_default_write (fp, data, n)
1147 _IO_FILE *fp;
1148 const void *data;
1149 _IO_ssize_t n;
1151 return 0;
1155 _IO_default_showmanyc (fp)
1156 _IO_FILE *fp;
1158 return -1;
1161 void
1162 _IO_default_imbue (fp, locale)
1163 _IO_FILE *fp;
1164 void *locale;
1168 _IO_ITER
1169 _IO_iter_begin()
1171 return (_IO_ITER) _IO_list_all;
1174 _IO_ITER
1175 _IO_iter_end()
1177 return NULL;
1180 _IO_ITER
1181 _IO_iter_next(iter)
1182 _IO_ITER iter;
1184 return iter->_chain;
1187 _IO_FILE *
1188 _IO_iter_file(iter)
1189 _IO_ITER iter;
1191 return iter;
1194 void
1195 _IO_list_lock()
1197 #ifdef _IO_MTSAFE_IO
1198 _IO_lock_lock (list_all_lock);
1199 #endif
1202 void
1203 _IO_list_unlock()
1205 #ifdef _IO_MTSAFE_IO
1206 _IO_lock_unlock (list_all_lock);
1207 #endif
1210 void
1211 _IO_list_resetlock()
1213 #ifdef _IO_MTSAFE_IO
1214 _IO_lock_init (list_all_lock);
1215 #endif
1219 #ifdef TODO
1220 #if defined(linux)
1221 #define IO_CLEANUP ;
1222 #endif
1224 #ifdef IO_CLEANUP
1225 IO_CLEANUP
1226 #else
1227 struct __io_defs {
1228 __io_defs() { }
1229 ~__io_defs() { _IO_cleanup (); }
1231 __io_defs io_defs__;
1232 #endif
1234 #endif /* TODO */
1236 #ifdef weak_alias
1237 weak_alias (_IO_cleanup, _cleanup)
1238 #endif
1240 #ifdef text_set_element
1241 text_set_element(__libc_atexit, _cleanup);
1242 #endif