* io/ftw.c (ftw_startup): Use fchdir to return to original
[glibc.git] / libio / genops.c
blob030343e7aac8925d28e3a77d167159c2db6858ef
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>
36 #include <stdbool.h>
38 #ifdef _IO_MTSAFE_IO
39 static _IO_lock_t list_all_lock = _IO_lock_initializer;
40 #endif
42 /* Used to signal modifications to the list of FILE decriptors. */
43 static int _IO_list_all_stamp;
46 static _IO_FILE *run_fp;
48 static void
49 flush_cleanup (void *not_used)
51 if (run_fp != NULL)
52 _IO_funlockfile (run_fp);
53 #ifdef _IO_MTSAFE_IO
54 _IO_lock_unlock (list_all_lock);
55 #endif
58 void
59 _IO_un_link (fp)
60 struct _IO_FILE_plus *fp;
62 if (fp->file._flags & _IO_LINKED)
64 struct _IO_FILE_plus **f;
65 #ifdef _IO_MTSAFE_IO
66 _IO_cleanup_region_start_noarg (flush_cleanup);
67 _IO_lock_lock (list_all_lock);
68 run_fp = (_IO_FILE *) fp;
69 _IO_flockfile ((_IO_FILE *) fp);
70 #endif
71 for (f = &INTUSE(_IO_list_all); *f;
72 f = (struct _IO_FILE_plus **) &(*f)->file._chain)
74 if (*f == fp)
76 *f = (struct _IO_FILE_plus *) fp->file._chain;
77 ++_IO_list_all_stamp;
78 break;
81 fp->file._flags &= ~_IO_LINKED;
82 #ifdef _IO_MTSAFE_IO
83 _IO_funlockfile ((_IO_FILE *) fp);
84 run_fp = NULL;
85 _IO_lock_unlock (list_all_lock);
86 _IO_cleanup_region_end (0);
87 #endif
90 INTDEF(_IO_un_link)
92 void
93 _IO_link_in (fp)
94 struct _IO_FILE_plus *fp;
96 if ((fp->file._flags & _IO_LINKED) == 0)
98 fp->file._flags |= _IO_LINKED;
99 #ifdef _IO_MTSAFE_IO
100 _IO_cleanup_region_start_noarg (flush_cleanup);
101 _IO_lock_lock (list_all_lock);
102 run_fp = (_IO_FILE *) fp;
103 _IO_flockfile ((_IO_FILE *) fp);
104 #endif
105 fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
106 INTUSE(_IO_list_all) = fp;
107 ++_IO_list_all_stamp;
108 #ifdef _IO_MTSAFE_IO
109 _IO_funlockfile ((_IO_FILE *) fp);
110 run_fp = NULL;
111 _IO_lock_unlock (list_all_lock);
112 _IO_cleanup_region_end (0);
113 #endif
116 INTDEF(_IO_link_in)
118 /* Return minimum _pos markers
119 Assumes the current get area is the main get area. */
120 _IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
122 _IO_ssize_t
123 _IO_least_marker (fp, end_p)
124 _IO_FILE *fp;
125 char *end_p;
127 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
128 struct _IO_marker *mark;
129 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
130 if (mark->_pos < least_so_far)
131 least_so_far = mark->_pos;
132 return least_so_far;
135 /* Switch current get area from backup buffer to (start of) main get area. */
137 void
138 _IO_switch_to_main_get_area (fp)
139 _IO_FILE *fp;
141 char *tmp;
142 fp->_flags &= ~_IO_IN_BACKUP;
143 /* Swap _IO_read_end and _IO_save_end. */
144 tmp = fp->_IO_read_end;
145 fp->_IO_read_end = fp->_IO_save_end;
146 fp->_IO_save_end= tmp;
147 /* Swap _IO_read_base and _IO_save_base. */
148 tmp = fp->_IO_read_base;
149 fp->_IO_read_base = fp->_IO_save_base;
150 fp->_IO_save_base = tmp;
151 /* Set _IO_read_ptr. */
152 fp->_IO_read_ptr = fp->_IO_read_base;
155 /* Switch current get area from main get area to (end of) backup area. */
157 void
158 _IO_switch_to_backup_area (fp)
159 _IO_FILE *fp;
161 char *tmp;
162 fp->_flags |= _IO_IN_BACKUP;
163 /* Swap _IO_read_end and _IO_save_end. */
164 tmp = fp->_IO_read_end;
165 fp->_IO_read_end = fp->_IO_save_end;
166 fp->_IO_save_end = tmp;
167 /* Swap _IO_read_base and _IO_save_base. */
168 tmp = fp->_IO_read_base;
169 fp->_IO_read_base = fp->_IO_save_base;
170 fp->_IO_save_base = tmp;
171 /* Set _IO_read_ptr. */
172 fp->_IO_read_ptr = fp->_IO_read_end;
176 _IO_switch_to_get_mode (fp)
177 _IO_FILE *fp;
179 if (fp->_IO_write_ptr > fp->_IO_write_base)
180 if (_IO_OVERFLOW (fp, EOF) == EOF)
181 return EOF;
182 if (_IO_in_backup (fp))
183 fp->_IO_read_base = fp->_IO_backup_base;
184 else
186 fp->_IO_read_base = fp->_IO_buf_base;
187 if (fp->_IO_write_ptr > fp->_IO_read_end)
188 fp->_IO_read_end = fp->_IO_write_ptr;
190 fp->_IO_read_ptr = fp->_IO_write_ptr;
192 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
194 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
195 return 0;
197 INTDEF(_IO_switch_to_get_mode)
199 void
200 _IO_free_backup_area (fp)
201 _IO_FILE *fp;
203 if (_IO_in_backup (fp))
204 _IO_switch_to_main_get_area (fp); /* Just in case. */
205 free (fp->_IO_save_base);
206 fp->_IO_save_base = NULL;
207 fp->_IO_save_end = NULL;
208 fp->_IO_backup_base = NULL;
210 INTDEF(_IO_free_backup_area)
212 #if 0
214 _IO_switch_to_put_mode (fp)
215 _IO_FILE *fp;
217 fp->_IO_write_base = fp->_IO_read_ptr;
218 fp->_IO_write_ptr = fp->_IO_read_ptr;
219 /* Following is wrong if line- or un-buffered? */
220 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
221 ? fp->_IO_read_end : fp->_IO_buf_end);
223 fp->_IO_read_ptr = fp->_IO_read_end;
224 fp->_IO_read_base = fp->_IO_read_end;
226 fp->_flags |= _IO_CURRENTLY_PUTTING;
227 return 0;
229 #endif
232 __overflow (f, ch)
233 _IO_FILE *f;
234 int ch;
236 /* This is a single-byte stream. */
237 if (f->_mode == 0)
238 _IO_fwide (f, -1);
239 return _IO_OVERFLOW (f, ch);
241 libc_hidden_def (__overflow)
243 static int save_for_backup (_IO_FILE *fp, char *end_p)
244 #ifdef _LIBC
245 internal_function
246 #endif
249 static int
250 #ifdef _LIBC
251 internal_function
252 #endif
253 save_for_backup (fp, end_p)
254 _IO_FILE *fp;
255 char *end_p;
257 /* Append [_IO_read_base..end_p] to backup area. */
258 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
259 /* needed_size is how much space we need in the backup area. */
260 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
261 /* FIXME: Dubious arithmetic if pointers are NULL */
262 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
263 _IO_size_t avail; /* Extra space available for future expansion. */
264 _IO_ssize_t delta;
265 struct _IO_marker *mark;
266 if (needed_size > current_Bsize)
268 char *new_buffer;
269 avail = 100;
270 new_buffer = (char *) malloc (avail + needed_size);
271 if (new_buffer == NULL)
272 return EOF; /* FIXME */
273 if (least_mark < 0)
275 #ifdef _LIBC
276 __mempcpy (__mempcpy (new_buffer + avail,
277 fp->_IO_save_end + least_mark,
278 -least_mark),
279 fp->_IO_read_base,
280 end_p - fp->_IO_read_base);
281 #else
282 memcpy (new_buffer + avail,
283 fp->_IO_save_end + least_mark,
284 -least_mark);
285 memcpy (new_buffer + avail - least_mark,
286 fp->_IO_read_base,
287 end_p - fp->_IO_read_base);
288 #endif
290 else
291 memcpy (new_buffer + avail,
292 fp->_IO_read_base + least_mark,
293 needed_size);
294 if (fp->_IO_save_base)
295 free (fp->_IO_save_base);
296 fp->_IO_save_base = new_buffer;
297 fp->_IO_save_end = new_buffer + avail + needed_size;
299 else
301 avail = current_Bsize - needed_size;
302 if (least_mark < 0)
304 memmove (fp->_IO_save_base + avail,
305 fp->_IO_save_end + least_mark,
306 -least_mark);
307 memcpy (fp->_IO_save_base + avail - least_mark,
308 fp->_IO_read_base,
309 end_p - fp->_IO_read_base);
311 else if (needed_size > 0)
312 memcpy (fp->_IO_save_base + avail,
313 fp->_IO_read_base + least_mark,
314 needed_size);
316 fp->_IO_backup_base = fp->_IO_save_base + avail;
317 /* Adjust all the streammarkers. */
318 delta = end_p - fp->_IO_read_base;
319 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
320 mark->_pos -= delta;
321 return 0;
325 __underflow (fp)
326 _IO_FILE *fp;
328 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
329 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
330 return EOF;
331 #endif
333 if (fp->_mode == 0)
334 _IO_fwide (fp, -1);
335 if (_IO_in_put_mode (fp))
336 if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
337 return EOF;
338 if (fp->_IO_read_ptr < fp->_IO_read_end)
339 return *(unsigned char *) fp->_IO_read_ptr;
340 if (_IO_in_backup (fp))
342 _IO_switch_to_main_get_area (fp);
343 if (fp->_IO_read_ptr < fp->_IO_read_end)
344 return *(unsigned char *) fp->_IO_read_ptr;
346 if (_IO_have_markers (fp))
348 if (save_for_backup (fp, fp->_IO_read_end))
349 return EOF;
351 else if (_IO_have_backup (fp))
352 INTUSE(_IO_free_backup_area) (fp);
353 return _IO_UNDERFLOW (fp);
355 libc_hidden_def (__underflow)
358 __uflow (fp)
359 _IO_FILE *fp;
361 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
362 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
363 return EOF;
364 #endif
366 if (fp->_mode == 0)
367 _IO_fwide (fp, -11);
368 if (_IO_in_put_mode (fp))
369 if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
370 return EOF;
371 if (fp->_IO_read_ptr < fp->_IO_read_end)
372 return *(unsigned char *) fp->_IO_read_ptr++;
373 if (_IO_in_backup (fp))
375 _IO_switch_to_main_get_area (fp);
376 if (fp->_IO_read_ptr < fp->_IO_read_end)
377 return *(unsigned char *) fp->_IO_read_ptr++;
379 if (_IO_have_markers (fp))
381 if (save_for_backup (fp, fp->_IO_read_end))
382 return EOF;
384 else if (_IO_have_backup (fp))
385 INTUSE(_IO_free_backup_area) (fp);
386 return _IO_UFLOW (fp);
388 libc_hidden_def (__uflow)
390 void
391 _IO_setb (f, b, eb, a)
392 _IO_FILE *f;
393 char *b;
394 char *eb;
395 int a;
397 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
398 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
399 f->_IO_buf_base = b;
400 f->_IO_buf_end = eb;
401 if (a)
402 f->_flags &= ~_IO_USER_BUF;
403 else
404 f->_flags |= _IO_USER_BUF;
406 INTDEF(_IO_setb)
408 void
409 _IO_doallocbuf (fp)
410 _IO_FILE *fp;
412 if (fp->_IO_buf_base)
413 return;
414 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
415 if (_IO_DOALLOCATE (fp) != EOF)
416 return;
417 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
419 INTDEF(_IO_doallocbuf)
422 _IO_default_underflow (fp)
423 _IO_FILE *fp;
425 return EOF;
429 _IO_default_uflow (fp)
430 _IO_FILE *fp;
432 int ch = _IO_UNDERFLOW (fp);
433 if (ch == EOF)
434 return EOF;
435 return *(unsigned char *) fp->_IO_read_ptr++;
437 INTDEF(_IO_default_uflow)
439 _IO_size_t
440 _IO_default_xsputn (f, data, n)
441 _IO_FILE *f;
442 const void *data;
443 _IO_size_t n;
445 const char *s = (char *) data;
446 _IO_size_t more = n;
447 if (more <= 0)
448 return 0;
449 for (;;)
451 /* Space available. */
452 if (f->_IO_write_ptr < f->_IO_write_end)
454 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
455 if (count > more)
456 count = more;
457 if (count > 20)
459 #ifdef _LIBC
460 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
461 #else
462 memcpy (f->_IO_write_ptr, s, count);
463 f->_IO_write_ptr += count;
464 #endif
465 s += count;
467 else if (count)
469 char *p = f->_IO_write_ptr;
470 _IO_ssize_t i;
471 for (i = count; --i >= 0; )
472 *p++ = *s++;
473 f->_IO_write_ptr = p;
475 more -= count;
477 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
478 break;
479 more--;
481 return n - more;
483 INTDEF(_IO_default_xsputn)
485 _IO_size_t
486 _IO_sgetn (fp, data, n)
487 _IO_FILE *fp;
488 void *data;
489 _IO_size_t n;
491 /* FIXME handle putback buffer here! */
492 return _IO_XSGETN (fp, data, n);
494 INTDEF(_IO_sgetn)
496 _IO_size_t
497 _IO_default_xsgetn (fp, data, n)
498 _IO_FILE *fp;
499 void *data;
500 _IO_size_t n;
502 _IO_size_t more = n;
503 char *s = (char*) data;
504 for (;;)
506 /* Data available. */
507 if (fp->_IO_read_ptr < fp->_IO_read_end)
509 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
510 if (count > more)
511 count = more;
512 if (count > 20)
514 #ifdef _LIBC
515 s = __mempcpy (s, fp->_IO_read_ptr, count);
516 #else
517 memcpy (s, fp->_IO_read_ptr, count);
518 s += count;
519 #endif
520 fp->_IO_read_ptr += count;
522 else if (count)
524 char *p = fp->_IO_read_ptr;
525 int i = (int) count;
526 while (--i >= 0)
527 *s++ = *p++;
528 fp->_IO_read_ptr = p;
530 more -= count;
532 if (more == 0 || __underflow (fp) == EOF)
533 break;
535 return n - more;
537 INTDEF(_IO_default_xsgetn)
539 #if 0
540 /* Seems not to be needed. --drepper */
542 _IO_sync (fp)
543 _IO_FILE *fp;
545 return 0;
547 #endif
549 _IO_FILE *
550 _IO_default_setbuf (fp, p, len)
551 _IO_FILE *fp;
552 char *p;
553 _IO_ssize_t len;
555 if (_IO_SYNC (fp) == EOF)
556 return NULL;
557 if (p == NULL || len == 0)
559 fp->_flags |= _IO_UNBUFFERED;
560 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
562 else
564 fp->_flags &= ~_IO_UNBUFFERED;
565 INTUSE(_IO_setb) (fp, p, p+len, 0);
567 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
568 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
569 return fp;
572 _IO_off64_t
573 _IO_default_seekpos (fp, pos, mode)
574 _IO_FILE *fp;
575 _IO_off64_t pos;
576 int mode;
578 return _IO_SEEKOFF (fp, pos, 0, mode);
582 _IO_default_doallocate (fp)
583 _IO_FILE *fp;
585 char *buf;
587 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
588 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
589 return 1;
591 INTDEF(_IO_default_doallocate)
593 void
594 _IO_init (fp, flags)
595 _IO_FILE *fp;
596 int flags;
598 _IO_no_init (fp, flags, -1, NULL, NULL);
600 INTDEF(_IO_init)
602 void
603 _IO_old_init (fp, flags)
604 _IO_FILE *fp;
605 int flags;
607 fp->_flags = _IO_MAGIC|flags;
608 fp->_flags2 = 0;
609 fp->_IO_buf_base = NULL;
610 fp->_IO_buf_end = NULL;
611 fp->_IO_read_base = NULL;
612 fp->_IO_read_ptr = NULL;
613 fp->_IO_read_end = NULL;
614 fp->_IO_write_base = NULL;
615 fp->_IO_write_ptr = NULL;
616 fp->_IO_write_end = NULL;
617 fp->_chain = NULL; /* Not necessary. */
619 fp->_IO_save_base = NULL;
620 fp->_IO_backup_base = NULL;
621 fp->_IO_save_end = NULL;
622 fp->_markers = NULL;
623 fp->_cur_column = 0;
624 #if _IO_JUMPS_OFFSET
625 fp->_vtable_offset = 0;
626 #endif
627 #ifdef _IO_MTSAFE_IO
628 if (fp->_lock != NULL)
629 _IO_lock_init (*fp->_lock);
630 #endif
633 void
634 _IO_no_init (fp, flags, orientation, wd, jmp)
635 _IO_FILE *fp;
636 int flags;
637 int orientation;
638 struct _IO_wide_data *wd;
639 const struct _IO_jump_t *jmp;
641 _IO_old_init (fp, flags);
642 fp->_mode = orientation;
643 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
644 if (orientation >= 0)
646 fp->_wide_data = wd;
647 fp->_wide_data->_IO_buf_base = NULL;
648 fp->_wide_data->_IO_buf_end = NULL;
649 fp->_wide_data->_IO_read_base = NULL;
650 fp->_wide_data->_IO_read_ptr = NULL;
651 fp->_wide_data->_IO_read_end = NULL;
652 fp->_wide_data->_IO_write_base = NULL;
653 fp->_wide_data->_IO_write_ptr = NULL;
654 fp->_wide_data->_IO_write_end = NULL;
655 fp->_wide_data->_IO_save_base = NULL;
656 fp->_wide_data->_IO_backup_base = NULL;
657 fp->_wide_data->_IO_save_end = NULL;
659 fp->_wide_data->_wide_vtable = jmp;
661 #endif
662 fp->_freeres_list = NULL;
666 _IO_default_sync (fp)
667 _IO_FILE *fp;
669 return 0;
672 /* The way the C++ classes are mapped into the C functions in the
673 current implementation, this function can get called twice! */
675 void
676 _IO_default_finish (fp, dummy)
677 _IO_FILE *fp;
678 int dummy;
680 struct _IO_marker *mark;
681 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
683 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
684 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
687 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
688 mark->_sbuf = NULL;
690 if (fp->_IO_save_base)
692 free (fp->_IO_save_base);
693 fp->_IO_save_base = NULL;
696 #ifdef _IO_MTSAFE_IO
697 if (fp->_lock != NULL)
698 _IO_lock_fini (*fp->_lock);
699 #endif
701 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
703 INTDEF(_IO_default_finish)
705 _IO_off64_t
706 _IO_default_seekoff (fp, offset, dir, mode)
707 _IO_FILE *fp;
708 _IO_off64_t offset;
709 int dir;
710 int mode;
712 return _IO_pos_BAD;
716 _IO_sputbackc (fp, c)
717 _IO_FILE *fp;
718 int c;
720 int result;
722 if (fp->_IO_read_ptr > fp->_IO_read_base
723 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
725 fp->_IO_read_ptr--;
726 result = (unsigned char) c;
728 else
729 result = _IO_PBACKFAIL (fp, c);
731 if (result != EOF)
732 fp->_flags &= ~_IO_EOF_SEEN;
734 return result;
736 INTDEF(_IO_sputbackc)
739 _IO_sungetc (fp)
740 _IO_FILE *fp;
742 int result;
744 if (fp->_IO_read_ptr > fp->_IO_read_base)
746 fp->_IO_read_ptr--;
747 result = (unsigned char) *fp->_IO_read_ptr;
749 else
750 result = _IO_PBACKFAIL (fp, EOF);
752 if (result != EOF)
753 fp->_flags &= ~_IO_EOF_SEEN;
755 return result;
758 #if 0 /* Work in progress */
759 /* Seems not to be needed. */
760 #if 0
761 void
762 _IO_set_column (fp, c)
763 _IO_FILE *fp;
764 int c;
766 if (c == -1)
767 fp->_column = -1;
768 else
769 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
771 #else
773 _IO_set_column (fp, i)
774 _IO_FILE *fp;
775 int i;
777 fp->_cur_column = i + 1;
778 return 0;
780 #endif
781 #endif
784 unsigned
785 _IO_adjust_column (start, line, count)
786 unsigned start;
787 const char *line;
788 int count;
790 const char *ptr = line + count;
791 while (ptr > line)
792 if (*--ptr == '\n')
793 return line + count - ptr - 1;
794 return start + count;
796 INTDEF(_IO_adjust_column)
798 #if 0
799 /* Seems not to be needed. --drepper */
801 _IO_get_column (fp)
802 _IO_FILE *fp;
804 if (fp->_cur_column)
805 return _IO_adjust_column (fp->_cur_column - 1,
806 fp->_IO_write_base,
807 fp->_IO_write_ptr - fp->_IO_write_base);
808 return -1;
810 #endif
814 _IO_flush_all_lockp (int do_lock)
816 int result = 0;
817 struct _IO_FILE *fp;
818 int last_stamp;
820 #ifdef _IO_MTSAFE_IO
821 _IO_cleanup_region_start_noarg (flush_cleanup);
822 if (do_lock)
823 _IO_lock_lock (list_all_lock);
824 #endif
826 last_stamp = _IO_list_all_stamp;
827 fp = (_IO_FILE *) INTUSE(_IO_list_all);
828 while (fp != NULL)
830 run_fp = fp;
831 if (do_lock)
832 _IO_flockfile (fp);
834 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
835 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
836 || (_IO_vtable_offset (fp) == 0
837 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
838 > fp->_wide_data->_IO_write_base))
839 #endif
841 && _IO_OVERFLOW (fp, EOF) == EOF)
842 result = EOF;
844 if (do_lock)
845 _IO_funlockfile (fp);
846 run_fp = NULL;
848 if (last_stamp != _IO_list_all_stamp)
850 /* Something was added to the list. Start all over again. */
851 fp = (_IO_FILE *) INTUSE(_IO_list_all);
852 last_stamp = _IO_list_all_stamp;
854 else
855 fp = fp->_chain;
858 #ifdef _IO_MTSAFE_IO
859 if (do_lock)
860 _IO_lock_unlock (list_all_lock);
861 _IO_cleanup_region_end (0);
862 #endif
864 return result;
869 _IO_flush_all ()
871 /* We want locking. */
872 return _IO_flush_all_lockp (1);
874 INTDEF(_IO_flush_all)
876 void
877 _IO_flush_all_linebuffered ()
879 struct _IO_FILE *fp;
880 int last_stamp;
882 #ifdef _IO_MTSAFE_IO
883 _IO_cleanup_region_start_noarg (flush_cleanup);
884 _IO_lock_lock (list_all_lock);
885 #endif
887 last_stamp = _IO_list_all_stamp;
888 fp = (_IO_FILE *) INTUSE(_IO_list_all);
889 while (fp != NULL)
891 run_fp = fp;
892 _IO_flockfile (fp);
894 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
895 _IO_OVERFLOW (fp, EOF);
897 _IO_funlockfile (fp);
898 run_fp = NULL;
900 if (last_stamp != _IO_list_all_stamp)
902 /* Something was added to the list. Start all over again. */
903 fp = (_IO_FILE *) INTUSE(_IO_list_all);
904 last_stamp = _IO_list_all_stamp;
906 else
907 fp = fp->_chain;
910 #ifdef _IO_MTSAFE_IO
911 _IO_lock_unlock (list_all_lock);
912 _IO_cleanup_region_end (0);
913 #endif
915 INTDEF(_IO_flush_all_linebuffered)
916 #ifdef _LIBC
917 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
918 #endif
921 /* The following is a bit tricky. In general, we want to unbuffer the
922 streams so that all output which follows is seen. If we are not
923 looking for memory leaks it does not make much sense to free the
924 actual buffer because this will happen anyway once the program
925 terminated. If we do want to look for memory leaks we have to free
926 the buffers. Whether something is freed is determined by the
927 function sin the libc_freeres section. Those are called as part of
928 the atexit routine, just like _IO_cleanup. The problem is we do
929 not know whether the freeres code is called first or _IO_cleanup.
930 if the former is the case, we set the DEALLOC_BUFFER variable to
931 true and _IO_unbuffer_write will take care of the rest. If
932 _IO_unbuffer_write is called first we add the streams to a list
933 which the freeres function later can walk through. */
934 static void _IO_unbuffer_write (void);
936 static bool dealloc_buffers;
937 static _IO_FILE *freeres_list;
939 static void
940 _IO_unbuffer_write (void)
942 struct _IO_FILE *fp;
943 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
945 if (! (fp->_flags & _IO_UNBUFFERED)
946 && (! (fp->_flags & _IO_NO_WRITES)
947 || (fp->_flags & _IO_IS_APPENDING))
948 /* Iff stream is un-orientated, it wasn't used. */
949 && fp->_mode != 0)
951 int cnt;
952 #define MAXTRIES 2
953 for (cnt = 0; cnt < MAXTRIES; ++cnt)
954 if (_IO_lock_trylock (*fp->_lock) == 0)
955 break;
956 else
957 /* Give the other thread time to finish up its use of the
958 stream. */
959 __sched_yield ();
961 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
963 fp->_flags |= _IO_USER_BUF;
965 fp->_freeres_list = freeres_list;
966 freeres_list = fp;
967 fp->_freeres_buf = fp->_IO_buf_base;
968 fp->_freeres_size = _IO_blen (fp);
971 _IO_SETBUF (fp, NULL, 0);
973 if (cnt < MAXTRIES)
974 _IO_lock_unlock (*fp->_lock);
977 /* Make sure that never again the wide char functions can be
978 used. */
979 fp->_mode = -1;
984 libc_freeres_fn (buffer_free)
986 dealloc_buffers = true;
988 while (freeres_list != NULL)
990 FREE_BUF (freeres_list->_freeres_buf, freeres_list->_freeres_size);
992 freeres_list = freeres_list->_freeres_list;
998 _IO_cleanup ()
1000 /* We do *not* want locking. Some threads might use streams but
1001 that is their problem, we flush them underneath them. */
1002 int result = _IO_flush_all_lockp (0);
1004 /* We currently don't have a reliable mechanism for making sure that
1005 C++ static destructors are executed in the correct order.
1006 So it is possible that other static destructors might want to
1007 write to cout - and they're supposed to be able to do so.
1009 The following will make the standard streambufs be unbuffered,
1010 which forces any output from late destructors to be written out. */
1011 _IO_unbuffer_write ();
1013 return result;
1017 void
1018 _IO_init_marker (marker, fp)
1019 struct _IO_marker *marker;
1020 _IO_FILE *fp;
1022 marker->_sbuf = fp;
1023 if (_IO_in_put_mode (fp))
1024 INTUSE(_IO_switch_to_get_mode) (fp);
1025 if (_IO_in_backup (fp))
1026 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
1027 else
1028 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
1030 /* Should perhaps sort the chain? */
1031 marker->_next = fp->_markers;
1032 fp->_markers = marker;
1035 void
1036 _IO_remove_marker (marker)
1037 struct _IO_marker *marker;
1039 /* Unlink from sb's chain. */
1040 struct _IO_marker **ptr = &marker->_sbuf->_markers;
1041 for (; ; ptr = &(*ptr)->_next)
1043 if (*ptr == NULL)
1044 break;
1045 else if (*ptr == marker)
1047 *ptr = marker->_next;
1048 return;
1051 #if 0
1052 if _sbuf has a backup area that is no longer needed, should we delete
1053 it now, or wait until the next underflow?
1054 #endif
1057 #define BAD_DELTA EOF
1060 _IO_marker_difference (mark1, mark2)
1061 struct _IO_marker *mark1;
1062 struct _IO_marker *mark2;
1064 return mark1->_pos - mark2->_pos;
1067 /* Return difference between MARK and current position of MARK's stream. */
1069 _IO_marker_delta (mark)
1070 struct _IO_marker *mark;
1072 int cur_pos;
1073 if (mark->_sbuf == NULL)
1074 return BAD_DELTA;
1075 if (_IO_in_backup (mark->_sbuf))
1076 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1077 else
1078 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1079 return mark->_pos - cur_pos;
1083 _IO_seekmark (fp, mark, delta)
1084 _IO_FILE *fp;
1085 struct _IO_marker *mark;
1086 int delta;
1088 if (mark->_sbuf != fp)
1089 return EOF;
1090 if (mark->_pos >= 0)
1092 if (_IO_in_backup (fp))
1093 _IO_switch_to_main_get_area (fp);
1094 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1096 else
1098 if (!_IO_in_backup (fp))
1099 _IO_switch_to_backup_area (fp);
1100 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1102 return 0;
1105 void
1106 _IO_unsave_markers (fp)
1107 _IO_FILE *fp;
1109 struct _IO_marker *mark = fp->_markers;
1110 if (mark)
1112 #ifdef TODO
1113 streampos offset = seekoff (0, ios::cur, ios::in);
1114 if (offset != EOF)
1116 offset += eGptr () - Gbase ();
1117 for ( ; mark != NULL; mark = mark->_next)
1118 mark->set_streampos (mark->_pos + offset);
1120 else
1122 for ( ; mark != NULL; mark = mark->_next)
1123 mark->set_streampos (EOF);
1125 #endif
1126 fp->_markers = 0;
1129 if (_IO_have_backup (fp))
1130 INTUSE(_IO_free_backup_area) (fp);
1132 INTDEF(_IO_unsave_markers)
1134 #if 0
1135 /* Seems not to be needed. --drepper */
1137 _IO_nobackup_pbackfail (fp, c)
1138 _IO_FILE *fp;
1139 int c;
1141 if (fp->_IO_read_ptr > fp->_IO_read_base)
1142 fp->_IO_read_ptr--;
1143 if (c != EOF && *fp->_IO_read_ptr != c)
1144 *fp->_IO_read_ptr = c;
1145 return (unsigned char) c;
1147 #endif
1150 _IO_default_pbackfail (fp, c)
1151 _IO_FILE *fp;
1152 int c;
1154 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1155 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1156 --fp->_IO_read_ptr;
1157 else
1159 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1160 if (!_IO_in_backup (fp))
1162 /* We need to keep the invariant that the main get area
1163 logically follows the backup area. */
1164 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1166 if (save_for_backup (fp, fp->_IO_read_ptr))
1167 return EOF;
1169 else if (!_IO_have_backup (fp))
1171 /* No backup buffer: allocate one. */
1172 /* Use nshort buffer, if unused? (probably not) FIXME */
1173 int backup_size = 128;
1174 char *bbuf = (char *) malloc (backup_size);
1175 if (bbuf == NULL)
1176 return EOF;
1177 fp->_IO_save_base = bbuf;
1178 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1179 fp->_IO_backup_base = fp->_IO_save_end;
1181 fp->_IO_read_base = fp->_IO_read_ptr;
1182 _IO_switch_to_backup_area (fp);
1184 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1186 /* Increase size of existing backup buffer. */
1187 _IO_size_t new_size;
1188 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1189 char *new_buf;
1190 new_size = 2 * old_size;
1191 new_buf = (char *) malloc (new_size);
1192 if (new_buf == NULL)
1193 return EOF;
1194 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1195 old_size);
1196 free (fp->_IO_read_base);
1197 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1198 new_buf + new_size);
1199 fp->_IO_backup_base = fp->_IO_read_ptr;
1202 *--fp->_IO_read_ptr = c;
1204 return (unsigned char) c;
1206 INTDEF(_IO_default_pbackfail)
1208 _IO_off64_t
1209 _IO_default_seek (fp, offset, dir)
1210 _IO_FILE *fp;
1211 _IO_off64_t offset;
1212 int dir;
1214 return _IO_pos_BAD;
1218 _IO_default_stat (fp, st)
1219 _IO_FILE *fp;
1220 void* st;
1222 return EOF;
1225 _IO_ssize_t
1226 _IO_default_read (fp, data, n)
1227 _IO_FILE* fp;
1228 void *data;
1229 _IO_ssize_t n;
1231 return -1;
1234 _IO_ssize_t
1235 _IO_default_write (fp, data, n)
1236 _IO_FILE *fp;
1237 const void *data;
1238 _IO_ssize_t n;
1240 return 0;
1244 _IO_default_showmanyc (fp)
1245 _IO_FILE *fp;
1247 return -1;
1250 void
1251 _IO_default_imbue (fp, locale)
1252 _IO_FILE *fp;
1253 void *locale;
1257 _IO_ITER
1258 _IO_iter_begin()
1260 return (_IO_ITER) INTUSE(_IO_list_all);
1262 libc_hidden_def (_IO_iter_begin)
1264 _IO_ITER
1265 _IO_iter_end()
1267 return NULL;
1269 libc_hidden_def (_IO_iter_end)
1271 _IO_ITER
1272 _IO_iter_next(iter)
1273 _IO_ITER iter;
1275 return iter->_chain;
1277 libc_hidden_def (_IO_iter_next)
1279 _IO_FILE *
1280 _IO_iter_file(iter)
1281 _IO_ITER iter;
1283 return iter;
1285 libc_hidden_def (_IO_iter_file)
1287 void
1288 _IO_list_lock()
1290 #ifdef _IO_MTSAFE_IO
1291 _IO_lock_lock (list_all_lock);
1292 #endif
1294 libc_hidden_def (_IO_list_lock)
1296 void
1297 _IO_list_unlock()
1299 #ifdef _IO_MTSAFE_IO
1300 _IO_lock_unlock (list_all_lock);
1301 #endif
1303 libc_hidden_def (_IO_list_unlock)
1305 void
1306 _IO_list_resetlock()
1308 #ifdef _IO_MTSAFE_IO
1309 _IO_lock_init (list_all_lock);
1310 #endif
1312 libc_hidden_def (_IO_list_resetlock)
1315 #ifdef TODO
1316 #if defined(linux)
1317 #define IO_CLEANUP ;
1318 #endif
1320 #ifdef IO_CLEANUP
1321 IO_CLEANUP
1322 #else
1323 struct __io_defs {
1324 __io_defs() { }
1325 ~__io_defs() { _IO_cleanup (); }
1327 __io_defs io_defs__;
1328 #endif
1330 #endif /* TODO */
1332 #ifdef text_set_element
1333 text_set_element(__libc_atexit, _IO_cleanup);
1334 #endif