xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/libio/genops.c (revision c2fb321235c8dbfba0909bc43913400e90646ae7)
103a78d15Sespie /* Copyright (C) 1993, 1995, 1997-1999, 2000 Free Software Foundation, Inc.
203a78d15Sespie    This file is part of the GNU IO Library.
303a78d15Sespie 
403a78d15Sespie    This library is free software; you can redistribute it and/or
503a78d15Sespie    modify it under the terms of the GNU General Public License as
603a78d15Sespie    published by the Free Software Foundation; either version 2, or (at
703a78d15Sespie    your option) any later version.
803a78d15Sespie 
903a78d15Sespie    This library is distributed in the hope that it will be useful, but
1003a78d15Sespie    WITHOUT ANY WARRANTY; without even the implied warranty of
1103a78d15Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1203a78d15Sespie    General Public License for more details.
1303a78d15Sespie 
1403a78d15Sespie    You should have received a copy of the GNU General Public License
1503a78d15Sespie    along with this library; see the file COPYING.  If not, write to
1603a78d15Sespie    the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
1703a78d15Sespie    MA 02111-1307, USA.
1803a78d15Sespie 
1903a78d15Sespie    As a special exception, if you link this library with files
2003a78d15Sespie    compiled with a GNU compiler to produce an executable, this does
2103a78d15Sespie    not cause the resulting executable to be covered by the GNU General
2203a78d15Sespie    Public License.  This exception does not however invalidate any
2303a78d15Sespie    other reasons why the executable file might be covered by the GNU
2403a78d15Sespie    General Public License.  */
2503a78d15Sespie 
2603a78d15Sespie /* Generic or default I/O operations. */
2703a78d15Sespie 
2803a78d15Sespie #include "libioP.h"
2903a78d15Sespie #ifdef __STDC__
3003a78d15Sespie #include <stdlib.h>
3103a78d15Sespie #endif
3203a78d15Sespie #include <string.h>
3303a78d15Sespie 
3403a78d15Sespie #ifdef _IO_MTSAFE_IO
3503a78d15Sespie static _IO_lock_t list_all_lock = _IO_lock_initializer;
3603a78d15Sespie #endif
3703a78d15Sespie 
3803a78d15Sespie void
_IO_un_link(fp)3903a78d15Sespie _IO_un_link (fp)
4003a78d15Sespie      struct _IO_FILE_plus *fp;
4103a78d15Sespie {
4203a78d15Sespie   if (fp->file._flags & _IO_LINKED)
4303a78d15Sespie     {
4403a78d15Sespie       struct _IO_FILE_plus **f;
4503a78d15Sespie #ifdef _IO_MTSAFE_IO
4603a78d15Sespie       _IO_lock_lock (list_all_lock);
4703a78d15Sespie #endif
4803a78d15Sespie       for (f = &_IO_list_all; *f; f = (struct _IO_FILE_plus **) &(*f)->file._chain)
4903a78d15Sespie 	{
5003a78d15Sespie 	  if (*f == fp)
5103a78d15Sespie 	    {
5203a78d15Sespie 	      *f = (struct _IO_FILE_plus *) fp->file._chain;
5303a78d15Sespie 	      break;
5403a78d15Sespie 	    }
5503a78d15Sespie 	}
5603a78d15Sespie #ifdef _IO_MTSAFE_IO
5703a78d15Sespie       _IO_lock_unlock (list_all_lock);
5803a78d15Sespie #endif
5903a78d15Sespie       fp->file._flags &= ~_IO_LINKED;
6003a78d15Sespie     }
6103a78d15Sespie }
6203a78d15Sespie 
6303a78d15Sespie void
_IO_link_in(fp)6403a78d15Sespie _IO_link_in (fp)
6503a78d15Sespie      struct _IO_FILE_plus *fp;
6603a78d15Sespie {
6703a78d15Sespie     if ((fp->file._flags & _IO_LINKED) == 0)
6803a78d15Sespie       {
6903a78d15Sespie 	fp->file._flags |= _IO_LINKED;
7003a78d15Sespie #ifdef _IO_MTSAFE_IO
7103a78d15Sespie 	_IO_lock_lock (list_all_lock);
7203a78d15Sespie #endif
7303a78d15Sespie 	fp->file._chain = (_IO_FILE *) _IO_list_all;
7403a78d15Sespie 	_IO_list_all = fp;
7503a78d15Sespie #ifdef _IO_MTSAFE_IO
7603a78d15Sespie 	_IO_lock_unlock (list_all_lock);
7703a78d15Sespie #endif
7803a78d15Sespie       }
7903a78d15Sespie }
8003a78d15Sespie 
8103a78d15Sespie /* Return minimum _pos markers
8203a78d15Sespie    Assumes the current get area is the main get area. */
8303a78d15Sespie _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
8403a78d15Sespie 
8503a78d15Sespie _IO_ssize_t
_IO_least_marker(fp,end_p)8603a78d15Sespie _IO_least_marker (fp, end_p)
8703a78d15Sespie      _IO_FILE *fp;
8803a78d15Sespie      char *end_p;
8903a78d15Sespie {
9003a78d15Sespie   _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
9103a78d15Sespie   struct _IO_marker *mark;
9203a78d15Sespie   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
9303a78d15Sespie     if (mark->_pos < least_so_far)
9403a78d15Sespie       least_so_far = mark->_pos;
9503a78d15Sespie   return least_so_far;
9603a78d15Sespie }
9703a78d15Sespie 
9803a78d15Sespie /* Switch current get area from backup buffer to (start of) main get area. */
9903a78d15Sespie 
10003a78d15Sespie void
_IO_switch_to_main_get_area(fp)10103a78d15Sespie _IO_switch_to_main_get_area (fp)
10203a78d15Sespie      _IO_FILE *fp;
10303a78d15Sespie {
10403a78d15Sespie   char *tmp;
10503a78d15Sespie   fp->_flags &= ~_IO_IN_BACKUP;
10603a78d15Sespie   /* Swap _IO_read_end and _IO_save_end. */
10703a78d15Sespie   tmp = fp->_IO_read_end;
10803a78d15Sespie   fp->_IO_read_end = fp->_IO_save_end;
10903a78d15Sespie   fp->_IO_save_end= tmp;
11003a78d15Sespie   /* Swap _IO_read_base and _IO_save_base. */
11103a78d15Sespie   tmp = fp->_IO_read_base;
11203a78d15Sespie   fp->_IO_read_base = fp->_IO_save_base;
11303a78d15Sespie   fp->_IO_save_base = tmp;
11403a78d15Sespie   /* Set _IO_read_ptr. */
11503a78d15Sespie   fp->_IO_read_ptr = fp->_IO_read_base;
11603a78d15Sespie }
11703a78d15Sespie 
11803a78d15Sespie /* Switch current get area from main get area to (end of) backup area. */
11903a78d15Sespie 
12003a78d15Sespie void
_IO_switch_to_backup_area(fp)12103a78d15Sespie _IO_switch_to_backup_area (fp)
12203a78d15Sespie      _IO_FILE *fp;
12303a78d15Sespie {
12403a78d15Sespie   char *tmp;
12503a78d15Sespie   fp->_flags |= _IO_IN_BACKUP;
12603a78d15Sespie   /* Swap _IO_read_end and _IO_save_end. */
12703a78d15Sespie   tmp = fp->_IO_read_end;
12803a78d15Sespie   fp->_IO_read_end = fp->_IO_save_end;
12903a78d15Sespie   fp->_IO_save_end = tmp;
13003a78d15Sespie   /* Swap _IO_read_base and _IO_save_base. */
13103a78d15Sespie   tmp = fp->_IO_read_base;
13203a78d15Sespie   fp->_IO_read_base = fp->_IO_save_base;
13303a78d15Sespie   fp->_IO_save_base = tmp;
13403a78d15Sespie   /* Set _IO_read_ptr.  */
13503a78d15Sespie   fp->_IO_read_ptr = fp->_IO_read_end;
13603a78d15Sespie }
13703a78d15Sespie 
13803a78d15Sespie int
_IO_switch_to_get_mode(fp)13903a78d15Sespie _IO_switch_to_get_mode (fp)
14003a78d15Sespie      _IO_FILE *fp;
14103a78d15Sespie {
14203a78d15Sespie   if (fp->_IO_write_ptr > fp->_IO_write_base)
14303a78d15Sespie     if (_IO_OVERFLOW (fp, EOF) == EOF)
14403a78d15Sespie       return EOF;
14503a78d15Sespie   if (_IO_in_backup (fp))
14603a78d15Sespie     fp->_IO_read_base = fp->_IO_backup_base;
14703a78d15Sespie   else
14803a78d15Sespie     {
14903a78d15Sespie       fp->_IO_read_base = fp->_IO_buf_base;
15003a78d15Sespie       if (fp->_IO_write_ptr > fp->_IO_read_end)
15103a78d15Sespie 	fp->_IO_read_end = fp->_IO_write_ptr;
15203a78d15Sespie     }
15303a78d15Sespie   fp->_IO_read_ptr = fp->_IO_write_ptr;
15403a78d15Sespie 
15503a78d15Sespie   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
15603a78d15Sespie 
15703a78d15Sespie   fp->_flags &= ~_IO_CURRENTLY_PUTTING;
15803a78d15Sespie   return 0;
15903a78d15Sespie }
16003a78d15Sespie 
16103a78d15Sespie void
_IO_free_backup_area(fp)16203a78d15Sespie _IO_free_backup_area (fp)
16303a78d15Sespie      _IO_FILE *fp;
16403a78d15Sespie {
16503a78d15Sespie   if (_IO_in_backup (fp))
16603a78d15Sespie     _IO_switch_to_main_get_area (fp);  /* Just in case. */
16703a78d15Sespie   free (fp->_IO_save_base);
16803a78d15Sespie   fp->_IO_save_base = NULL;
16903a78d15Sespie   fp->_IO_save_end = NULL;
17003a78d15Sespie   fp->_IO_backup_base = NULL;
17103a78d15Sespie }
17203a78d15Sespie 
17303a78d15Sespie #if 0
17403a78d15Sespie int
17503a78d15Sespie _IO_switch_to_put_mode (fp)
17603a78d15Sespie      _IO_FILE *fp;
17703a78d15Sespie {
17803a78d15Sespie   fp->_IO_write_base = fp->_IO_read_ptr;
17903a78d15Sespie   fp->_IO_write_ptr = fp->_IO_read_ptr;
18003a78d15Sespie   /* Following is wrong if line- or un-buffered? */
18103a78d15Sespie   fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
18203a78d15Sespie 		       ? fp->_IO_read_end : fp->_IO_buf_end);
18303a78d15Sespie 
18403a78d15Sespie   fp->_IO_read_ptr = fp->_IO_read_end;
18503a78d15Sespie   fp->_IO_read_base = fp->_IO_read_end;
18603a78d15Sespie 
18703a78d15Sespie   fp->_flags |= _IO_CURRENTLY_PUTTING;
18803a78d15Sespie   return 0;
18903a78d15Sespie }
19003a78d15Sespie #endif
19103a78d15Sespie 
19203a78d15Sespie int
__overflow(f,ch)19303a78d15Sespie __overflow (f, ch)
19403a78d15Sespie      _IO_FILE *f;
19503a78d15Sespie      int ch;
19603a78d15Sespie {
19703a78d15Sespie   /* This is a single-byte stream.  */
19803a78d15Sespie   if (f->_mode == 0)
19903a78d15Sespie     _IO_fwide (f, -1);
20003a78d15Sespie   return _IO_OVERFLOW (f, ch);
20103a78d15Sespie }
20203a78d15Sespie 
20303a78d15Sespie static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
20403a78d15Sespie #ifdef _LIBC
20503a78d15Sespie      internal_function
20603a78d15Sespie #endif
20703a78d15Sespie      ;
20803a78d15Sespie 
20903a78d15Sespie static int
21003a78d15Sespie #ifdef _LIBC
21103a78d15Sespie internal_function
21203a78d15Sespie #endif
save_for_backup(fp,end_p)21303a78d15Sespie save_for_backup (fp, end_p)
21403a78d15Sespie      _IO_FILE *fp;
21503a78d15Sespie      char *end_p;
21603a78d15Sespie {
21703a78d15Sespie   /* Append [_IO_read_base..end_p] to backup area. */
21803a78d15Sespie   _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
21903a78d15Sespie   /* needed_size is how much space we need in the backup area. */
22003a78d15Sespie   _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
22103a78d15Sespie   /* FIXME: Dubious arithmetic if pointers are NULL */
22203a78d15Sespie   _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
22303a78d15Sespie   _IO_size_t avail; /* Extra space available for future expansion. */
22403a78d15Sespie   _IO_ssize_t delta;
22503a78d15Sespie   struct _IO_marker *mark;
22603a78d15Sespie   if (needed_size > current_Bsize)
22703a78d15Sespie     {
22803a78d15Sespie       char *new_buffer;
22903a78d15Sespie       avail = 100;
23003a78d15Sespie       new_buffer = (char *) malloc (avail + needed_size);
23103a78d15Sespie       if (new_buffer == NULL)
23203a78d15Sespie 	return EOF;		/* FIXME */
23303a78d15Sespie       if (least_mark < 0)
23403a78d15Sespie 	{
23503a78d15Sespie #ifdef _LIBC
23603a78d15Sespie 	  __mempcpy (__mempcpy (new_buffer + avail,
23703a78d15Sespie 				fp->_IO_save_end + least_mark,
23803a78d15Sespie 				-least_mark),
23903a78d15Sespie 		     fp->_IO_read_base,
24003a78d15Sespie 		     end_p - fp->_IO_read_base);
24103a78d15Sespie #else
24203a78d15Sespie 	  memcpy (new_buffer + avail,
24303a78d15Sespie 		  fp->_IO_save_end + least_mark,
24403a78d15Sespie 		  -least_mark);
24503a78d15Sespie 	  memcpy (new_buffer + avail - least_mark,
24603a78d15Sespie 		  fp->_IO_read_base,
24703a78d15Sespie 		  end_p - fp->_IO_read_base);
24803a78d15Sespie #endif
24903a78d15Sespie 	}
25003a78d15Sespie       else
25103a78d15Sespie 	memcpy (new_buffer + avail,
25203a78d15Sespie 		fp->_IO_read_base + least_mark,
25303a78d15Sespie 		needed_size);
25403a78d15Sespie       if (fp->_IO_save_base)
25503a78d15Sespie 	free (fp->_IO_save_base);
25603a78d15Sespie       fp->_IO_save_base = new_buffer;
25703a78d15Sespie       fp->_IO_save_end = new_buffer + avail + needed_size;
25803a78d15Sespie     }
25903a78d15Sespie   else
26003a78d15Sespie     {
26103a78d15Sespie       avail = current_Bsize - needed_size;
26203a78d15Sespie       if (least_mark < 0)
26303a78d15Sespie 	{
26403a78d15Sespie 	  memmove (fp->_IO_save_base + avail,
26503a78d15Sespie 		   fp->_IO_save_end + least_mark,
26603a78d15Sespie 		   -least_mark);
26703a78d15Sespie 	  memcpy (fp->_IO_save_base + avail - least_mark,
26803a78d15Sespie 		  fp->_IO_read_base,
26903a78d15Sespie 		  end_p - fp->_IO_read_base);
27003a78d15Sespie 	}
27103a78d15Sespie       else if (needed_size > 0)
27203a78d15Sespie 	memcpy (fp->_IO_save_base + avail,
27303a78d15Sespie 		fp->_IO_read_base + least_mark,
27403a78d15Sespie 		needed_size);
27503a78d15Sespie     }
27603a78d15Sespie   fp->_IO_backup_base = fp->_IO_save_base + avail;
27703a78d15Sespie   /* Adjust all the streammarkers. */
27803a78d15Sespie   delta = end_p - fp->_IO_read_base;
27903a78d15Sespie   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
28003a78d15Sespie     mark->_pos -= delta;
28103a78d15Sespie   return 0;
28203a78d15Sespie }
28303a78d15Sespie 
28403a78d15Sespie int
__underflow(fp)28503a78d15Sespie __underflow (fp)
28603a78d15Sespie      _IO_FILE *fp;
28703a78d15Sespie {
288*c2fb3212Sespie #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
28903a78d15Sespie   if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
29003a78d15Sespie     return EOF;
29103a78d15Sespie #endif
29203a78d15Sespie 
29303a78d15Sespie   if (fp->_mode == 0)
29403a78d15Sespie     _IO_fwide (fp, -1);
29503a78d15Sespie   if (_IO_in_put_mode (fp))
29603a78d15Sespie     if (_IO_switch_to_get_mode (fp) == EOF)
29703a78d15Sespie       return EOF;
29803a78d15Sespie   if (fp->_IO_read_ptr < fp->_IO_read_end)
29903a78d15Sespie     return *(unsigned char *) fp->_IO_read_ptr;
30003a78d15Sespie   if (_IO_in_backup (fp))
30103a78d15Sespie     {
30203a78d15Sespie       _IO_switch_to_main_get_area (fp);
30303a78d15Sespie       if (fp->_IO_read_ptr < fp->_IO_read_end)
30403a78d15Sespie 	return *(unsigned char *) fp->_IO_read_ptr;
30503a78d15Sespie     }
30603a78d15Sespie   if (_IO_have_markers (fp))
30703a78d15Sespie     {
30803a78d15Sespie       if (save_for_backup (fp, fp->_IO_read_end))
30903a78d15Sespie 	return EOF;
31003a78d15Sespie     }
31103a78d15Sespie   else if (_IO_have_backup (fp))
31203a78d15Sespie     _IO_free_backup_area (fp);
31303a78d15Sespie   return _IO_UNDERFLOW (fp);
31403a78d15Sespie }
31503a78d15Sespie 
31603a78d15Sespie int
__uflow(fp)31703a78d15Sespie __uflow (fp)
31803a78d15Sespie      _IO_FILE *fp;
31903a78d15Sespie {
320*c2fb3212Sespie #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
32103a78d15Sespie   if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
32203a78d15Sespie     return EOF;
32303a78d15Sespie #endif
32403a78d15Sespie 
32503a78d15Sespie   if (fp->_mode == 0)
32603a78d15Sespie     _IO_fwide (fp, -11);
32703a78d15Sespie   if (_IO_in_put_mode (fp))
32803a78d15Sespie     if (_IO_switch_to_get_mode (fp) == EOF)
32903a78d15Sespie       return EOF;
33003a78d15Sespie   if (fp->_IO_read_ptr < fp->_IO_read_end)
33103a78d15Sespie     return *(unsigned char *) fp->_IO_read_ptr++;
33203a78d15Sespie   if (_IO_in_backup (fp))
33303a78d15Sespie     {
33403a78d15Sespie       _IO_switch_to_main_get_area (fp);
33503a78d15Sespie       if (fp->_IO_read_ptr < fp->_IO_read_end)
33603a78d15Sespie 	return *(unsigned char *) fp->_IO_read_ptr++;
33703a78d15Sespie     }
33803a78d15Sespie   if (_IO_have_markers (fp))
33903a78d15Sespie     {
34003a78d15Sespie       if (save_for_backup (fp, fp->_IO_read_end))
34103a78d15Sespie 	return EOF;
34203a78d15Sespie     }
34303a78d15Sespie   else if (_IO_have_backup (fp))
34403a78d15Sespie     _IO_free_backup_area (fp);
34503a78d15Sespie   return _IO_UFLOW (fp);
34603a78d15Sespie }
34703a78d15Sespie 
34803a78d15Sespie void
_IO_setb(f,b,eb,a)34903a78d15Sespie _IO_setb (f, b, eb, a)
35003a78d15Sespie      _IO_FILE *f;
35103a78d15Sespie       char *b;
35203a78d15Sespie      char *eb;
35303a78d15Sespie      int a;
35403a78d15Sespie {
35503a78d15Sespie   if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
35603a78d15Sespie     FREE_BUF (f->_IO_buf_base, _IO_blen (f));
35703a78d15Sespie   f->_IO_buf_base = b;
35803a78d15Sespie   f->_IO_buf_end = eb;
35903a78d15Sespie   if (a)
36003a78d15Sespie     f->_flags &= ~_IO_USER_BUF;
36103a78d15Sespie   else
36203a78d15Sespie     f->_flags |= _IO_USER_BUF;
36303a78d15Sespie }
36403a78d15Sespie 
36503a78d15Sespie void
_IO_doallocbuf(fp)36603a78d15Sespie _IO_doallocbuf (fp)
36703a78d15Sespie      _IO_FILE *fp;
36803a78d15Sespie {
36903a78d15Sespie   if (fp->_IO_buf_base)
37003a78d15Sespie     return;
37103a78d15Sespie   if (!(fp->_flags & _IO_UNBUFFERED))
37203a78d15Sespie     if (_IO_DOALLOCATE (fp) != EOF)
37303a78d15Sespie       return;
37403a78d15Sespie   _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
37503a78d15Sespie }
37603a78d15Sespie 
37703a78d15Sespie int
_IO_default_underflow(fp)37803a78d15Sespie _IO_default_underflow (fp)
37903a78d15Sespie      _IO_FILE *fp;
38003a78d15Sespie {
38103a78d15Sespie   return EOF;
38203a78d15Sespie }
38303a78d15Sespie 
38403a78d15Sespie int
_IO_default_uflow(fp)38503a78d15Sespie _IO_default_uflow (fp)
38603a78d15Sespie      _IO_FILE *fp;
38703a78d15Sespie {
38803a78d15Sespie   int ch = _IO_UNDERFLOW (fp);
38903a78d15Sespie   if (ch == EOF)
39003a78d15Sespie     return EOF;
39103a78d15Sespie   return *(unsigned char *) fp->_IO_read_ptr++;
39203a78d15Sespie }
39303a78d15Sespie 
39403a78d15Sespie _IO_size_t
_IO_default_xsputn(f,data,n)39503a78d15Sespie _IO_default_xsputn (f, data, n)
39603a78d15Sespie      _IO_FILE *f;
39703a78d15Sespie      const void *data;
39803a78d15Sespie      _IO_size_t n;
39903a78d15Sespie {
40003a78d15Sespie   const char *s = (char *) data;
40103a78d15Sespie   _IO_size_t more = n;
40203a78d15Sespie   if (more <= 0)
40303a78d15Sespie     return 0;
40403a78d15Sespie   for (;;)
40503a78d15Sespie     {
40603a78d15Sespie       /* Space available. */
40703a78d15Sespie       _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
40803a78d15Sespie       if (count > 0)
40903a78d15Sespie 	{
41003a78d15Sespie 	  if ((_IO_size_t) count > more)
41103a78d15Sespie 	    count = more;
41203a78d15Sespie 	  if (count > 20)
41303a78d15Sespie 	    {
41403a78d15Sespie #ifdef _LIBC
41503a78d15Sespie 	      f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
41603a78d15Sespie #else
41703a78d15Sespie 	      memcpy (f->_IO_write_ptr, s, count);
41803a78d15Sespie 	      f->_IO_write_ptr += count;
41903a78d15Sespie #endif
42003a78d15Sespie 	      s += count;
42103a78d15Sespie             }
42203a78d15Sespie 	  else if (count <= 0)
42303a78d15Sespie 	    count = 0;
42403a78d15Sespie 	  else
42503a78d15Sespie 	    {
42603a78d15Sespie 	      char *p = f->_IO_write_ptr;
42703a78d15Sespie 	      _IO_ssize_t i;
42803a78d15Sespie 	      for (i = count; --i >= 0; )
42903a78d15Sespie 		*p++ = *s++;
43003a78d15Sespie 	      f->_IO_write_ptr = p;
43103a78d15Sespie             }
43203a78d15Sespie 	  more -= count;
43303a78d15Sespie         }
43403a78d15Sespie       if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
43503a78d15Sespie 	break;
43603a78d15Sespie       more--;
43703a78d15Sespie     }
43803a78d15Sespie   return n - more;
43903a78d15Sespie }
44003a78d15Sespie 
44103a78d15Sespie _IO_size_t
_IO_sgetn(fp,data,n)44203a78d15Sespie _IO_sgetn (fp, data, n)
44303a78d15Sespie      _IO_FILE *fp;
44403a78d15Sespie      void *data;
44503a78d15Sespie      _IO_size_t n;
44603a78d15Sespie {
44703a78d15Sespie   /* FIXME handle putback buffer here! */
44803a78d15Sespie   return _IO_XSGETN (fp, data, n);
44903a78d15Sespie }
45003a78d15Sespie 
45103a78d15Sespie _IO_size_t
_IO_default_xsgetn(fp,data,n)45203a78d15Sespie _IO_default_xsgetn (fp, data, n)
45303a78d15Sespie      _IO_FILE *fp;
45403a78d15Sespie      void *data;
45503a78d15Sespie      _IO_size_t n;
45603a78d15Sespie {
45703a78d15Sespie   _IO_size_t more = n;
45803a78d15Sespie   char *s = (char*) data;
45903a78d15Sespie   for (;;)
46003a78d15Sespie     {
46103a78d15Sespie       /* Data available. */
46203a78d15Sespie       _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
46303a78d15Sespie       if (count > 0)
46403a78d15Sespie 	{
46503a78d15Sespie 	  if ((_IO_size_t) count > more)
46603a78d15Sespie 	    count = more;
46703a78d15Sespie 	  if (count > 20)
46803a78d15Sespie 	    {
46903a78d15Sespie #ifdef _LIBC
47003a78d15Sespie 	      s = __mempcpy (s, fp->_IO_read_ptr, count);
47103a78d15Sespie #else
47203a78d15Sespie 	      memcpy (s, fp->_IO_read_ptr, count);
47303a78d15Sespie 	      s += count;
47403a78d15Sespie #endif
47503a78d15Sespie 	      fp->_IO_read_ptr += count;
47603a78d15Sespie 	    }
47703a78d15Sespie 	  else if (count <= 0)
47803a78d15Sespie 	    count = 0;
47903a78d15Sespie 	  else
48003a78d15Sespie 	    {
48103a78d15Sespie 	      char *p = fp->_IO_read_ptr;
48203a78d15Sespie 	      int i = (int) count;
48303a78d15Sespie 	      while (--i >= 0)
48403a78d15Sespie 		*s++ = *p++;
48503a78d15Sespie 	      fp->_IO_read_ptr = p;
48603a78d15Sespie             }
48703a78d15Sespie             more -= count;
48803a78d15Sespie         }
48903a78d15Sespie       if (more == 0 || __underflow (fp) == EOF)
49003a78d15Sespie 	break;
49103a78d15Sespie     }
49203a78d15Sespie   return n - more;
49303a78d15Sespie }
49403a78d15Sespie 
49503a78d15Sespie #if 0
49603a78d15Sespie /* Seems not to be needed. --drepper */
49703a78d15Sespie int
49803a78d15Sespie _IO_sync (fp)
49903a78d15Sespie      _IO_FILE *fp;
50003a78d15Sespie {
50103a78d15Sespie   return 0;
50203a78d15Sespie }
50303a78d15Sespie #endif
50403a78d15Sespie 
50503a78d15Sespie _IO_FILE *
_IO_default_setbuf(fp,p,len)50603a78d15Sespie _IO_default_setbuf (fp, p, len)
50703a78d15Sespie      _IO_FILE *fp;
50803a78d15Sespie      char *p;
50903a78d15Sespie      _IO_ssize_t len;
51003a78d15Sespie {
51103a78d15Sespie     if (_IO_SYNC (fp) == EOF)
51203a78d15Sespie 	return NULL;
51303a78d15Sespie     if (p == NULL || len == 0)
51403a78d15Sespie       {
51503a78d15Sespie 	fp->_flags |= _IO_UNBUFFERED;
51603a78d15Sespie 	_IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
51703a78d15Sespie       }
51803a78d15Sespie     else
51903a78d15Sespie       {
52003a78d15Sespie 	fp->_flags &= ~_IO_UNBUFFERED;
52103a78d15Sespie 	_IO_setb (fp, p, p+len, 0);
52203a78d15Sespie       }
52303a78d15Sespie     fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
52403a78d15Sespie     fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
52503a78d15Sespie     return fp;
52603a78d15Sespie }
52703a78d15Sespie 
52803a78d15Sespie _IO_off64_t
_IO_default_seekpos(fp,pos,mode)52903a78d15Sespie _IO_default_seekpos (fp, pos, mode)
53003a78d15Sespie      _IO_FILE *fp;
53103a78d15Sespie      _IO_off64_t pos;
53203a78d15Sespie      int mode;
53303a78d15Sespie {
53403a78d15Sespie   return _IO_SEEKOFF (fp, pos, 0, mode);
53503a78d15Sespie }
53603a78d15Sespie 
53703a78d15Sespie int
_IO_default_doallocate(fp)53803a78d15Sespie _IO_default_doallocate (fp)
53903a78d15Sespie      _IO_FILE *fp;
54003a78d15Sespie {
54103a78d15Sespie   char *buf;
54203a78d15Sespie 
54303a78d15Sespie   ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
54403a78d15Sespie   _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
54503a78d15Sespie   return 1;
54603a78d15Sespie }
54703a78d15Sespie 
54803a78d15Sespie void
_IO_init(fp,flags)54903a78d15Sespie _IO_init (fp, flags)
55003a78d15Sespie      _IO_FILE *fp;
55103a78d15Sespie      int flags;
55203a78d15Sespie {
55303a78d15Sespie   _IO_no_init (fp, flags, -1, NULL, NULL);
55403a78d15Sespie }
55503a78d15Sespie 
55603a78d15Sespie void
_IO_no_init(fp,flags,orientation,wd,jmp)55703a78d15Sespie _IO_no_init (fp, flags, orientation, wd, jmp)
55803a78d15Sespie      _IO_FILE *fp;
55903a78d15Sespie      int flags;
56003a78d15Sespie      int orientation;
56103a78d15Sespie      struct _IO_wide_data *wd;
56203a78d15Sespie      struct _IO_jump_t *jmp;
56303a78d15Sespie {
56403a78d15Sespie   fp->_flags = _IO_MAGIC|flags;
56503a78d15Sespie   fp->_IO_buf_base = NULL;
56603a78d15Sespie   fp->_IO_buf_end = NULL;
56703a78d15Sespie   fp->_IO_read_base = NULL;
56803a78d15Sespie   fp->_IO_read_ptr = NULL;
56903a78d15Sespie   fp->_IO_read_end = NULL;
57003a78d15Sespie   fp->_IO_write_base = NULL;
57103a78d15Sespie   fp->_IO_write_ptr = NULL;
57203a78d15Sespie   fp->_IO_write_end = NULL;
57303a78d15Sespie   fp->_chain = NULL; /* Not necessary. */
57403a78d15Sespie 
57503a78d15Sespie   fp->_IO_save_base = NULL;
57603a78d15Sespie   fp->_IO_backup_base = NULL;
57703a78d15Sespie   fp->_IO_save_end = NULL;
57803a78d15Sespie   fp->_markers = NULL;
57903a78d15Sespie   fp->_cur_column = 0;
58003a78d15Sespie #if _IO_JUMPS_OFFSET
58103a78d15Sespie   fp->_vtable_offset = 0;
58203a78d15Sespie #endif
58303a78d15Sespie #ifdef _IO_MTSAFE_IO
58403a78d15Sespie   _IO_lock_init (*fp->_lock);
58503a78d15Sespie #endif
58603a78d15Sespie   fp->_mode = orientation;
587*c2fb3212Sespie #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
58803a78d15Sespie   if (orientation >= 0)
58903a78d15Sespie     {
59003a78d15Sespie       fp->_wide_data = wd;
59103a78d15Sespie       fp->_wide_data->_IO_buf_base = NULL;
59203a78d15Sespie       fp->_wide_data->_IO_buf_end = NULL;
59303a78d15Sespie       fp->_wide_data->_IO_read_base = NULL;
59403a78d15Sespie       fp->_wide_data->_IO_read_ptr = NULL;
59503a78d15Sespie       fp->_wide_data->_IO_read_end = NULL;
59603a78d15Sespie       fp->_wide_data->_IO_write_base = NULL;
59703a78d15Sespie       fp->_wide_data->_IO_write_ptr = NULL;
59803a78d15Sespie       fp->_wide_data->_IO_write_end = NULL;
59903a78d15Sespie       fp->_wide_data->_IO_save_base = NULL;
60003a78d15Sespie       fp->_wide_data->_IO_backup_base = NULL;
60103a78d15Sespie       fp->_wide_data->_IO_save_end = NULL;
60203a78d15Sespie 
60303a78d15Sespie       fp->_wide_data->_wide_vtable = jmp;
60403a78d15Sespie     }
60503a78d15Sespie #endif
60603a78d15Sespie }
60703a78d15Sespie 
60803a78d15Sespie int
_IO_default_sync(fp)60903a78d15Sespie _IO_default_sync (fp)
61003a78d15Sespie      _IO_FILE *fp;
61103a78d15Sespie {
61203a78d15Sespie   return 0;
61303a78d15Sespie }
61403a78d15Sespie 
61503a78d15Sespie /* The way the C++ classes are mapped into the C functions in the
61603a78d15Sespie    current implementation, this function can get called twice! */
61703a78d15Sespie 
61803a78d15Sespie void
_IO_default_finish(fp,dummy)61903a78d15Sespie _IO_default_finish (fp, dummy)
62003a78d15Sespie      _IO_FILE *fp;
62103a78d15Sespie      int dummy;
62203a78d15Sespie {
62303a78d15Sespie   struct _IO_marker *mark;
62403a78d15Sespie   if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
62503a78d15Sespie     {
62603a78d15Sespie       FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
62703a78d15Sespie       fp->_IO_buf_base = fp->_IO_buf_end = NULL;
62803a78d15Sespie     }
62903a78d15Sespie 
63003a78d15Sespie   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
63103a78d15Sespie     mark->_sbuf = NULL;
63203a78d15Sespie 
63303a78d15Sespie   if (fp->_IO_save_base)
63403a78d15Sespie     {
63503a78d15Sespie       free (fp->_IO_save_base);
63603a78d15Sespie       fp->_IO_save_base = NULL;
63703a78d15Sespie     }
63803a78d15Sespie 
63903a78d15Sespie #ifdef _IO_MTSAFE_IO
64003a78d15Sespie   _IO_lock_fini (*fp->_lock);
64103a78d15Sespie #endif
64203a78d15Sespie 
64303a78d15Sespie   _IO_un_link ((struct _IO_FILE_plus *) fp);
64403a78d15Sespie }
64503a78d15Sespie 
64603a78d15Sespie _IO_off64_t
_IO_default_seekoff(fp,offset,dir,mode)64703a78d15Sespie _IO_default_seekoff (fp, offset, dir, mode)
64803a78d15Sespie      _IO_FILE *fp;
64903a78d15Sespie      _IO_off64_t offset;
65003a78d15Sespie      int dir;
65103a78d15Sespie      int mode;
65203a78d15Sespie {
65303a78d15Sespie     return _IO_pos_BAD;
65403a78d15Sespie }
65503a78d15Sespie 
65603a78d15Sespie int
_IO_sputbackc(fp,c)65703a78d15Sespie _IO_sputbackc (fp, c)
65803a78d15Sespie      _IO_FILE *fp;
65903a78d15Sespie      int c;
66003a78d15Sespie {
66103a78d15Sespie   int result;
66203a78d15Sespie 
66303a78d15Sespie   if (fp->_IO_read_ptr > fp->_IO_read_base
66403a78d15Sespie       && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
66503a78d15Sespie     {
66603a78d15Sespie       fp->_IO_read_ptr--;
66703a78d15Sespie       result = (unsigned char) c;
66803a78d15Sespie     }
66903a78d15Sespie   else
67003a78d15Sespie     result = _IO_PBACKFAIL (fp, c);
67103a78d15Sespie 
67203a78d15Sespie   if (result != EOF)
67303a78d15Sespie     fp->_flags &= ~_IO_EOF_SEEN;
67403a78d15Sespie 
67503a78d15Sespie   return result;
67603a78d15Sespie }
67703a78d15Sespie 
67803a78d15Sespie int
_IO_sungetc(fp)67903a78d15Sespie _IO_sungetc (fp)
68003a78d15Sespie      _IO_FILE *fp;
68103a78d15Sespie {
68203a78d15Sespie   int result;
68303a78d15Sespie 
68403a78d15Sespie   if (fp->_IO_read_ptr > fp->_IO_read_base)
68503a78d15Sespie     {
68603a78d15Sespie       fp->_IO_read_ptr--;
68703a78d15Sespie       result = (unsigned char) *fp->_IO_read_ptr;
68803a78d15Sespie     }
68903a78d15Sespie   else
69003a78d15Sespie     result = _IO_PBACKFAIL (fp, EOF);
69103a78d15Sespie 
69203a78d15Sespie   if (result != EOF)
69303a78d15Sespie     fp->_flags &= ~_IO_EOF_SEEN;
69403a78d15Sespie 
69503a78d15Sespie   return result;
69603a78d15Sespie }
69703a78d15Sespie 
69803a78d15Sespie #if 0 /* Work in progress */
69903a78d15Sespie /* Seems not to be needed.  */
70003a78d15Sespie #if 0
70103a78d15Sespie void
70203a78d15Sespie _IO_set_column (fp, c)
70303a78d15Sespie      _IO_FILE *fp;
70403a78d15Sespie      int c;
70503a78d15Sespie {
70603a78d15Sespie   if (c == -1)
70703a78d15Sespie     fp->_column = -1;
70803a78d15Sespie   else
70903a78d15Sespie     fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
71003a78d15Sespie }
71103a78d15Sespie #else
71203a78d15Sespie int
71303a78d15Sespie _IO_set_column (fp, i)
71403a78d15Sespie      _IO_FILE *fp;
71503a78d15Sespie      int i;
71603a78d15Sespie {
71703a78d15Sespie   fp->_cur_column = i + 1;
71803a78d15Sespie   return 0;
71903a78d15Sespie }
72003a78d15Sespie #endif
72103a78d15Sespie #endif
72203a78d15Sespie 
72303a78d15Sespie 
72403a78d15Sespie unsigned
_IO_adjust_column(start,line,count)72503a78d15Sespie _IO_adjust_column (start, line, count)
72603a78d15Sespie      unsigned start;
72703a78d15Sespie      const char *line;
72803a78d15Sespie      int count;
72903a78d15Sespie {
73003a78d15Sespie   const char *ptr = line + count;
73103a78d15Sespie   while (ptr > line)
73203a78d15Sespie     if (*--ptr == '\n')
73303a78d15Sespie       return line + count - ptr - 1;
73403a78d15Sespie   return start + count;
73503a78d15Sespie }
73603a78d15Sespie 
73703a78d15Sespie #if 0
73803a78d15Sespie /* Seems not to be needed. --drepper */
73903a78d15Sespie int
74003a78d15Sespie _IO_get_column (fp)
74103a78d15Sespie      _IO_FILE *fp;
74203a78d15Sespie {
74303a78d15Sespie   if (fp->_cur_column)
74403a78d15Sespie     return _IO_adjust_column (fp->_cur_column - 1,
74503a78d15Sespie 			      fp->_IO_write_base,
74603a78d15Sespie 			      fp->_IO_write_ptr - fp->_IO_write_base);
74703a78d15Sespie   return -1;
74803a78d15Sespie }
74903a78d15Sespie #endif
75003a78d15Sespie 
75103a78d15Sespie int
_IO_flush_all()75203a78d15Sespie _IO_flush_all ()
75303a78d15Sespie {
75403a78d15Sespie   int result = 0;
75503a78d15Sespie   struct _IO_FILE *fp;
75603a78d15Sespie   for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
75703a78d15Sespie     if (((fp->_mode < 0 && fp->_IO_write_ptr > fp->_IO_write_base)
758*c2fb3212Sespie #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
75903a78d15Sespie 	 || (fp->_vtable_offset == 0
76003a78d15Sespie 	     && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
76103a78d15Sespie 				  > fp->_wide_data->_IO_write_base))
76203a78d15Sespie #endif
76303a78d15Sespie 	 )
76403a78d15Sespie 	&& _IO_OVERFLOW (fp, EOF) == EOF)
76503a78d15Sespie       result = EOF;
76603a78d15Sespie   return result;
76703a78d15Sespie }
76803a78d15Sespie 
76903a78d15Sespie void
_IO_flush_all_linebuffered()77003a78d15Sespie _IO_flush_all_linebuffered ()
77103a78d15Sespie {
77203a78d15Sespie   struct _IO_FILE *fp;
77303a78d15Sespie   for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
77403a78d15Sespie     if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
77503a78d15Sespie       _IO_OVERFLOW (fp, EOF);
77603a78d15Sespie }
77703a78d15Sespie 
77803a78d15Sespie static void _IO_unbuffer_write __P ((void));
77903a78d15Sespie 
78003a78d15Sespie static void
_IO_unbuffer_write()78103a78d15Sespie _IO_unbuffer_write ()
78203a78d15Sespie {
78303a78d15Sespie   struct _IO_FILE *fp;
78403a78d15Sespie   for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
78503a78d15Sespie     if (! (fp->_flags & _IO_UNBUFFERED)
78603a78d15Sespie 	&& (! (fp->_flags & _IO_NO_WRITES)
78703a78d15Sespie 	    || (fp->_flags & _IO_IS_APPENDING))
78803a78d15Sespie 	/* Iff stream is un-orientated, it wasn't used. */
78903a78d15Sespie 	&& fp->_mode != 0)
79003a78d15Sespie       _IO_SETBUF (fp, NULL, 0);
79103a78d15Sespie }
79203a78d15Sespie 
79303a78d15Sespie int
_IO_cleanup()79403a78d15Sespie _IO_cleanup ()
79503a78d15Sespie {
79603a78d15Sespie   int result = _IO_flush_all ();
79703a78d15Sespie 
79803a78d15Sespie   /* We currently don't have a reliable mechanism for making sure that
79903a78d15Sespie      C++ static destructors are executed in the correct order.
80003a78d15Sespie      So it is possible that other static destructors might want to
80103a78d15Sespie      write to cout - and they're supposed to be able to do so.
80203a78d15Sespie 
80303a78d15Sespie      The following will make the standard streambufs be unbuffered,
80403a78d15Sespie      which forces any output from late destructors to be written out. */
80503a78d15Sespie   _IO_unbuffer_write ();
80603a78d15Sespie 
80703a78d15Sespie   return result;
80803a78d15Sespie }
80903a78d15Sespie 
81003a78d15Sespie 
81103a78d15Sespie void
_IO_init_marker(marker,fp)81203a78d15Sespie _IO_init_marker (marker, fp)
81303a78d15Sespie      struct _IO_marker *marker;
81403a78d15Sespie      _IO_FILE *fp;
81503a78d15Sespie {
81603a78d15Sespie   marker->_sbuf = fp;
81703a78d15Sespie   if (_IO_in_put_mode (fp))
81803a78d15Sespie     _IO_switch_to_get_mode (fp);
81903a78d15Sespie   if (_IO_in_backup (fp))
82003a78d15Sespie     marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
82103a78d15Sespie   else
82203a78d15Sespie     marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
82303a78d15Sespie 
82403a78d15Sespie   /* Should perhaps sort the chain? */
82503a78d15Sespie   marker->_next = fp->_markers;
82603a78d15Sespie   fp->_markers = marker;
82703a78d15Sespie }
82803a78d15Sespie 
82903a78d15Sespie void
_IO_remove_marker(marker)83003a78d15Sespie _IO_remove_marker (marker)
83103a78d15Sespie      struct _IO_marker *marker;
83203a78d15Sespie {
83303a78d15Sespie   /* Unlink from sb's chain. */
83403a78d15Sespie   struct _IO_marker **ptr = &marker->_sbuf->_markers;
83503a78d15Sespie   for (; ; ptr = &(*ptr)->_next)
83603a78d15Sespie     {
83703a78d15Sespie       if (*ptr == NULL)
83803a78d15Sespie 	break;
83903a78d15Sespie       else if (*ptr == marker)
84003a78d15Sespie 	{
84103a78d15Sespie 	  *ptr = marker->_next;
84203a78d15Sespie 	  return;
84303a78d15Sespie 	}
84403a78d15Sespie     }
84503a78d15Sespie #if 0
84603a78d15Sespie     if _sbuf has a backup area that is no longer needed, should we delete
84703a78d15Sespie     it now, or wait until the next underflow?
84803a78d15Sespie #endif
84903a78d15Sespie }
85003a78d15Sespie 
85103a78d15Sespie #define BAD_DELTA EOF
85203a78d15Sespie 
85303a78d15Sespie int
_IO_marker_difference(mark1,mark2)85403a78d15Sespie _IO_marker_difference (mark1, mark2)
85503a78d15Sespie      struct _IO_marker *mark1;
85603a78d15Sespie      struct _IO_marker *mark2;
85703a78d15Sespie {
85803a78d15Sespie   return mark1->_pos - mark2->_pos;
85903a78d15Sespie }
86003a78d15Sespie 
86103a78d15Sespie /* Return difference between MARK and current position of MARK's stream. */
86203a78d15Sespie int
_IO_marker_delta(mark)86303a78d15Sespie _IO_marker_delta (mark)
86403a78d15Sespie      struct _IO_marker *mark;
86503a78d15Sespie {
86603a78d15Sespie   int cur_pos;
86703a78d15Sespie   if (mark->_sbuf == NULL)
86803a78d15Sespie     return BAD_DELTA;
86903a78d15Sespie   if (_IO_in_backup (mark->_sbuf))
87003a78d15Sespie     cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
87103a78d15Sespie   else
87203a78d15Sespie     cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
87303a78d15Sespie   return mark->_pos - cur_pos;
87403a78d15Sespie }
87503a78d15Sespie 
87603a78d15Sespie int
_IO_seekmark(fp,mark,delta)87703a78d15Sespie _IO_seekmark (fp, mark, delta)
87803a78d15Sespie      _IO_FILE *fp;
87903a78d15Sespie      struct _IO_marker *mark;
88003a78d15Sespie      int delta;
88103a78d15Sespie {
88203a78d15Sespie   if (mark->_sbuf != fp)
88303a78d15Sespie     return EOF;
88403a78d15Sespie  if (mark->_pos >= 0)
88503a78d15Sespie     {
88603a78d15Sespie       if (_IO_in_backup (fp))
88703a78d15Sespie 	_IO_switch_to_main_get_area (fp);
88803a78d15Sespie       fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
88903a78d15Sespie     }
89003a78d15Sespie   else
89103a78d15Sespie     {
89203a78d15Sespie       if (!_IO_in_backup (fp))
89303a78d15Sespie 	_IO_switch_to_backup_area (fp);
89403a78d15Sespie       fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
89503a78d15Sespie     }
89603a78d15Sespie   return 0;
89703a78d15Sespie }
89803a78d15Sespie 
89903a78d15Sespie void
_IO_unsave_markers(fp)90003a78d15Sespie _IO_unsave_markers (fp)
90103a78d15Sespie      _IO_FILE *fp;
90203a78d15Sespie {
90303a78d15Sespie   struct _IO_marker *mark = fp->_markers;
90403a78d15Sespie   if (mark)
90503a78d15Sespie     {
90603a78d15Sespie #ifdef TODO
90703a78d15Sespie       streampos offset = seekoff (0, ios::cur, ios::in);
90803a78d15Sespie       if (offset != EOF)
90903a78d15Sespie 	{
91003a78d15Sespie 	  offset += eGptr () - Gbase ();
91103a78d15Sespie 	  for ( ; mark != NULL; mark = mark->_next)
91203a78d15Sespie 	    mark->set_streampos (mark->_pos + offset);
91303a78d15Sespie 	}
91403a78d15Sespie     else
91503a78d15Sespie       {
91603a78d15Sespie 	for ( ; mark != NULL; mark = mark->_next)
91703a78d15Sespie 	  mark->set_streampos (EOF);
91803a78d15Sespie       }
91903a78d15Sespie #endif
92003a78d15Sespie       fp->_markers = 0;
92103a78d15Sespie     }
92203a78d15Sespie 
92303a78d15Sespie   if (_IO_have_backup (fp))
92403a78d15Sespie     _IO_free_backup_area (fp);
92503a78d15Sespie }
92603a78d15Sespie 
92703a78d15Sespie #if 0
92803a78d15Sespie /* Seems not to be needed. --drepper */
92903a78d15Sespie int
93003a78d15Sespie _IO_nobackup_pbackfail (fp, c)
93103a78d15Sespie      _IO_FILE *fp;
93203a78d15Sespie      int c;
93303a78d15Sespie {
93403a78d15Sespie   if (fp->_IO_read_ptr > fp->_IO_read_base)
93503a78d15Sespie 	fp->_IO_read_ptr--;
93603a78d15Sespie   if (c != EOF && *fp->_IO_read_ptr != c)
93703a78d15Sespie       *fp->_IO_read_ptr = c;
93803a78d15Sespie   return (unsigned char) c;
93903a78d15Sespie }
94003a78d15Sespie #endif
94103a78d15Sespie 
94203a78d15Sespie int
_IO_default_pbackfail(fp,c)94303a78d15Sespie _IO_default_pbackfail (fp, c)
94403a78d15Sespie      _IO_FILE *fp;
94503a78d15Sespie      int c;
94603a78d15Sespie {
94703a78d15Sespie   if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
94803a78d15Sespie       && (unsigned char) fp->_IO_read_ptr[-1] == c)
94903a78d15Sespie     --fp->_IO_read_ptr;
95003a78d15Sespie   else
95103a78d15Sespie     {
95203a78d15Sespie       /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
95303a78d15Sespie       if (!_IO_in_backup (fp))
95403a78d15Sespie 	{
95503a78d15Sespie 	  /* We need to keep the invariant that the main get area
95603a78d15Sespie 	     logically follows the backup area.  */
95703a78d15Sespie 	  if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
95803a78d15Sespie 	    {
95903a78d15Sespie 	      if (save_for_backup (fp, fp->_IO_read_ptr))
96003a78d15Sespie 		return EOF;
96103a78d15Sespie 	    }
96203a78d15Sespie 	  else if (!_IO_have_backup (fp))
96303a78d15Sespie 	    {
96403a78d15Sespie 	      /* No backup buffer: allocate one. */
96503a78d15Sespie 	      /* Use nshort buffer, if unused? (probably not)  FIXME */
96603a78d15Sespie 	      int backup_size = 128;
96703a78d15Sespie 	      char *bbuf = (char *) malloc (backup_size);
96803a78d15Sespie 	      if (bbuf == NULL)
96903a78d15Sespie 		return EOF;
97003a78d15Sespie 	      fp->_IO_save_base = bbuf;
97103a78d15Sespie 	      fp->_IO_save_end = fp->_IO_save_base + backup_size;
97203a78d15Sespie 	      fp->_IO_backup_base = fp->_IO_save_end;
97303a78d15Sespie 	    }
97403a78d15Sespie 	  fp->_IO_read_base = fp->_IO_read_ptr;
97503a78d15Sespie 	  _IO_switch_to_backup_area (fp);
97603a78d15Sespie 	}
97703a78d15Sespie       else if (fp->_IO_read_ptr <= fp->_IO_read_base)
97803a78d15Sespie 	{
97903a78d15Sespie 	  /* Increase size of existing backup buffer. */
98003a78d15Sespie 	  _IO_size_t new_size;
98103a78d15Sespie 	  _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
98203a78d15Sespie 	  char *new_buf;
98303a78d15Sespie 	  new_size = 2 * old_size;
98403a78d15Sespie 	  new_buf = (char *) malloc (new_size);
98503a78d15Sespie 	  if (new_buf == NULL)
98603a78d15Sespie 	    return EOF;
98703a78d15Sespie 	  memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
98803a78d15Sespie 		  old_size);
98903a78d15Sespie 	  free (fp->_IO_read_base);
99003a78d15Sespie 	  _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
99103a78d15Sespie 		    new_buf + new_size);
99203a78d15Sespie 	  fp->_IO_backup_base = fp->_IO_read_ptr;
99303a78d15Sespie 	}
99403a78d15Sespie 
99503a78d15Sespie       *--fp->_IO_read_ptr = c;
99603a78d15Sespie     }
99703a78d15Sespie   return (unsigned char) c;
99803a78d15Sespie }
99903a78d15Sespie 
100003a78d15Sespie _IO_off64_t
_IO_default_seek(fp,offset,dir)100103a78d15Sespie _IO_default_seek (fp, offset, dir)
100203a78d15Sespie      _IO_FILE *fp;
100303a78d15Sespie      _IO_off64_t offset;
100403a78d15Sespie      int dir;
100503a78d15Sespie {
100603a78d15Sespie   return _IO_pos_BAD;
100703a78d15Sespie }
100803a78d15Sespie 
100903a78d15Sespie int
_IO_default_stat(fp,st)101003a78d15Sespie _IO_default_stat (fp, st)
101103a78d15Sespie      _IO_FILE *fp;
101203a78d15Sespie      void* st;
101303a78d15Sespie {
101403a78d15Sespie   return EOF;
101503a78d15Sespie }
101603a78d15Sespie 
101703a78d15Sespie _IO_ssize_t
_IO_default_read(fp,data,n)101803a78d15Sespie _IO_default_read (fp, data, n)
101903a78d15Sespie      _IO_FILE* fp;
102003a78d15Sespie      void *data;
102103a78d15Sespie      _IO_ssize_t n;
102203a78d15Sespie {
102303a78d15Sespie   return -1;
102403a78d15Sespie }
102503a78d15Sespie 
102603a78d15Sespie _IO_ssize_t
_IO_default_write(fp,data,n)102703a78d15Sespie _IO_default_write (fp, data, n)
102803a78d15Sespie      _IO_FILE *fp;
102903a78d15Sespie      const void *data;
103003a78d15Sespie      _IO_ssize_t n;
103103a78d15Sespie {
103203a78d15Sespie   return 0;
103303a78d15Sespie }
103403a78d15Sespie 
103503a78d15Sespie int
_IO_default_showmanyc(fp)103603a78d15Sespie _IO_default_showmanyc (fp)
103703a78d15Sespie      _IO_FILE *fp;
103803a78d15Sespie {
103903a78d15Sespie   return -1;
104003a78d15Sespie }
104103a78d15Sespie 
104203a78d15Sespie void
_IO_default_imbue(fp,locale)104303a78d15Sespie _IO_default_imbue (fp, locale)
104403a78d15Sespie      _IO_FILE *fp;
104503a78d15Sespie      void *locale;
104603a78d15Sespie {
104703a78d15Sespie }
104803a78d15Sespie 
104903a78d15Sespie _IO_ITER
_IO_iter_begin()105003a78d15Sespie _IO_iter_begin()
105103a78d15Sespie {
105203a78d15Sespie   return (_IO_ITER) _IO_list_all;
105303a78d15Sespie }
105403a78d15Sespie 
105503a78d15Sespie _IO_ITER
_IO_iter_end()105603a78d15Sespie _IO_iter_end()
105703a78d15Sespie {
105803a78d15Sespie   return NULL;
105903a78d15Sespie }
106003a78d15Sespie 
106103a78d15Sespie _IO_ITER
_IO_iter_next(iter)106203a78d15Sespie _IO_iter_next(iter)
106303a78d15Sespie     _IO_ITER iter;
106403a78d15Sespie {
106503a78d15Sespie   return iter->_chain;
106603a78d15Sespie }
106703a78d15Sespie 
106803a78d15Sespie _IO_FILE *
_IO_iter_file(iter)106903a78d15Sespie _IO_iter_file(iter)
107003a78d15Sespie     _IO_ITER iter;
107103a78d15Sespie {
107203a78d15Sespie   return iter;
107303a78d15Sespie }
107403a78d15Sespie 
107503a78d15Sespie void
_IO_list_lock()107603a78d15Sespie _IO_list_lock()
107703a78d15Sespie {
107803a78d15Sespie #ifdef _IO_MTSAFE_IO
107903a78d15Sespie   _IO_lock_lock (list_all_lock);
108003a78d15Sespie #endif
108103a78d15Sespie }
108203a78d15Sespie 
108303a78d15Sespie void
_IO_list_unlock()108403a78d15Sespie _IO_list_unlock()
108503a78d15Sespie {
108603a78d15Sespie #ifdef _IO_MTSAFE_IO
108703a78d15Sespie   _IO_lock_unlock (list_all_lock);
108803a78d15Sespie #endif
108903a78d15Sespie }
109003a78d15Sespie 
109103a78d15Sespie void
_IO_list_resetlock()109203a78d15Sespie _IO_list_resetlock()
109303a78d15Sespie {
109403a78d15Sespie #ifdef _IO_MTSAFE_IO
109503a78d15Sespie   _IO_lock_init (list_all_lock);
109603a78d15Sespie #endif
109703a78d15Sespie }
109803a78d15Sespie 
109903a78d15Sespie 
110003a78d15Sespie #ifdef TODO
110103a78d15Sespie #if defined(linux)
110203a78d15Sespie #define IO_CLEANUP ;
110303a78d15Sespie #endif
110403a78d15Sespie 
110503a78d15Sespie #ifdef IO_CLEANUP
110603a78d15Sespie   IO_CLEANUP
110703a78d15Sespie #else
110803a78d15Sespie struct __io_defs {
110903a78d15Sespie     __io_defs() { }
111003a78d15Sespie     ~__io_defs() { _IO_cleanup (); }
111103a78d15Sespie };
111203a78d15Sespie __io_defs io_defs__;
111303a78d15Sespie #endif
111403a78d15Sespie 
111503a78d15Sespie #endif /* TODO */
111603a78d15Sespie 
111703a78d15Sespie #ifdef weak_alias
111803a78d15Sespie weak_alias (_IO_cleanup, _cleanup)
111903a78d15Sespie #endif
112003a78d15Sespie 
112103a78d15Sespie #ifdef text_set_element
112203a78d15Sespie text_set_element(__libc_atexit, _cleanup);
112303a78d15Sespie #endif
1124