]> sourceware.org Git - glibc.git/blame - libio/genops.c
Update.
[glibc.git] / libio / genops.c
CommitLineData
51e176c2 1/* Copyright (C) 1993, 1995, 1997, 1998, 1999 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
UD
39_IO_un_link (fp)
40 _IO_FILE *fp;
41{
42 if (fp->_flags & _IO_LINKED)
43 {
44 _IO_FILE **f;
d328b80b 45#ifdef _IO_MTSAFE_IO
118bad87 46 _IO_lock_lock (list_all_lock);
51e176c2 47#endif
40a55d20
UD
48 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
49 {
50 if (*f == fp)
51 {
52 *f = fp->_chain;
53 break;
54 }
55 }
51e176c2 56#ifdef _IO_MTSAFE_IO
118bad87 57 _IO_lock_unlock (list_all_lock);
51e176c2 58#endif
40a55d20 59 fp->_flags &= ~_IO_LINKED;
96aa2d94 60 }
96aa2d94
RM
61}
62
63void
40a55d20
UD
64_IO_link_in (fp)
65 _IO_FILE *fp;
96aa2d94 66{
40a55d20
UD
67 if ((fp->_flags & _IO_LINKED) == 0)
68 {
96aa2d94 69 fp->_flags |= _IO_LINKED;
51e176c2 70#ifdef _IO_MTSAFE_IO
118bad87 71 _IO_lock_lock (list_all_lock);
51e176c2 72#endif
96aa2d94
RM
73 fp->_chain = _IO_list_all;
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{
d64b6ad0
UD
285 if (_IO_fwide (fp, -1) != -1)
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{
d64b6ad0
UD
313 if (_IO_fwide (fp, -1) != -1)
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 }
40a55d20 423 if (more == 0 || __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
40a55d20 630 _IO_un_link (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;
742 _IO_FILE *fp;
743 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
d64b6ad0
UD
744 if (((fp->_mode < 0 && fp->_IO_write_ptr > fp->_IO_write_base)
745 || (fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
746 > fp->_wide_data->_IO_write_base)))
96aa2d94
RM
747 && _IO_OVERFLOW (fp, EOF) == EOF)
748 result = EOF;
749 return result;
750}
751
752void
40a55d20 753_IO_flush_all_linebuffered ()
96aa2d94
RM
754{
755 _IO_FILE *fp;
756 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
63551311 757 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
96aa2d94
RM
758 _IO_OVERFLOW (fp, EOF);
759}
760
628a0aa1 761static void _IO_unbuffer_write __P ((void));
40a55d20
UD
762
763static void
628a0aa1 764_IO_unbuffer_write ()
96aa2d94
RM
765{
766 _IO_FILE *fp;
767 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
628a0aa1
UD
768 if (! (fp->_flags & _IO_UNBUFFERED)
769 && (! (fp->_flags & _IO_NO_WRITES)
770 || (fp->_flags & _IO_IS_APPENDING)))
96aa2d94
RM
771 _IO_SETBUF (fp, NULL, 0);
772}
773
310b3460 774int
40a55d20 775_IO_cleanup ()
96aa2d94 776{
310b3460 777 int result = _IO_flush_all ();
96aa2d94
RM
778
779 /* We currently don't have a reliable mechanism for making sure that
780 C++ static destructors are executed in the correct order.
6d52618b 781 So it is possible that other static destructors might want to
96aa2d94
RM
782 write to cout - and they're supposed to be able to do so.
783
adfa2078 784 The following will make the standard streambufs be unbuffered,
96aa2d94 785 which forces any output from late destructors to be written out. */
628a0aa1 786 _IO_unbuffer_write ();
310b3460
UD
787
788 return result;
96aa2d94
RM
789}
790
f2ea0f5b 791
96aa2d94 792void
40a55d20
UD
793_IO_init_marker (marker, fp)
794 struct _IO_marker *marker;
795 _IO_FILE *fp;
96aa2d94
RM
796{
797 marker->_sbuf = fp;
40a55d20
UD
798 if (_IO_in_put_mode (fp))
799 _IO_switch_to_get_mode (fp);
800 if (_IO_in_backup (fp))
96aa2d94
RM
801 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
802 else
803 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
adfa2078 804
96aa2d94
RM
805 /* Should perhaps sort the chain? */
806 marker->_next = fp->_markers;
807 fp->_markers = marker;
808}
809
810void
40a55d20
UD
811_IO_remove_marker (marker)
812 struct _IO_marker *marker;
96aa2d94
RM
813{
814 /* Unlink from sb's chain. */
40a55d20 815 struct _IO_marker **ptr = &marker->_sbuf->_markers;
96aa2d94
RM
816 for (; ; ptr = &(*ptr)->_next)
817 {
818 if (*ptr == NULL)
819 break;
820 else if (*ptr == marker)
821 {
822 *ptr = marker->_next;
823 return;
824 }
825 }
826#if 0
827 if _sbuf has a backup area that is no longer needed, should we delete
828 it now, or wait until the next underflow?
829#endif
830}
831
832#define BAD_DELTA EOF
833
834int
40a55d20
UD
835_IO_marker_difference (mark1, mark2)
836 struct _IO_marker *mark1;
837 struct _IO_marker *mark2;
96aa2d94
RM
838{
839 return mark1->_pos - mark2->_pos;
840}
841
6d52618b 842/* Return difference between MARK and current position of MARK's stream. */
96aa2d94 843int
40a55d20
UD
844_IO_marker_delta (mark)
845 struct _IO_marker *mark;
96aa2d94
RM
846{
847 int cur_pos;
848 if (mark->_sbuf == NULL)
849 return BAD_DELTA;
40a55d20 850 if (_IO_in_backup (mark->_sbuf))
96aa2d94
RM
851 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
852 else
853 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
854 return mark->_pos - cur_pos;
855}
856
857int
40a55d20
UD
858_IO_seekmark (fp, mark, delta)
859 _IO_FILE *fp;
860 struct _IO_marker *mark;
861 int delta;
96aa2d94
RM
862{
863 if (mark->_sbuf != fp)
864 return EOF;
865 if (mark->_pos >= 0)
866 {
40a55d20
UD
867 if (_IO_in_backup (fp))
868 _IO_switch_to_main_get_area (fp);
96aa2d94
RM
869 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
870 }
871 else
872 {
40a55d20 873 if (!_IO_in_backup (fp))
05f732b3 874 _IO_switch_to_backup_area (fp);
96aa2d94
RM
875 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
876 }
877 return 0;
878}
879
880void
40a55d20
UD
881_IO_unsave_markers (fp)
882 _IO_FILE *fp;
96aa2d94 883{
40a55d20 884 struct _IO_marker *mark = fp->_markers;
96aa2d94
RM
885 if (mark)
886 {
887#ifdef TODO
40a55d20 888 streampos offset = seekoff (0, ios::cur, ios::in);
96aa2d94
RM
889 if (offset != EOF)
890 {
40a55d20 891 offset += eGptr () - Gbase ();
96aa2d94 892 for ( ; mark != NULL; mark = mark->_next)
40a55d20 893 mark->set_streampos (mark->_pos + offset);
96aa2d94
RM
894 }
895 else
896 {
897 for ( ; mark != NULL; mark = mark->_next)
40a55d20 898 mark->set_streampos (EOF);
96aa2d94
RM
899 }
900#endif
901 fp->_markers = 0;
902 }
903
40a55d20
UD
904 if (_IO_have_backup (fp))
905 _IO_free_backup_area (fp);
96aa2d94
RM
906}
907
40a55d20
UD
908#if 0
909/* Seems not to be needed. --drepper */
96aa2d94 910int
40a55d20
UD
911_IO_nobackup_pbackfail (fp, c)
912 _IO_FILE *fp;
913 int c;
96aa2d94
RM
914{
915 if (fp->_IO_read_ptr > fp->_IO_read_base)
916 fp->_IO_read_ptr--;
917 if (c != EOF && *fp->_IO_read_ptr != c)
918 *fp->_IO_read_ptr = c;
40a55d20 919 return (unsigned char) c;
96aa2d94 920}
40a55d20 921#endif
96aa2d94
RM
922
923int
40a55d20
UD
924_IO_default_pbackfail (fp, c)
925 _IO_FILE *fp;
926 int c;
96aa2d94 927{
00bc5db0 928 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
c94a8080 929 && (unsigned char) fp->_IO_read_ptr[-1] == c)
00bc5db0
UD
930 --fp->_IO_read_ptr;
931 else
40a55d20
UD
932 {
933 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
05f732b3 934 if (!_IO_in_backup (fp))
40a55d20 935 {
05f732b3
UD
936 /* We need to keep the invariant that the main get area
937 logically follows the backup area. */
938 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
939 {
940 if (save_for_backup (fp, fp->_IO_read_ptr))
941 return EOF;
942 }
943 else if (!_IO_have_backup (fp))
944 {
945 /* No backup buffer: allocate one. */
946 /* Use nshort buffer, if unused? (probably not) FIXME */
947 int backup_size = 128;
948 char *bbuf = (char *) malloc (backup_size);
949 if (bbuf == NULL)
950 return EOF;
951 fp->_IO_save_base = bbuf;
952 fp->_IO_save_end = fp->_IO_save_base + backup_size;
953 fp->_IO_backup_base = fp->_IO_save_end;
954 }
955 fp->_IO_read_base = fp->_IO_read_ptr;
40a55d20
UD
956 _IO_switch_to_backup_area (fp);
957 }
958 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
959 {
960 /* Increase size of existing backup buffer. */
961 _IO_size_t new_size;
962 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
963 char *new_buf;
964 new_size = 2 * old_size;
965 new_buf = (char *) malloc (new_size);
966 if (new_buf == NULL)
967 return EOF;
968 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
969 old_size);
970 free (fp->_IO_read_base);
971 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
972 new_buf + new_size);
973 fp->_IO_backup_base = fp->_IO_read_ptr;
974 }
00bc5db0
UD
975
976 *--fp->_IO_read_ptr = c;
40a55d20 977 }
00bc5db0 978 return (unsigned char) c;
96aa2d94
RM
979}
980
d64b6ad0 981_IO_off64_t
40a55d20
UD
982_IO_default_seek (fp, offset, dir)
983 _IO_FILE *fp;
dfd2257a 984 _IO_off64_t offset;
40a55d20 985 int dir;
96aa2d94
RM
986{
987 return _IO_pos_BAD;
988}
989
990int
40a55d20
UD
991_IO_default_stat (fp, st)
992 _IO_FILE *fp;
993 void* st;
96aa2d94
RM
994{
995 return EOF;
996}
997
998_IO_ssize_t
40a55d20
UD
999_IO_default_read (fp, data, n)
1000 _IO_FILE* fp;
1001 void *data;
1002 _IO_ssize_t n;
96aa2d94
RM
1003{
1004 return -1;
1005}
1006
1007_IO_ssize_t
40a55d20
UD
1008_IO_default_write (fp, data, n)
1009 _IO_FILE *fp;
1010 const void *data;
1011 _IO_ssize_t n;
96aa2d94
RM
1012{
1013 return 0;
1014}
1015
dfd2257a
UD
1016int
1017_IO_default_showmanyc (fp)
1018 _IO_FILE *fp;
1019{
1020 return -1;
1021}
1022
1023void
1024_IO_default_imbue (fp, locale)
1025 _IO_FILE *fp;
1026 void *locale;
1027{
1028}
1029
96aa2d94
RM
1030
1031#ifdef TODO
1032#if defined(linux)
1033#define IO_CLEANUP ;
1034#endif
1035
1036#ifdef IO_CLEANUP
1037 IO_CLEANUP
1038#else
1039struct __io_defs {
1040 __io_defs() { }
40a55d20 1041 ~__io_defs() { _IO_cleanup (); }
adfa2078 1042};
96aa2d94
RM
1043__io_defs io_defs__;
1044#endif
1045
1046#endif /* TODO */
adfa2078
UD
1047
1048#ifdef weak_alias
1049weak_alias (_IO_cleanup, _cleanup)
1050#endif
f65fd747
UD
1051
1052#ifdef text_set_element
1053text_set_element(__libc_atexit, _cleanup);
1054#endif
This page took 0.209715 seconds and 5 git commands to generate.