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