]> sourceware.org Git - glibc.git/blame - libio/genops.c
Update.
[glibc.git] / libio / genops.c
CommitLineData
9202ffe3 1/* Copyright (C) 1993, 1995, 1997-1999, 2000 Free Software Foundation, Inc.
40a55d20
UD
2 This file is part of the GNU IO Library.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this library; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17 MA 02111-1307, USA.
18
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does
21 not cause the resulting executable to be covered by the GNU General
22 Public License. This exception does not however invalidate any
23 other reasons why the executable file might be covered by the GNU
24 General Public License. */
96aa2d94
RM
25
26/* Generic or default I/O operations. */
27
28#include "libioP.h"
29#ifdef __STDC__
30#include <stdlib.h>
31#endif
32#include <string.h>
33
51e176c2 34#ifdef _IO_MTSAFE_IO
118bad87 35static _IO_lock_t list_all_lock = _IO_lock_initializer;
51e176c2 36#endif
118bad87 37
96aa2d94 38void
40a55d20 39_IO_un_link (fp)
2ca8b1ee 40 struct _IO_FILE_plus *fp;
40a55d20 41{
2ca8b1ee 42 if (fp->file._flags & _IO_LINKED)
40a55d20 43 {
2ca8b1ee 44 struct _IO_FILE_plus **f;
d328b80b 45#ifdef _IO_MTSAFE_IO
118bad87 46 _IO_lock_lock (list_all_lock);
51e176c2 47#endif
2ca8b1ee 48 for (f = &_IO_list_all; *f != NULL; f = &(*f)->file._chain)
40a55d20
UD
49 {
50 if (*f == fp)
51 {
2ca8b1ee 52 *f = fp->file._chain;
40a55d20
UD
53 break;
54 }
55 }
51e176c2 56#ifdef _IO_MTSAFE_IO
118bad87 57 _IO_lock_unlock (list_all_lock);
51e176c2 58#endif
2ca8b1ee 59 fp->file._flags &= ~_IO_LINKED;
96aa2d94 60 }
96aa2d94
RM
61}
62
63void
40a55d20 64_IO_link_in (fp)
2ca8b1ee 65 struct _IO_FILE_plus *fp;
96aa2d94 66{
2ca8b1ee 67 if ((fp->file._flags & _IO_LINKED) == 0)
40a55d20 68 {
2ca8b1ee 69 fp->file._flags |= _IO_LINKED;
51e176c2 70#ifdef _IO_MTSAFE_IO
118bad87 71 _IO_lock_lock (list_all_lock);
51e176c2 72#endif
2ca8b1ee 73 fp->file._chain = _IO_list_all;
96aa2d94 74 _IO_list_all = fp;
51e176c2 75#ifdef _IO_MTSAFE_IO
118bad87 76 _IO_lock_unlock (list_all_lock);
51e176c2 77#endif
40a55d20 78 }
96aa2d94
RM
79}
80
81/* Return minimum _pos markers
82 Assumes the current get area is the main get area. */
d64b6ad0 83_IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
96aa2d94 84
d64b6ad0 85_IO_ssize_t
05f732b3 86_IO_least_marker (fp, end_p)
40a55d20 87 _IO_FILE *fp;
05f732b3 88 char *end_p;
96aa2d94 89{
05f732b3 90 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
40a55d20 91 struct _IO_marker *mark;
96aa2d94
RM
92 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
93 if (mark->_pos < least_so_far)
94 least_so_far = mark->_pos;
95 return least_so_far;
96}
97
98/* Switch current get area from backup buffer to (start of) main get area. */
99
100void
40a55d20
UD
101_IO_switch_to_main_get_area (fp)
102 _IO_FILE *fp;
96aa2d94
RM
103{
104 char *tmp;
105 fp->_flags &= ~_IO_IN_BACKUP;
106 /* Swap _IO_read_end and _IO_save_end. */
40a55d20
UD
107 tmp = fp->_IO_read_end;
108 fp->_IO_read_end = fp->_IO_save_end;
109 fp->_IO_save_end= tmp;
96aa2d94 110 /* Swap _IO_read_base and _IO_save_base. */
40a55d20
UD
111 tmp = fp->_IO_read_base;
112 fp->_IO_read_base = fp->_IO_save_base;
113 fp->_IO_save_base = tmp;
05f732b3
UD
114 /* Set _IO_read_ptr. */
115 fp->_IO_read_ptr = fp->_IO_read_base;
96aa2d94
RM
116}
117
118/* Switch current get area from main get area to (end of) backup area. */
119
120void
40a55d20
UD
121_IO_switch_to_backup_area (fp)
122 _IO_FILE *fp;
96aa2d94
RM
123{
124 char *tmp;
125 fp->_flags |= _IO_IN_BACKUP;
126 /* Swap _IO_read_end and _IO_save_end. */
40a55d20
UD
127 tmp = fp->_IO_read_end;
128 fp->_IO_read_end = fp->_IO_save_end;
129 fp->_IO_save_end = tmp;
05f732b3 130 /* Swap _IO_read_base and _IO_save_base. */
40a55d20
UD
131 tmp = fp->_IO_read_base;
132 fp->_IO_read_base = fp->_IO_save_base;
133 fp->_IO_save_base = tmp;
05f732b3 134 /* Set _IO_read_ptr. */
96aa2d94
RM
135 fp->_IO_read_ptr = fp->_IO_read_end;
136}
137
138int
40a55d20
UD
139_IO_switch_to_get_mode (fp)
140 _IO_FILE *fp;
96aa2d94
RM
141{
142 if (fp->_IO_write_ptr > fp->_IO_write_base)
143 if (_IO_OVERFLOW (fp, EOF) == EOF)
144 return EOF;
40a55d20 145 if (_IO_in_backup (fp))
96aa2d94
RM
146 fp->_IO_read_base = fp->_IO_backup_base;
147 else
148 {
149 fp->_IO_read_base = fp->_IO_buf_base;
150 if (fp->_IO_write_ptr > fp->_IO_read_end)
151 fp->_IO_read_end = fp->_IO_write_ptr;
152 }
153 fp->_IO_read_ptr = fp->_IO_write_ptr;
154
155 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
156
157 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
158 return 0;
159}
160
161void
40a55d20
UD
162_IO_free_backup_area (fp)
163 _IO_FILE *fp;
96aa2d94
RM
164{
165 if (_IO_in_backup (fp))
40a55d20 166 _IO_switch_to_main_get_area (fp); /* Just in case. */
96aa2d94
RM
167 free (fp->_IO_save_base);
168 fp->_IO_save_base = NULL;
169 fp->_IO_save_end = NULL;
170 fp->_IO_backup_base = NULL;
171}
172
173#if 0
174int
40a55d20
UD
175_IO_switch_to_put_mode (fp)
176 _IO_FILE *fp;
96aa2d94
RM
177{
178 fp->_IO_write_base = fp->_IO_read_ptr;
179 fp->_IO_write_ptr = fp->_IO_read_ptr;
180 /* Following is wrong if line- or un-buffered? */
40a55d20
UD
181 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
182 ? fp->_IO_read_end : fp->_IO_buf_end);
96aa2d94
RM
183
184 fp->_IO_read_ptr = fp->_IO_read_end;
185 fp->_IO_read_base = fp->_IO_read_end;
186
187 fp->_flags |= _IO_CURRENTLY_PUTTING;
188 return 0;
189}
190#endif
191
192int
40a55d20
UD
193__overflow (f, ch)
194 _IO_FILE *f;
195 int ch;
96aa2d94
RM
196{
197 return _IO_OVERFLOW (f, ch);
198}
199
05f732b3 200static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
dfd2257a
UD
201#ifdef _LIBC
202 internal_function
203#endif
204 ;
40a55d20 205
05f732b3 206static int
dfd2257a 207#ifdef _LIBC
05f732b3 208internal_function
dfd2257a 209#endif
05f732b3 210save_for_backup (fp, end_p)
40a55d20 211 _IO_FILE *fp;
05f732b3 212 char *end_p;
96aa2d94 213{
05f732b3
UD
214 /* Append [_IO_read_base..end_p] to backup area. */
215 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
96aa2d94 216 /* needed_size is how much space we need in the backup area. */
05f732b3
UD
217 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
218 /* FIXME: Dubious arithmetic if pointers are NULL */
219 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
220 _IO_size_t avail; /* Extra space available for future expansion. */
221 _IO_ssize_t delta;
96aa2d94
RM
222 struct _IO_marker *mark;
223 if (needed_size > current_Bsize)
224 {
225 char *new_buffer;
226 avail = 100;
40a55d20 227 new_buffer = (char *) malloc (avail + needed_size);
96aa2d94
RM
228 if (new_buffer == NULL)
229 return EOF; /* FIXME */
230 if (least_mark < 0)
231 {
86187531
UD
232#ifdef _LIBC
233 __mempcpy (__mempcpy (new_buffer + avail,
234 fp->_IO_save_end + least_mark,
235 -least_mark),
236 fp->_IO_read_base,
05f732b3 237 end_p - fp->_IO_read_base);
86187531 238#else
40a55d20
UD
239 memcpy (new_buffer + avail,
240 fp->_IO_save_end + least_mark,
241 -least_mark);
242 memcpy (new_buffer + avail - least_mark,
243 fp->_IO_read_base,
05f732b3 244 end_p - fp->_IO_read_base);
86187531 245#endif
96aa2d94
RM
246 }
247 else
40a55d20
UD
248 memcpy (new_buffer + avail,
249 fp->_IO_read_base + least_mark,
250 needed_size);
96aa2d94
RM
251 if (fp->_IO_save_base)
252 free (fp->_IO_save_base);
253 fp->_IO_save_base = new_buffer;
254 fp->_IO_save_end = new_buffer + avail + needed_size;
255 }
256 else
257 {
258 avail = current_Bsize - needed_size;
259 if (least_mark < 0)
260 {
40a55d20
UD
261 memmove (fp->_IO_save_base + avail,
262 fp->_IO_save_end + least_mark,
263 -least_mark);
264 memcpy (fp->_IO_save_base + avail - least_mark,
265 fp->_IO_read_base,
05f732b3 266 end_p - fp->_IO_read_base);
96aa2d94
RM
267 }
268 else if (needed_size > 0)
40a55d20
UD
269 memcpy (fp->_IO_save_base + avail,
270 fp->_IO_read_base + least_mark,
271 needed_size);
96aa2d94 272 }
96aa2d94
RM
273 fp->_IO_backup_base = fp->_IO_save_base + avail;
274 /* Adjust all the streammarkers. */
05f732b3 275 delta = end_p - fp->_IO_read_base;
96aa2d94
RM
276 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
277 mark->_pos -= delta;
278 return 0;
279}
280
281int
40a55d20
UD
282__underflow (fp)
283 _IO_FILE *fp;
96aa2d94 284{
c9eaa8b9 285 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
d64b6ad0
UD
286 return EOF;
287
40a55d20
UD
288 if (_IO_in_put_mode (fp))
289 if (_IO_switch_to_get_mode (fp) == EOF)
290 return EOF;
96aa2d94 291 if (fp->_IO_read_ptr < fp->_IO_read_end)
40a55d20
UD
292 return *(unsigned char *) fp->_IO_read_ptr;
293 if (_IO_in_backup (fp))
96aa2d94 294 {
40a55d20 295 _IO_switch_to_main_get_area (fp);
96aa2d94 296 if (fp->_IO_read_ptr < fp->_IO_read_end)
31f7410f 297 return *(unsigned char *) fp->_IO_read_ptr;
96aa2d94 298 }
40a55d20 299 if (_IO_have_markers (fp))
96aa2d94 300 {
05f732b3 301 if (save_for_backup (fp, fp->_IO_read_end))
96aa2d94
RM
302 return EOF;
303 }
40a55d20
UD
304 else if (_IO_have_backup (fp))
305 _IO_free_backup_area (fp);
96aa2d94
RM
306 return _IO_UNDERFLOW (fp);
307}
308
309int
40a55d20
UD
310__uflow (fp)
311 _IO_FILE *fp;
96aa2d94 312{
c9eaa8b9 313 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
d64b6ad0
UD
314 return EOF;
315
40a55d20
UD
316 if (_IO_in_put_mode (fp))
317 if (_IO_switch_to_get_mode (fp) == EOF)
318 return EOF;
96aa2d94 319 if (fp->_IO_read_ptr < fp->_IO_read_end)
40a55d20
UD
320 return *(unsigned char *) fp->_IO_read_ptr++;
321 if (_IO_in_backup (fp))
96aa2d94 322 {
40a55d20 323 _IO_switch_to_main_get_area (fp);
96aa2d94 324 if (fp->_IO_read_ptr < fp->_IO_read_end)
31f7410f 325 return *(unsigned char *) fp->_IO_read_ptr++;
96aa2d94 326 }
40a55d20 327 if (_IO_have_markers (fp))
96aa2d94 328 {
05f732b3 329 if (save_for_backup (fp, fp->_IO_read_end))
96aa2d94
RM
330 return EOF;
331 }
40a55d20
UD
332 else if (_IO_have_backup (fp))
333 _IO_free_backup_area (fp);
96aa2d94
RM
334 return _IO_UFLOW (fp);
335}
336
337void
40a55d20
UD
338_IO_setb (f, b, eb, a)
339 _IO_FILE *f;
340 char *b;
341 char *eb;
342 int a;
96aa2d94
RM
343{
344 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
40a55d20 345 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
96aa2d94
RM
346 f->_IO_buf_base = b;
347 f->_IO_buf_end = eb;
348 if (a)
349 f->_flags &= ~_IO_USER_BUF;
350 else
351 f->_flags |= _IO_USER_BUF;
352}
353
354void
40a55d20
UD
355_IO_doallocbuf (fp)
356 _IO_FILE *fp;
96aa2d94
RM
357{
358 if (fp->_IO_buf_base)
359 return;
360 if (!(fp->_flags & _IO_UNBUFFERED))
361 if (_IO_DOALLOCATE (fp) != EOF)
362 return;
40a55d20 363 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
96aa2d94
RM
364}
365
366int
40a55d20
UD
367_IO_default_underflow (fp)
368 _IO_FILE *fp;
96aa2d94
RM
369{
370 return EOF;
371}
372
373int
40a55d20
UD
374_IO_default_uflow (fp)
375 _IO_FILE *fp;
96aa2d94
RM
376{
377 int ch = _IO_UNDERFLOW (fp);
378 if (ch == EOF)
379 return EOF;
40a55d20 380 return *(unsigned char *) fp->_IO_read_ptr++;
96aa2d94
RM
381}
382
383_IO_size_t
40a55d20
UD
384_IO_default_xsputn (f, data, n)
385 _IO_FILE *f;
386 const void *data;
387 _IO_size_t n;
96aa2d94 388{
40a55d20
UD
389 const char *s = (char *) data;
390 _IO_size_t more = n;
96aa2d94
RM
391 if (more <= 0)
392 return 0;
393 for (;;)
394 {
40a55d20
UD
395 /* Space available. */
396 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
96aa2d94
RM
397 if (count > 0)
398 {
a68b0d31 399 if ((_IO_size_t) count > more)
96aa2d94
RM
400 count = more;
401 if (count > 20)
402 {
86187531
UD
403#ifdef _LIBC
404 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
405#else
40a55d20 406 memcpy (f->_IO_write_ptr, s, count);
96aa2d94 407 f->_IO_write_ptr += count;
86187531
UD
408#endif
409 s += count;
96aa2d94
RM
410 }
411 else if (count <= 0)
412 count = 0;
413 else
414 {
40a55d20
UD
415 char *p = f->_IO_write_ptr;
416 _IO_ssize_t i;
417 for (i = count; --i >= 0; )
418 *p++ = *s++;
96aa2d94
RM
419 f->_IO_write_ptr = p;
420 }
421 more -= count;
422 }
9202ffe3 423 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
96aa2d94
RM
424 break;
425 more--;
426 }
427 return n - more;
428}
429
430_IO_size_t
40a55d20
UD
431_IO_sgetn (fp, data, n)
432 _IO_FILE *fp;
433 void *data;
434 _IO_size_t n;
96aa2d94
RM
435{
436 /* FIXME handle putback buffer here! */
437 return _IO_XSGETN (fp, data, n);
438}
439
440_IO_size_t
40a55d20
UD
441_IO_default_xsgetn (fp, data, n)
442 _IO_FILE *fp;
443 void *data;
444 _IO_size_t n;
96aa2d94 445{
40a55d20
UD
446 _IO_size_t more = n;
447 char *s = (char*) data;
96aa2d94
RM
448 for (;;)
449 {
40a55d20
UD
450 /* Data available. */
451 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
96aa2d94
RM
452 if (count > 0)
453 {
a68b0d31 454 if ((_IO_size_t) count > more)
96aa2d94
RM
455 count = more;
456 if (count > 20)
457 {
86187531
UD
458#ifdef _LIBC
459 s = __mempcpy (s, fp->_IO_read_ptr, count);
460#else
40a55d20 461 memcpy (s, fp->_IO_read_ptr, count);
96aa2d94 462 s += count;
86187531 463#endif
96aa2d94
RM
464 fp->_IO_read_ptr += count;
465 }
466 else if (count <= 0)
467 count = 0;
468 else
469 {
40a55d20
UD
470 char *p = fp->_IO_read_ptr;
471 int i = (int) count;
472 while (--i >= 0)
473 *s++ = *p++;
96aa2d94
RM
474 fp->_IO_read_ptr = p;
475 }
476 more -= count;
477 }
40a55d20 478 if (more == 0 || __underflow (fp) == EOF)
96aa2d94
RM
479 break;
480 }
481 return n - more;
482}
483
40a55d20
UD
484#if 0
485/* Seems not to be needed. --drepper */
96aa2d94 486int
40a55d20
UD
487_IO_sync (fp)
488 _IO_FILE *fp;
96aa2d94
RM
489{
490 return 0;
491}
40a55d20 492#endif
96aa2d94 493
40a55d20
UD
494_IO_FILE *
495_IO_default_setbuf (fp, p, len)
496 _IO_FILE *fp;
497 char *p;
498 _IO_ssize_t len;
96aa2d94
RM
499{
500 if (_IO_SYNC (fp) == EOF)
501 return NULL;
502 if (p == NULL || len == 0)
503 {
504 fp->_flags |= _IO_UNBUFFERED;
40a55d20 505 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
96aa2d94
RM
506 }
507 else
508 {
509 fp->_flags &= ~_IO_UNBUFFERED;
40a55d20 510 _IO_setb (fp, p, p+len, 0);
96aa2d94
RM
511 }
512 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
513 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
514 return fp;
515}
516
d64b6ad0 517_IO_off64_t
40a55d20
UD
518_IO_default_seekpos (fp, pos, mode)
519 _IO_FILE *fp;
d64b6ad0 520 _IO_off64_t pos;
40a55d20 521 int mode;
96aa2d94 522{
d64b6ad0 523 return _IO_SEEKOFF (fp, pos, 0, mode);
96aa2d94
RM
524}
525
526int
40a55d20
UD
527_IO_default_doallocate (fp)
528 _IO_FILE *fp;
96aa2d94 529{
f8b87ef0
UD
530 char *buf;
531
40a55d20
UD
532 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
533 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
96aa2d94
RM
534 return 1;
535}
536
537void
40a55d20
UD
538_IO_init (fp, flags)
539 _IO_FILE *fp;
540 int flags;
d64b6ad0
UD
541{
542 _IO_no_init (fp, flags, -1, NULL, NULL);
543}
544
545void
546_IO_no_init (fp, flags, orientation, wd, jmp)
547 _IO_FILE *fp;
548 int flags;
549 int orientation;
550 struct _IO_wide_data *wd;
551 struct _IO_jump_t *jmp;
96aa2d94
RM
552{
553 fp->_flags = _IO_MAGIC|flags;
554 fp->_IO_buf_base = NULL;
555 fp->_IO_buf_end = NULL;
556 fp->_IO_read_base = NULL;
557 fp->_IO_read_ptr = NULL;
558 fp->_IO_read_end = NULL;
559 fp->_IO_write_base = NULL;
560 fp->_IO_write_ptr = NULL;
561 fp->_IO_write_end = NULL;
562 fp->_chain = NULL; /* Not necessary. */
563
564 fp->_IO_save_base = NULL;
565 fp->_IO_backup_base = NULL;
566 fp->_IO_save_end = NULL;
567 fp->_markers = NULL;
568 fp->_cur_column = 0;
bd355af0
UD
569#if _IO_JUMPS_OFFSET
570 fp->_vtable_offset = 0;
571#endif
7c713e28 572#ifdef _IO_MTSAFE_IO
df4ef2ab 573 _IO_lock_init (*fp->_lock);
7c713e28 574#endif
d64b6ad0
UD
575 fp->_mode = orientation;
576 if (orientation >= 0)
577 {
578 fp->_wide_data = wd;
579 fp->_wide_data->_IO_buf_base = NULL;
580 fp->_wide_data->_IO_buf_end = NULL;
581 fp->_wide_data->_IO_read_base = NULL;
582 fp->_wide_data->_IO_read_ptr = NULL;
583 fp->_wide_data->_IO_read_end = NULL;
584 fp->_wide_data->_IO_write_base = NULL;
585 fp->_wide_data->_IO_write_ptr = NULL;
586 fp->_wide_data->_IO_write_end = NULL;
587 fp->_wide_data->_IO_save_base = NULL;
588 fp->_wide_data->_IO_backup_base = NULL;
589 fp->_wide_data->_IO_save_end = NULL;
590
591 fp->_wide_data->_wide_vtable = jmp;
592 }
96aa2d94
RM
593}
594
595int
40a55d20
UD
596_IO_default_sync (fp)
597 _IO_FILE *fp;
96aa2d94
RM
598{
599 return 0;
600}
601
602/* The way the C++ classes are mapped into the C functions in the
603 current implementation, this function can get called twice! */
604
605void
40a55d20
UD
606_IO_default_finish (fp, dummy)
607 _IO_FILE *fp;
608 int dummy;
96aa2d94
RM
609{
610 struct _IO_marker *mark;
611 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
612 {
40a55d20 613 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
96aa2d94
RM
614 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
615 }
616
617 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
618 mark->_sbuf = NULL;
619
620 if (fp->_IO_save_base)
621 {
622 free (fp->_IO_save_base);
623 fp->_IO_save_base = NULL;
624 }
625
7c713e28 626#ifdef _IO_MTSAFE_IO
68dbb3a6 627 _IO_lock_fini (*fp->_lock);
7c713e28 628#endif
adfa2078 629
2ca8b1ee 630 _IO_un_link ((struct _IO_FILE_plus *) fp);
96aa2d94
RM
631}
632
d64b6ad0 633_IO_off64_t
40a55d20
UD
634_IO_default_seekoff (fp, offset, dir, mode)
635 _IO_FILE *fp;
dfd2257a 636 _IO_off64_t offset;
40a55d20
UD
637 int dir;
638 int mode;
96aa2d94
RM
639{
640 return _IO_pos_BAD;
641}
642
643int
40a55d20
UD
644_IO_sputbackc (fp, c)
645 _IO_FILE *fp;
646 int c;
96aa2d94 647{
19bc17a9 648 int result;
adfa2078 649
96aa2d94
RM
650 if (fp->_IO_read_ptr > fp->_IO_read_base
651 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
652 {
653 fp->_IO_read_ptr--;
40a55d20 654 result = (unsigned char) c;
96aa2d94 655 }
19bc17a9
RM
656 else
657 result = _IO_PBACKFAIL (fp, c);
658
659 if (result != EOF)
660 fp->_flags &= ~_IO_EOF_SEEN;
661
662 return result;
96aa2d94
RM
663}
664
665int
40a55d20
UD
666_IO_sungetc (fp)
667 _IO_FILE *fp;
96aa2d94 668{
19bc17a9 669 int result;
adfa2078 670
96aa2d94
RM
671 if (fp->_IO_read_ptr > fp->_IO_read_base)
672 {
673 fp->_IO_read_ptr--;
40a55d20 674 result = (unsigned char) *fp->_IO_read_ptr;
96aa2d94
RM
675 }
676 else
19bc17a9
RM
677 result = _IO_PBACKFAIL (fp, EOF);
678
679 if (result != EOF)
680 fp->_flags &= ~_IO_EOF_SEEN;
681
682 return result;
96aa2d94
RM
683}
684
685#if 0 /* Work in progress */
40a55d20
UD
686/* Seems not to be needed. */
687#if 0
96aa2d94 688void
40a55d20
UD
689_IO_set_column (fp, c)
690 _IO_FILE *fp;
691 int c;
96aa2d94
RM
692{
693 if (c == -1)
694 fp->_column = -1;
695 else
696 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
697}
698#else
699int
40a55d20
UD
700_IO_set_column (fp, i)
701 _IO_FILE *fp;
702 int i;
96aa2d94 703{
40a55d20 704 fp->_cur_column = i + 1;
96aa2d94
RM
705 return 0;
706}
707#endif
40a55d20 708#endif
96aa2d94
RM
709
710
711unsigned
40a55d20
UD
712_IO_adjust_column (start, line, count)
713 unsigned start;
714 const char *line;
715 int count;
96aa2d94 716{
40a55d20 717 const char *ptr = line + count;
96aa2d94
RM
718 while (ptr > line)
719 if (*--ptr == '\n')
720 return line + count - ptr - 1;
721 return start + count;
722}
723
40a55d20
UD
724#if 0
725/* Seems not to be needed. --drepper */
96aa2d94 726int
40a55d20
UD
727_IO_get_column (fp)
728 _IO_FILE *fp;
96aa2d94 729{
adfa2078 730 if (fp->_cur_column)
40a55d20 731 return _IO_adjust_column (fp->_cur_column - 1,
96aa2d94
RM
732 fp->_IO_write_base,
733 fp->_IO_write_ptr - fp->_IO_write_base);
734 return -1;
735}
40a55d20 736#endif
96aa2d94
RM
737
738int
40a55d20 739_IO_flush_all ()
96aa2d94
RM
740{
741 int result = 0;
2ca8b1ee
GM
742 struct _IO_FILE_plus *fp;
743 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
744 if (((fp->file._mode < 0 && fp->file._IO_write_ptr > fp->file._IO_write_base)
745 || (fp->file._vtable_offset == 0
746 && fp->file._mode > 0 && (fp->file._wide_data->_IO_write_ptr
747 > fp->file._wide_data->_IO_write_base)))
748 && _IO_OVERFLOW (&fp->file, EOF) == EOF)
96aa2d94
RM
749 result = EOF;
750 return result;
751}
752
753void
40a55d20 754_IO_flush_all_linebuffered ()
96aa2d94 755{
2ca8b1ee
GM
756 struct _IO_FILE_plus *fp;
757 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
758 if ((fp->file._flags & _IO_NO_WRITES) == 0 && fp->file._flags & _IO_LINE_BUF)
759 _IO_OVERFLOW (&fp->file, EOF);
96aa2d94
RM
760}
761
628a0aa1 762static void _IO_unbuffer_write __P ((void));
40a55d20
UD
763
764static void
628a0aa1 765_IO_unbuffer_write ()
96aa2d94 766{
2ca8b1ee
GM
767 struct _IO_FILE_plus *fp;
768 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
769 if (! (fp->file._flags & _IO_UNBUFFERED)
770 && (! (fp->file._flags & _IO_NO_WRITES)
771 || (fp->file._flags & _IO_IS_APPENDING)))
772 _IO_SETBUF (&fp->file, NULL, 0);
96aa2d94
RM
773}
774
310b3460 775int
40a55d20 776_IO_cleanup ()
96aa2d94 777{
310b3460 778 int result = _IO_flush_all ();
96aa2d94
RM
779
780 /* We currently don't have a reliable mechanism for making sure that
781 C++ static destructors are executed in the correct order.
6d52618b 782 So it is possible that other static destructors might want to
96aa2d94
RM
783 write to cout - and they're supposed to be able to do so.
784
adfa2078 785 The following will make the standard streambufs be unbuffered,
96aa2d94 786 which forces any output from late destructors to be written out. */
628a0aa1 787 _IO_unbuffer_write ();
310b3460
UD
788
789 return result;
96aa2d94
RM
790}
791
f2ea0f5b 792
96aa2d94 793void
40a55d20
UD
794_IO_init_marker (marker, fp)
795 struct _IO_marker *marker;
796 _IO_FILE *fp;
96aa2d94
RM
797{
798 marker->_sbuf = fp;
40a55d20
UD
799 if (_IO_in_put_mode (fp))
800 _IO_switch_to_get_mode (fp);
801 if (_IO_in_backup (fp))
96aa2d94
RM
802 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
803 else
804 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
adfa2078 805
96aa2d94
RM
806 /* Should perhaps sort the chain? */
807 marker->_next = fp->_markers;
808 fp->_markers = marker;
809}
810
811void
40a55d20
UD
812_IO_remove_marker (marker)
813 struct _IO_marker *marker;
96aa2d94
RM
814{
815 /* Unlink from sb's chain. */
40a55d20 816 struct _IO_marker **ptr = &marker->_sbuf->_markers;
96aa2d94
RM
817 for (; ; ptr = &(*ptr)->_next)
818 {
819 if (*ptr == NULL)
820 break;
821 else if (*ptr == marker)
822 {
823 *ptr = marker->_next;
824 return;
825 }
826 }
827#if 0
828 if _sbuf has a backup area that is no longer needed, should we delete
829 it now, or wait until the next underflow?
830#endif
831}
832
833#define BAD_DELTA EOF
834
835int
40a55d20
UD
836_IO_marker_difference (mark1, mark2)
837 struct _IO_marker *mark1;
838 struct _IO_marker *mark2;
96aa2d94
RM
839{
840 return mark1->_pos - mark2->_pos;
841}
842
6d52618b 843/* Return difference between MARK and current position of MARK's stream. */
96aa2d94 844int
40a55d20
UD
845_IO_marker_delta (mark)
846 struct _IO_marker *mark;
96aa2d94
RM
847{
848 int cur_pos;
849 if (mark->_sbuf == NULL)
850 return BAD_DELTA;
40a55d20 851 if (_IO_in_backup (mark->_sbuf))
96aa2d94
RM
852 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
853 else
854 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
855 return mark->_pos - cur_pos;
856}
857
858int
40a55d20
UD
859_IO_seekmark (fp, mark, delta)
860 _IO_FILE *fp;
861 struct _IO_marker *mark;
862 int delta;
96aa2d94
RM
863{
864 if (mark->_sbuf != fp)
865 return EOF;
866 if (mark->_pos >= 0)
867 {
40a55d20
UD
868 if (_IO_in_backup (fp))
869 _IO_switch_to_main_get_area (fp);
96aa2d94
RM
870 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
871 }
872 else
873 {
40a55d20 874 if (!_IO_in_backup (fp))
05f732b3 875 _IO_switch_to_backup_area (fp);
96aa2d94
RM
876 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
877 }
878 return 0;
879}
880
881void
40a55d20
UD
882_IO_unsave_markers (fp)
883 _IO_FILE *fp;
96aa2d94 884{
40a55d20 885 struct _IO_marker *mark = fp->_markers;
96aa2d94
RM
886 if (mark)
887 {
888#ifdef TODO
40a55d20 889 streampos offset = seekoff (0, ios::cur, ios::in);
96aa2d94
RM
890 if (offset != EOF)
891 {
40a55d20 892 offset += eGptr () - Gbase ();
96aa2d94 893 for ( ; mark != NULL; mark = mark->_next)
40a55d20 894 mark->set_streampos (mark->_pos + offset);
96aa2d94
RM
895 }
896 else
897 {
898 for ( ; mark != NULL; mark = mark->_next)
40a55d20 899 mark->set_streampos (EOF);
96aa2d94
RM
900 }
901#endif
902 fp->_markers = 0;
903 }
904
40a55d20
UD
905 if (_IO_have_backup (fp))
906 _IO_free_backup_area (fp);
96aa2d94
RM
907}
908
40a55d20
UD
909#if 0
910/* Seems not to be needed. --drepper */
96aa2d94 911int
40a55d20
UD
912_IO_nobackup_pbackfail (fp, c)
913 _IO_FILE *fp;
914 int c;
96aa2d94
RM
915{
916 if (fp->_IO_read_ptr > fp->_IO_read_base)
917 fp->_IO_read_ptr--;
918 if (c != EOF && *fp->_IO_read_ptr != c)
919 *fp->_IO_read_ptr = c;
40a55d20 920 return (unsigned char) c;
96aa2d94 921}
40a55d20 922#endif
96aa2d94
RM
923
924int
40a55d20
UD
925_IO_default_pbackfail (fp, c)
926 _IO_FILE *fp;
927 int c;
96aa2d94 928{
00bc5db0 929 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
c94a8080 930 && (unsigned char) fp->_IO_read_ptr[-1] == c)
00bc5db0
UD
931 --fp->_IO_read_ptr;
932 else
40a55d20
UD
933 {
934 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
05f732b3 935 if (!_IO_in_backup (fp))
40a55d20 936 {
05f732b3
UD
937 /* We need to keep the invariant that the main get area
938 logically follows the backup area. */
939 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
940 {
941 if (save_for_backup (fp, fp->_IO_read_ptr))
942 return EOF;
943 }
944 else if (!_IO_have_backup (fp))
945 {
946 /* No backup buffer: allocate one. */
947 /* Use nshort buffer, if unused? (probably not) FIXME */
948 int backup_size = 128;
949 char *bbuf = (char *) malloc (backup_size);
950 if (bbuf == NULL)
951 return EOF;
952 fp->_IO_save_base = bbuf;
953 fp->_IO_save_end = fp->_IO_save_base + backup_size;
954 fp->_IO_backup_base = fp->_IO_save_end;
955 }
956 fp->_IO_read_base = fp->_IO_read_ptr;
40a55d20
UD
957 _IO_switch_to_backup_area (fp);
958 }
959 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
960 {
961 /* Increase size of existing backup buffer. */
962 _IO_size_t new_size;
963 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
964 char *new_buf;
965 new_size = 2 * old_size;
966 new_buf = (char *) malloc (new_size);
967 if (new_buf == NULL)
968 return EOF;
969 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
970 old_size);
971 free (fp->_IO_read_base);
972 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
973 new_buf + new_size);
974 fp->_IO_backup_base = fp->_IO_read_ptr;
975 }
00bc5db0
UD
976
977 *--fp->_IO_read_ptr = c;
40a55d20 978 }
00bc5db0 979 return (unsigned char) c;
96aa2d94
RM
980}
981
d64b6ad0 982_IO_off64_t
40a55d20
UD
983_IO_default_seek (fp, offset, dir)
984 _IO_FILE *fp;
dfd2257a 985 _IO_off64_t offset;
40a55d20 986 int dir;
96aa2d94
RM
987{
988 return _IO_pos_BAD;
989}
990
991int
40a55d20
UD
992_IO_default_stat (fp, st)
993 _IO_FILE *fp;
994 void* st;
96aa2d94
RM
995{
996 return EOF;
997}
998
999_IO_ssize_t
40a55d20
UD
1000_IO_default_read (fp, data, n)
1001 _IO_FILE* fp;
1002 void *data;
1003 _IO_ssize_t n;
96aa2d94
RM
1004{
1005 return -1;
1006}
1007
1008_IO_ssize_t
40a55d20
UD
1009_IO_default_write (fp, data, n)
1010 _IO_FILE *fp;
1011 const void *data;
1012 _IO_ssize_t n;
96aa2d94
RM
1013{
1014 return 0;
1015}
1016
dfd2257a
UD
1017int
1018_IO_default_showmanyc (fp)
1019 _IO_FILE *fp;
1020{
1021 return -1;
1022}
1023
1024void
1025_IO_default_imbue (fp, locale)
1026 _IO_FILE *fp;
1027 void *locale;
1028{
1029}
1030
3fc9ca4e
UD
1031_IO_ITER
1032_IO_iter_begin()
1033{
1034 return _IO_list_all;
1035}
1036
1037_IO_ITER
1038_IO_iter_end()
1039{
2ca8b1ee 1040 return NULL;
3fc9ca4e
UD
1041}
1042
1043_IO_ITER
1044_IO_iter_next(iter)
1045 _IO_ITER iter;
1046{
2ca8b1ee 1047 return iter->file._chain;
3fc9ca4e
UD
1048}
1049
1050_IO_FILE *
1051_IO_iter_file(iter)
1052 _IO_ITER iter;
1053{
2ca8b1ee 1054 return (_IO_FILE *) iter;
3fc9ca4e
UD
1055}
1056
1057void
1058_IO_list_lock()
1059{
92cfdd8a 1060#ifdef _IO_MTSAFE_IO
3fc9ca4e 1061 _IO_lock_lock (list_all_lock);
92cfdd8a 1062#endif
3fc9ca4e
UD
1063}
1064
1065void
1066_IO_list_unlock()
1067{
92cfdd8a
AJ
1068#ifdef _IO_MTSAFE_IO
1069 _IO_lock_unlock (list_all_lock);
1070#endif
3fc9ca4e
UD
1071}
1072
1073void
1074_IO_list_resetlock()
1075{
92cfdd8a 1076#ifdef _IO_MTSAFE_IO
3fc9ca4e 1077 _IO_lock_init (list_all_lock);
92cfdd8a 1078#endif
3fc9ca4e
UD
1079}
1080
96aa2d94
RM
1081
1082#ifdef TODO
1083#if defined(linux)
1084#define IO_CLEANUP ;
1085#endif
1086
1087#ifdef IO_CLEANUP
1088 IO_CLEANUP
1089#else
1090struct __io_defs {
1091 __io_defs() { }
40a55d20 1092 ~__io_defs() { _IO_cleanup (); }
adfa2078 1093};
96aa2d94
RM
1094__io_defs io_defs__;
1095#endif
1096
1097#endif /* TODO */
adfa2078
UD
1098
1099#ifdef weak_alias
1100weak_alias (_IO_cleanup, _cleanup)
1101#endif
f65fd747
UD
1102
1103#ifdef text_set_element
1104text_set_element(__libc_atexit, _cleanup);
1105#endif
This page took 0.237673 seconds and 5 git commands to generate.