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