Blame libio/genops.c

Packit 6c4009
/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.
Packit 6c4009
Packit 6c4009
   As a special exception, if you link the code in this file with
Packit 6c4009
   files compiled with a GNU compiler to produce an executable,
Packit 6c4009
   that does not cause the resulting executable to be covered by
Packit 6c4009
   the GNU Lesser General Public License.  This exception does not
Packit 6c4009
   however invalidate any other reasons why the executable file
Packit 6c4009
   might be covered by the GNU Lesser General Public License.
Packit 6c4009
   This exception applies to code released by its copyright holders
Packit 6c4009
   in files containing the exception.  */
Packit 6c4009
Packit 6c4009
/* Generic or default I/O operations. */
Packit 6c4009
Packit 6c4009
#include "libioP.h"
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <stdbool.h>
Packit 6c4009
#include <sched.h>
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
static _IO_lock_t list_all_lock = _IO_lock_initializer;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
static FILE *run_fp;
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
static void
Packit 6c4009
flush_cleanup (void *not_used)
Packit 6c4009
{
Packit 6c4009
  if (run_fp != NULL)
Packit 6c4009
    _IO_funlockfile (run_fp);
Packit 6c4009
  _IO_lock_unlock (list_all_lock);
Packit 6c4009
}
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_un_link (struct _IO_FILE_plus *fp)
Packit 6c4009
{
Packit 6c4009
  if (fp->file._flags & _IO_LINKED)
Packit 6c4009
    {
Packit 6c4009
      FILE **f;
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
      _IO_cleanup_region_start_noarg (flush_cleanup);
Packit 6c4009
      _IO_lock_lock (list_all_lock);
Packit 6c4009
      run_fp = (FILE *) fp;
Packit 6c4009
      _IO_flockfile ((FILE *) fp);
Packit 6c4009
#endif
Packit 6c4009
      if (_IO_list_all == NULL)
Packit 6c4009
	;
Packit 6c4009
      else if (fp == _IO_list_all)
Packit 6c4009
	_IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
Packit 6c4009
      else
Packit 6c4009
	for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
Packit 6c4009
	  if (*f == (FILE *) fp)
Packit 6c4009
	    {
Packit 6c4009
	      *f = fp->file._chain;
Packit 6c4009
	      break;
Packit 6c4009
	    }
Packit 6c4009
      fp->file._flags &= ~_IO_LINKED;
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
      _IO_funlockfile ((FILE *) fp);
Packit 6c4009
      run_fp = NULL;
Packit 6c4009
      _IO_lock_unlock (list_all_lock);
Packit 6c4009
      _IO_cleanup_region_end (0);
Packit 6c4009
#endif
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_un_link)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_link_in (struct _IO_FILE_plus *fp)
Packit 6c4009
{
Packit 6c4009
  if ((fp->file._flags & _IO_LINKED) == 0)
Packit 6c4009
    {
Packit 6c4009
      fp->file._flags |= _IO_LINKED;
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
      _IO_cleanup_region_start_noarg (flush_cleanup);
Packit 6c4009
      _IO_lock_lock (list_all_lock);
Packit 6c4009
      run_fp = (FILE *) fp;
Packit 6c4009
      _IO_flockfile ((FILE *) fp);
Packit 6c4009
#endif
Packit 6c4009
      fp->file._chain = (FILE *) _IO_list_all;
Packit 6c4009
      _IO_list_all = fp;
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
      _IO_funlockfile ((FILE *) fp);
Packit 6c4009
      run_fp = NULL;
Packit 6c4009
      _IO_lock_unlock (list_all_lock);
Packit 6c4009
      _IO_cleanup_region_end (0);
Packit 6c4009
#endif
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_link_in)
Packit 6c4009
Packit 6c4009
/* Return minimum _pos markers
Packit 6c4009
   Assumes the current get area is the main get area. */
Packit 6c4009
ssize_t _IO_least_marker (FILE *fp, char *end_p);
Packit 6c4009
Packit 6c4009
ssize_t
Packit 6c4009
_IO_least_marker (FILE *fp, char *end_p)
Packit 6c4009
{
Packit 6c4009
  ssize_t least_so_far = end_p - fp->_IO_read_base;
Packit 6c4009
  struct _IO_marker *mark;
Packit 6c4009
  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
Packit 6c4009
    if (mark->_pos < least_so_far)
Packit 6c4009
      least_so_far = mark->_pos;
Packit 6c4009
  return least_so_far;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Switch current get area from backup buffer to (start of) main get area. */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_switch_to_main_get_area (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  char *tmp;
Packit 6c4009
  fp->_flags &= ~_IO_IN_BACKUP;
Packit 6c4009
  /* Swap _IO_read_end and _IO_save_end. */
Packit 6c4009
  tmp = fp->_IO_read_end;
Packit 6c4009
  fp->_IO_read_end = fp->_IO_save_end;
Packit 6c4009
  fp->_IO_save_end= tmp;
Packit 6c4009
  /* Swap _IO_read_base and _IO_save_base. */
Packit 6c4009
  tmp = fp->_IO_read_base;
Packit 6c4009
  fp->_IO_read_base = fp->_IO_save_base;
Packit 6c4009
  fp->_IO_save_base = tmp;
Packit 6c4009
  /* Set _IO_read_ptr. */
Packit 6c4009
  fp->_IO_read_ptr = fp->_IO_read_base;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Switch current get area from main get area to (end of) backup area. */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_switch_to_backup_area (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  char *tmp;
Packit 6c4009
  fp->_flags |= _IO_IN_BACKUP;
Packit 6c4009
  /* Swap _IO_read_end and _IO_save_end. */
Packit 6c4009
  tmp = fp->_IO_read_end;
Packit 6c4009
  fp->_IO_read_end = fp->_IO_save_end;
Packit 6c4009
  fp->_IO_save_end = tmp;
Packit 6c4009
  /* Swap _IO_read_base and _IO_save_base. */
Packit 6c4009
  tmp = fp->_IO_read_base;
Packit 6c4009
  fp->_IO_read_base = fp->_IO_save_base;
Packit 6c4009
  fp->_IO_save_base = tmp;
Packit 6c4009
  /* Set _IO_read_ptr.  */
Packit 6c4009
  fp->_IO_read_ptr = fp->_IO_read_end;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_switch_to_get_mode (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  if (fp->_IO_write_ptr > fp->_IO_write_base)
Packit 6c4009
    if (_IO_OVERFLOW (fp, EOF) == EOF)
Packit 6c4009
      return EOF;
Packit 6c4009
  if (_IO_in_backup (fp))
Packit 6c4009
    fp->_IO_read_base = fp->_IO_backup_base;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      fp->_IO_read_base = fp->_IO_buf_base;
Packit 6c4009
      if (fp->_IO_write_ptr > fp->_IO_read_end)
Packit 6c4009
	fp->_IO_read_end = fp->_IO_write_ptr;
Packit 6c4009
    }
Packit 6c4009
  fp->_IO_read_ptr = fp->_IO_write_ptr;
Packit 6c4009
Packit 6c4009
  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
Packit 6c4009
Packit 6c4009
  fp->_flags &= ~_IO_CURRENTLY_PUTTING;
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_switch_to_get_mode)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_free_backup_area (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  if (_IO_in_backup (fp))
Packit 6c4009
    _IO_switch_to_main_get_area (fp);  /* Just in case. */
Packit 6c4009
  free (fp->_IO_save_base);
Packit 6c4009
  fp->_IO_save_base = NULL;
Packit 6c4009
  fp->_IO_save_end = NULL;
Packit 6c4009
  fp->_IO_backup_base = NULL;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_free_backup_area)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
__overflow (FILE *f, int ch)
Packit 6c4009
{
Packit 6c4009
  /* This is a single-byte stream.  */
Packit 6c4009
  if (f->_mode == 0)
Packit 6c4009
    _IO_fwide (f, -1);
Packit 6c4009
  return _IO_OVERFLOW (f, ch);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (__overflow)
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
save_for_backup (FILE *fp, char *end_p)
Packit 6c4009
{
Packit 6c4009
  /* Append [_IO_read_base..end_p] to backup area. */
Packit 6c4009
  ssize_t least_mark = _IO_least_marker (fp, end_p);
Packit 6c4009
  /* needed_size is how much space we need in the backup area. */
Packit 6c4009
  size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
Packit 6c4009
  /* FIXME: Dubious arithmetic if pointers are NULL */
Packit 6c4009
  size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
Packit 6c4009
  size_t avail; /* Extra space available for future expansion. */
Packit 6c4009
  ssize_t delta;
Packit 6c4009
  struct _IO_marker *mark;
Packit 6c4009
  if (needed_size > current_Bsize)
Packit 6c4009
    {
Packit 6c4009
      char *new_buffer;
Packit 6c4009
      avail = 100;
Packit 6c4009
      new_buffer = (char *) malloc (avail + needed_size);
Packit 6c4009
      if (new_buffer == NULL)
Packit 6c4009
	return EOF;		/* FIXME */
Packit 6c4009
      if (least_mark < 0)
Packit 6c4009
	{
Packit 6c4009
	  __mempcpy (__mempcpy (new_buffer + avail,
Packit 6c4009
				fp->_IO_save_end + least_mark,
Packit 6c4009
				-least_mark),
Packit 6c4009
		     fp->_IO_read_base,
Packit 6c4009
		     end_p - fp->_IO_read_base);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	memcpy (new_buffer + avail,
Packit 6c4009
		fp->_IO_read_base + least_mark,
Packit 6c4009
		needed_size);
Packit 6c4009
      free (fp->_IO_save_base);
Packit 6c4009
      fp->_IO_save_base = new_buffer;
Packit 6c4009
      fp->_IO_save_end = new_buffer + avail + needed_size;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      avail = current_Bsize - needed_size;
Packit 6c4009
      if (least_mark < 0)
Packit 6c4009
	{
Packit 6c4009
	  memmove (fp->_IO_save_base + avail,
Packit 6c4009
		   fp->_IO_save_end + least_mark,
Packit 6c4009
		   -least_mark);
Packit 6c4009
	  memcpy (fp->_IO_save_base + avail - least_mark,
Packit 6c4009
		  fp->_IO_read_base,
Packit 6c4009
		  end_p - fp->_IO_read_base);
Packit 6c4009
	}
Packit 6c4009
      else if (needed_size > 0)
Packit 6c4009
	memcpy (fp->_IO_save_base + avail,
Packit 6c4009
		fp->_IO_read_base + least_mark,
Packit 6c4009
		needed_size);
Packit 6c4009
    }
Packit 6c4009
  fp->_IO_backup_base = fp->_IO_save_base + avail;
Packit 6c4009
  /* Adjust all the streammarkers. */
Packit 6c4009
  delta = end_p - fp->_IO_read_base;
Packit 6c4009
  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
Packit 6c4009
    mark->_pos -= delta;
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
__underflow (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
Packit 6c4009
    return EOF;
Packit 6c4009
Packit 6c4009
  if (fp->_mode == 0)
Packit 6c4009
    _IO_fwide (fp, -1);
Packit 6c4009
  if (_IO_in_put_mode (fp))
Packit 6c4009
    if (_IO_switch_to_get_mode (fp) == EOF)
Packit 6c4009
      return EOF;
Packit 6c4009
  if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit 6c4009
    return *(unsigned char *) fp->_IO_read_ptr;
Packit 6c4009
  if (_IO_in_backup (fp))
Packit 6c4009
    {
Packit 6c4009
      _IO_switch_to_main_get_area (fp);
Packit 6c4009
      if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit 6c4009
	return *(unsigned char *) fp->_IO_read_ptr;
Packit 6c4009
    }
Packit 6c4009
  if (_IO_have_markers (fp))
Packit 6c4009
    {
Packit 6c4009
      if (save_for_backup (fp, fp->_IO_read_end))
Packit 6c4009
	return EOF;
Packit 6c4009
    }
Packit 6c4009
  else if (_IO_have_backup (fp))
Packit 6c4009
    _IO_free_backup_area (fp);
Packit 6c4009
  return _IO_UNDERFLOW (fp);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (__underflow)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
__uflow (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
Packit 6c4009
    return EOF;
Packit 6c4009
Packit 6c4009
  if (fp->_mode == 0)
Packit 6c4009
    _IO_fwide (fp, -1);
Packit 6c4009
  if (_IO_in_put_mode (fp))
Packit 6c4009
    if (_IO_switch_to_get_mode (fp) == EOF)
Packit 6c4009
      return EOF;
Packit 6c4009
  if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit 6c4009
    return *(unsigned char *) fp->_IO_read_ptr++;
Packit 6c4009
  if (_IO_in_backup (fp))
Packit 6c4009
    {
Packit 6c4009
      _IO_switch_to_main_get_area (fp);
Packit 6c4009
      if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit 6c4009
	return *(unsigned char *) fp->_IO_read_ptr++;
Packit 6c4009
    }
Packit 6c4009
  if (_IO_have_markers (fp))
Packit 6c4009
    {
Packit 6c4009
      if (save_for_backup (fp, fp->_IO_read_end))
Packit 6c4009
	return EOF;
Packit 6c4009
    }
Packit 6c4009
  else if (_IO_have_backup (fp))
Packit 6c4009
    _IO_free_backup_area (fp);
Packit 6c4009
  return _IO_UFLOW (fp);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (__uflow)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_setb (FILE *f, char *b, char *eb, int a)
Packit 6c4009
{
Packit 6c4009
  if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
Packit 6c4009
    free (f->_IO_buf_base);
Packit 6c4009
  f->_IO_buf_base = b;
Packit 6c4009
  f->_IO_buf_end = eb;
Packit 6c4009
  if (a)
Packit 6c4009
    f->_flags &= ~_IO_USER_BUF;
Packit 6c4009
  else
Packit 6c4009
    f->_flags |= _IO_USER_BUF;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_setb)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_doallocbuf (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  if (fp->_IO_buf_base)
Packit 6c4009
    return;
Packit 6c4009
  if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
Packit 6c4009
    if (_IO_DOALLOCATE (fp) != EOF)
Packit 6c4009
      return;
Packit 6c4009
  _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_doallocbuf)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_underflow (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  return EOF;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_uflow (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  int ch = _IO_UNDERFLOW (fp);
Packit 6c4009
  if (ch == EOF)
Packit 6c4009
    return EOF;
Packit 6c4009
  return *(unsigned char *) fp->_IO_read_ptr++;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_uflow)
Packit 6c4009
Packit 6c4009
size_t
Packit 6c4009
_IO_default_xsputn (FILE *f, const void *data, size_t n)
Packit 6c4009
{
Packit 6c4009
  const char *s = (char *) data;
Packit 6c4009
  size_t more = n;
Packit 6c4009
  if (more <= 0)
Packit 6c4009
    return 0;
Packit 6c4009
  for (;;)
Packit 6c4009
    {
Packit 6c4009
      /* Space available. */
Packit 6c4009
      if (f->_IO_write_ptr < f->_IO_write_end)
Packit 6c4009
	{
Packit 6c4009
	  size_t count = f->_IO_write_end - f->_IO_write_ptr;
Packit 6c4009
	  if (count > more)
Packit 6c4009
	    count = more;
Packit 6c4009
	  if (count > 20)
Packit 6c4009
	    {
Packit 6c4009
	      f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
Packit 6c4009
	      s += count;
Packit 6c4009
	    }
Packit 6c4009
	  else if (count)
Packit 6c4009
	    {
Packit 6c4009
	      char *p = f->_IO_write_ptr;
Packit 6c4009
	      ssize_t i;
Packit 6c4009
	      for (i = count; --i >= 0; )
Packit 6c4009
		*p++ = *s++;
Packit 6c4009
	      f->_IO_write_ptr = p;
Packit 6c4009
	    }
Packit 6c4009
	  more -= count;
Packit 6c4009
	}
Packit 6c4009
      if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
Packit 6c4009
	break;
Packit 6c4009
      more--;
Packit 6c4009
    }
Packit 6c4009
  return n - more;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_xsputn)
Packit 6c4009
Packit 6c4009
size_t
Packit 6c4009
_IO_sgetn (FILE *fp, void *data, size_t n)
Packit 6c4009
{
Packit 6c4009
  /* FIXME handle putback buffer here! */
Packit 6c4009
  return _IO_XSGETN (fp, data, n);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_sgetn)
Packit 6c4009
Packit 6c4009
size_t
Packit 6c4009
_IO_default_xsgetn (FILE *fp, void *data, size_t n)
Packit 6c4009
{
Packit 6c4009
  size_t more = n;
Packit 6c4009
  char *s = (char*) data;
Packit 6c4009
  for (;;)
Packit 6c4009
    {
Packit 6c4009
      /* Data available. */
Packit 6c4009
      if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit 6c4009
	{
Packit 6c4009
	  size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
Packit 6c4009
	  if (count > more)
Packit 6c4009
	    count = more;
Packit 6c4009
	  if (count > 20)
Packit 6c4009
	    {
Packit 6c4009
	      s = __mempcpy (s, fp->_IO_read_ptr, count);
Packit 6c4009
	      fp->_IO_read_ptr += count;
Packit 6c4009
	    }
Packit 6c4009
	  else if (count)
Packit 6c4009
	    {
Packit 6c4009
	      char *p = fp->_IO_read_ptr;
Packit 6c4009
	      int i = (int) count;
Packit 6c4009
	      while (--i >= 0)
Packit 6c4009
		*s++ = *p++;
Packit 6c4009
	      fp->_IO_read_ptr = p;
Packit 6c4009
	    }
Packit 6c4009
	    more -= count;
Packit 6c4009
	}
Packit 6c4009
      if (more == 0 || __underflow (fp) == EOF)
Packit 6c4009
	break;
Packit 6c4009
    }
Packit 6c4009
  return n - more;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_xsgetn)
Packit 6c4009
Packit 6c4009
FILE *
Packit 6c4009
_IO_default_setbuf (FILE *fp, char *p, ssize_t len)
Packit 6c4009
{
Packit 6c4009
    if (_IO_SYNC (fp) == EOF)
Packit 6c4009
	return NULL;
Packit 6c4009
    if (p == NULL || len == 0)
Packit 6c4009
      {
Packit 6c4009
	fp->_flags |= _IO_UNBUFFERED;
Packit 6c4009
	_IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
Packit 6c4009
      }
Packit 6c4009
    else
Packit 6c4009
      {
Packit 6c4009
	fp->_flags &= ~_IO_UNBUFFERED;
Packit 6c4009
	_IO_setb (fp, p, p+len, 0);
Packit 6c4009
      }
Packit 6c4009
    fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
Packit 6c4009
    fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
Packit 6c4009
    return fp;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
off64_t
Packit 6c4009
_IO_default_seekpos (FILE *fp, off64_t pos, int mode)
Packit 6c4009
{
Packit 6c4009
  return _IO_SEEKOFF (fp, pos, 0, mode);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_doallocate (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  char *buf;
Packit 6c4009
Packit 6c4009
  buf = malloc(BUFSIZ);
Packit 6c4009
  if (__glibc_unlikely (buf == NULL))
Packit 6c4009
    return EOF;
Packit 6c4009
Packit 6c4009
  _IO_setb (fp, buf, buf+BUFSIZ, 1);
Packit 6c4009
  return 1;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_doallocate)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_init_internal (FILE *fp, int flags)
Packit 6c4009
{
Packit 6c4009
  _IO_no_init (fp, flags, -1, NULL, NULL);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_init (FILE *fp, int flags)
Packit 6c4009
{
Packit 6c4009
  IO_set_accept_foreign_vtables (&_IO_vtable_check);
Packit 6c4009
  _IO_init_internal (fp, flags);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static int stdio_needs_locking;
Packit 6c4009
Packit 6c4009
/* In a single-threaded process most stdio locks can be omitted.  After
Packit 6c4009
   _IO_enable_locks is called, locks are not optimized away any more.
Packit 6c4009
   It must be first called while the process is still single-threaded.
Packit 6c4009
Packit 6c4009
   This lock optimization can be disabled on a per-file basis by setting
Packit 6c4009
   _IO_FLAGS2_NEED_LOCK, because a file can have user-defined callbacks
Packit 6c4009
   or can be locked with flockfile and then a thread may be created
Packit 6c4009
   between a lock and unlock, so omitting the lock is not valid.
Packit 6c4009
Packit 6c4009
   Here we have to make sure that the flag is set on all existing files
Packit 6c4009
   and files created later.  */
Packit 6c4009
void
Packit 6c4009
_IO_enable_locks (void)
Packit 6c4009
{
Packit 6c4009
  _IO_ITER i;
Packit 6c4009
Packit 6c4009
  if (stdio_needs_locking)
Packit 6c4009
    return;
Packit 6c4009
  stdio_needs_locking = 1;
Packit 6c4009
  for (i = _IO_iter_begin (); i != _IO_iter_end (); i = _IO_iter_next (i))
Packit 6c4009
    _IO_iter_file (i)->_flags2 |= _IO_FLAGS2_NEED_LOCK;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_enable_locks)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_old_init (FILE *fp, int flags)
Packit 6c4009
{
Packit 6c4009
  fp->_flags = _IO_MAGIC|flags;
Packit 6c4009
  fp->_flags2 = 0;
Packit 6c4009
  if (stdio_needs_locking)
Packit 6c4009
    fp->_flags2 |= _IO_FLAGS2_NEED_LOCK;
Packit 6c4009
  fp->_IO_buf_base = NULL;
Packit 6c4009
  fp->_IO_buf_end = NULL;
Packit 6c4009
  fp->_IO_read_base = NULL;
Packit 6c4009
  fp->_IO_read_ptr = NULL;
Packit 6c4009
  fp->_IO_read_end = NULL;
Packit 6c4009
  fp->_IO_write_base = NULL;
Packit 6c4009
  fp->_IO_write_ptr = NULL;
Packit 6c4009
  fp->_IO_write_end = NULL;
Packit 6c4009
  fp->_chain = NULL; /* Not necessary. */
Packit 6c4009
Packit 6c4009
  fp->_IO_save_base = NULL;
Packit 6c4009
  fp->_IO_backup_base = NULL;
Packit 6c4009
  fp->_IO_save_end = NULL;
Packit 6c4009
  fp->_markers = NULL;
Packit 6c4009
  fp->_cur_column = 0;
Packit 6c4009
#if _IO_JUMPS_OFFSET
Packit 6c4009
  fp->_vtable_offset = 0;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  if (fp->_lock != NULL)
Packit 6c4009
    _IO_lock_init (*fp->_lock);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_no_init (FILE *fp, int flags, int orientation,
Packit 6c4009
	     struct _IO_wide_data *wd, const struct _IO_jump_t *jmp)
Packit 6c4009
{
Packit 6c4009
  _IO_old_init (fp, flags);
Packit 6c4009
  fp->_mode = orientation;
Packit 6c4009
  if (orientation >= 0)
Packit 6c4009
    {
Packit 6c4009
      fp->_wide_data = wd;
Packit 6c4009
      fp->_wide_data->_IO_buf_base = NULL;
Packit 6c4009
      fp->_wide_data->_IO_buf_end = NULL;
Packit 6c4009
      fp->_wide_data->_IO_read_base = NULL;
Packit 6c4009
      fp->_wide_data->_IO_read_ptr = NULL;
Packit 6c4009
      fp->_wide_data->_IO_read_end = NULL;
Packit 6c4009
      fp->_wide_data->_IO_write_base = NULL;
Packit 6c4009
      fp->_wide_data->_IO_write_ptr = NULL;
Packit 6c4009
      fp->_wide_data->_IO_write_end = NULL;
Packit 6c4009
      fp->_wide_data->_IO_save_base = NULL;
Packit 6c4009
      fp->_wide_data->_IO_backup_base = NULL;
Packit 6c4009
      fp->_wide_data->_IO_save_end = NULL;
Packit 6c4009
Packit 6c4009
      fp->_wide_data->_wide_vtable = jmp;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    /* Cause predictable crash when a wide function is called on a byte
Packit 6c4009
       stream.  */
Packit 6c4009
    fp->_wide_data = (struct _IO_wide_data *) -1L;
Packit 6c4009
  fp->_freeres_list = NULL;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_sync (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* The way the C++ classes are mapped into the C functions in the
Packit 6c4009
   current implementation, this function can get called twice! */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_default_finish (FILE *fp, int dummy)
Packit 6c4009
{
Packit 6c4009
  struct _IO_marker *mark;
Packit 6c4009
  if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
Packit 6c4009
    {
Packit 6c4009
      free (fp->_IO_buf_base);
Packit 6c4009
      fp->_IO_buf_base = fp->_IO_buf_end = NULL;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
Packit 6c4009
    mark->_sbuf = NULL;
Packit 6c4009
Packit 6c4009
  if (fp->_IO_save_base)
Packit 6c4009
    {
Packit 6c4009
      free (fp->_IO_save_base);
Packit 6c4009
      fp->_IO_save_base = NULL;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  _IO_un_link ((struct _IO_FILE_plus *) fp);
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  if (fp->_lock != NULL)
Packit 6c4009
    _IO_lock_fini (*fp->_lock);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_finish)
Packit 6c4009
Packit 6c4009
off64_t
Packit 6c4009
_IO_default_seekoff (FILE *fp, off64_t offset, int dir, int mode)
Packit 6c4009
{
Packit 6c4009
  return _IO_pos_BAD;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_sputbackc (FILE *fp, int c)
Packit 6c4009
{
Packit 6c4009
  int result;
Packit 6c4009
Packit 6c4009
  if (fp->_IO_read_ptr > fp->_IO_read_base
Packit 6c4009
      && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
Packit 6c4009
    {
Packit 6c4009
      fp->_IO_read_ptr--;
Packit 6c4009
      result = (unsigned char) c;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    result = _IO_PBACKFAIL (fp, c);
Packit 6c4009
Packit 6c4009
  if (result != EOF)
Packit 6c4009
    fp->_flags &= ~_IO_EOF_SEEN;
Packit 6c4009
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_sputbackc)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_sungetc (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  int result;
Packit 6c4009
Packit 6c4009
  if (fp->_IO_read_ptr > fp->_IO_read_base)
Packit 6c4009
    {
Packit 6c4009
      fp->_IO_read_ptr--;
Packit 6c4009
      result = (unsigned char) *fp->_IO_read_ptr;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    result = _IO_PBACKFAIL (fp, EOF);
Packit 6c4009
Packit 6c4009
  if (result != EOF)
Packit 6c4009
    fp->_flags &= ~_IO_EOF_SEEN;
Packit 6c4009
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
unsigned
Packit 6c4009
_IO_adjust_column (unsigned start, const char *line, int count)
Packit 6c4009
{
Packit 6c4009
  const char *ptr = line + count;
Packit 6c4009
  while (ptr > line)
Packit 6c4009
    if (*--ptr == '\n')
Packit 6c4009
      return line + count - ptr - 1;
Packit 6c4009
  return start + count;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_adjust_column)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_flush_all_lockp (int do_lock)
Packit 6c4009
{
Packit 6c4009
  int result = 0;
Packit 6c4009
  FILE *fp;
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_cleanup_region_start_noarg (flush_cleanup);
Packit 6c4009
  _IO_lock_lock (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  for (fp = (FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
Packit 6c4009
    {
Packit 6c4009
      run_fp = fp;
Packit 6c4009
      if (do_lock)
Packit 6c4009
	_IO_flockfile (fp);
Packit 6c4009
Packit 6c4009
      if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
Packit 6c4009
	   || (_IO_vtable_offset (fp) == 0
Packit 6c4009
	       && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
Packit 6c4009
				    > fp->_wide_data->_IO_write_base))
Packit 6c4009
	   )
Packit 6c4009
	  && _IO_OVERFLOW (fp, EOF) == EOF)
Packit 6c4009
	result = EOF;
Packit 6c4009
Packit 6c4009
      if (do_lock)
Packit 6c4009
	_IO_funlockfile (fp);
Packit 6c4009
      run_fp = NULL;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_unlock (list_all_lock);
Packit 6c4009
  _IO_cleanup_region_end (0);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_flush_all (void)
Packit 6c4009
{
Packit 6c4009
  /* We want locking.  */
Packit 6c4009
  return _IO_flush_all_lockp (1);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_flush_all)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_flush_all_linebuffered (void)
Packit 6c4009
{
Packit 6c4009
  FILE *fp;
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_cleanup_region_start_noarg (flush_cleanup);
Packit 6c4009
  _IO_lock_lock (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  for (fp = (FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
Packit 6c4009
    {
Packit 6c4009
      run_fp = fp;
Packit 6c4009
      _IO_flockfile (fp);
Packit 6c4009
Packit 6c4009
      if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
Packit 6c4009
	_IO_OVERFLOW (fp, EOF);
Packit 6c4009
Packit 6c4009
      _IO_funlockfile (fp);
Packit 6c4009
      run_fp = NULL;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_unlock (list_all_lock);
Packit 6c4009
  _IO_cleanup_region_end (0);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_flush_all_linebuffered)
Packit 6c4009
weak_alias (_IO_flush_all_linebuffered, _flushlbf)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The following is a bit tricky.  In general, we want to unbuffer the
Packit 6c4009
   streams so that all output which follows is seen.  If we are not
Packit 6c4009
   looking for memory leaks it does not make much sense to free the
Packit 6c4009
   actual buffer because this will happen anyway once the program
Packit 6c4009
   terminated.  If we do want to look for memory leaks we have to free
Packit 6c4009
   the buffers.  Whether something is freed is determined by the
Packit 6c4009
   function sin the libc_freeres section.  Those are called as part of
Packit 6c4009
   the atexit routine, just like _IO_cleanup.  The problem is we do
Packit 6c4009
   not know whether the freeres code is called first or _IO_cleanup.
Packit 6c4009
   if the former is the case, we set the DEALLOC_BUFFER variable to
Packit 6c4009
   true and _IO_unbuffer_all will take care of the rest.  If
Packit 6c4009
   _IO_unbuffer_all is called first we add the streams to a list
Packit 6c4009
   which the freeres function later can walk through.  */
Packit 6c4009
static void _IO_unbuffer_all (void);
Packit 6c4009
Packit 6c4009
static bool dealloc_buffers;
Packit 6c4009
static FILE *freeres_list;
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
_IO_unbuffer_all (void)
Packit 6c4009
{
Packit 6c4009
  FILE *fp;
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_cleanup_region_start_noarg (flush_cleanup);
Packit 6c4009
  _IO_lock_lock (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
Packit 6c4009
    {
Packit 6c4009
      if (! (fp->_flags & _IO_UNBUFFERED)
Packit 6c4009
	  /* Iff stream is un-orientated, it wasn't used. */
Packit 6c4009
	  && fp->_mode != 0)
Packit 6c4009
	{
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
	  int cnt;
Packit 6c4009
#define MAXTRIES 2
Packit 6c4009
	  for (cnt = 0; cnt < MAXTRIES; ++cnt)
Packit 6c4009
	    if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
Packit 6c4009
	      break;
Packit 6c4009
	    else
Packit 6c4009
	      /* Give the other thread time to finish up its use of the
Packit 6c4009
		 stream.  */
Packit 6c4009
	      __sched_yield ();
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
	  if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
Packit 6c4009
	    {
Packit 6c4009
	      fp->_flags |= _IO_USER_BUF;
Packit 6c4009
Packit 6c4009
	      fp->_freeres_list = freeres_list;
Packit 6c4009
	      freeres_list = fp;
Packit 6c4009
	      fp->_freeres_buf = fp->_IO_buf_base;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  _IO_SETBUF (fp, NULL, 0);
Packit 6c4009
Packit 6c4009
	  if (fp->_mode > 0)
Packit 6c4009
	    _IO_wsetb (fp, NULL, NULL, 0);
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
	  if (cnt < MAXTRIES && fp->_lock != NULL)
Packit 6c4009
	    _IO_lock_unlock (*fp->_lock);
Packit 6c4009
#endif
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Make sure that never again the wide char functions can be
Packit 6c4009
	 used.  */
Packit 6c4009
      fp->_mode = -1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_unlock (list_all_lock);
Packit 6c4009
  _IO_cleanup_region_end (0);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
libc_freeres_fn (buffer_free)
Packit 6c4009
{
Packit 6c4009
  dealloc_buffers = true;
Packit 6c4009
Packit 6c4009
  while (freeres_list != NULL)
Packit 6c4009
    {
Packit 6c4009
      free (freeres_list->_freeres_buf);
Packit 6c4009
Packit 6c4009
      freeres_list = freeres_list->_freeres_list;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_cleanup (void)
Packit 6c4009
{
Packit 6c4009
  /* We do *not* want locking.  Some threads might use streams but
Packit 6c4009
     that is their problem, we flush them underneath them.  */
Packit 6c4009
  int result = _IO_flush_all_lockp (0);
Packit 6c4009
Packit 6c4009
  /* We currently don't have a reliable mechanism for making sure that
Packit 6c4009
     C++ static destructors are executed in the correct order.
Packit 6c4009
     So it is possible that other static destructors might want to
Packit 6c4009
     write to cout - and they're supposed to be able to do so.
Packit 6c4009
Packit 6c4009
     The following will make the standard streambufs be unbuffered,
Packit 6c4009
     which forces any output from late destructors to be written out. */
Packit 6c4009
  _IO_unbuffer_all ();
Packit 6c4009
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_init_marker (struct _IO_marker *marker, FILE *fp)
Packit 6c4009
{
Packit 6c4009
  marker->_sbuf = fp;
Packit 6c4009
  if (_IO_in_put_mode (fp))
Packit 6c4009
    _IO_switch_to_get_mode (fp);
Packit 6c4009
  if (_IO_in_backup (fp))
Packit 6c4009
    marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
Packit 6c4009
  else
Packit 6c4009
    marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
Packit 6c4009
Packit 6c4009
  /* Should perhaps sort the chain? */
Packit 6c4009
  marker->_next = fp->_markers;
Packit 6c4009
  fp->_markers = marker;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_remove_marker (struct _IO_marker *marker)
Packit 6c4009
{
Packit 6c4009
  /* Unlink from sb's chain. */
Packit 6c4009
  struct _IO_marker **ptr = &marker->_sbuf->_markers;
Packit 6c4009
  for (; ; ptr = &(*ptr)->_next)
Packit 6c4009
    {
Packit 6c4009
      if (*ptr == NULL)
Packit 6c4009
	break;
Packit 6c4009
      else if (*ptr == marker)
Packit 6c4009
	{
Packit 6c4009
	  *ptr = marker->_next;
Packit 6c4009
	  return;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  /* FIXME: if _sbuf has a backup area that is no longer needed,
Packit 6c4009
     should we delete it now, or wait until the next underflow? */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define BAD_DELTA EOF
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2)
Packit 6c4009
{
Packit 6c4009
  return mark1->_pos - mark2->_pos;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Return difference between MARK and current position of MARK's stream. */
Packit 6c4009
int
Packit 6c4009
_IO_marker_delta (struct _IO_marker *mark)
Packit 6c4009
{
Packit 6c4009
  int cur_pos;
Packit 6c4009
  if (mark->_sbuf == NULL)
Packit 6c4009
    return BAD_DELTA;
Packit 6c4009
  if (_IO_in_backup (mark->_sbuf))
Packit 6c4009
    cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
Packit 6c4009
  else
Packit 6c4009
    cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
Packit 6c4009
  return mark->_pos - cur_pos;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_seekmark (FILE *fp, struct _IO_marker *mark, int delta)
Packit 6c4009
{
Packit 6c4009
  if (mark->_sbuf != fp)
Packit 6c4009
    return EOF;
Packit 6c4009
 if (mark->_pos >= 0)
Packit 6c4009
    {
Packit 6c4009
      if (_IO_in_backup (fp))
Packit 6c4009
	_IO_switch_to_main_get_area (fp);
Packit 6c4009
      fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if (!_IO_in_backup (fp))
Packit 6c4009
	_IO_switch_to_backup_area (fp);
Packit 6c4009
      fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
Packit 6c4009
    }
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_unsave_markers (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  struct _IO_marker *mark = fp->_markers;
Packit 6c4009
  if (mark)
Packit 6c4009
    {
Packit 6c4009
      fp->_markers = 0;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (_IO_have_backup (fp))
Packit 6c4009
    _IO_free_backup_area (fp);
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_unsave_markers)
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_pbackfail (FILE *fp, int c)
Packit 6c4009
{
Packit 6c4009
  if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
Packit 6c4009
      && (unsigned char) fp->_IO_read_ptr[-1] == c)
Packit 6c4009
    --fp->_IO_read_ptr;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
Packit 6c4009
      if (!_IO_in_backup (fp))
Packit 6c4009
	{
Packit 6c4009
	  /* We need to keep the invariant that the main get area
Packit 6c4009
	     logically follows the backup area.  */
Packit 6c4009
	  if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
Packit 6c4009
	    {
Packit 6c4009
	      if (save_for_backup (fp, fp->_IO_read_ptr))
Packit 6c4009
		return EOF;
Packit 6c4009
	    }
Packit 6c4009
	  else if (!_IO_have_backup (fp))
Packit 6c4009
	    {
Packit 6c4009
	      /* No backup buffer: allocate one. */
Packit 6c4009
	      /* Use nshort buffer, if unused? (probably not)  FIXME */
Packit 6c4009
	      int backup_size = 128;
Packit 6c4009
	      char *bbuf = (char *) malloc (backup_size);
Packit 6c4009
	      if (bbuf == NULL)
Packit 6c4009
		return EOF;
Packit 6c4009
	      fp->_IO_save_base = bbuf;
Packit 6c4009
	      fp->_IO_save_end = fp->_IO_save_base + backup_size;
Packit 6c4009
	      fp->_IO_backup_base = fp->_IO_save_end;
Packit 6c4009
	    }
Packit 6c4009
	  fp->_IO_read_base = fp->_IO_read_ptr;
Packit 6c4009
	  _IO_switch_to_backup_area (fp);
Packit 6c4009
	}
Packit 6c4009
      else if (fp->_IO_read_ptr <= fp->_IO_read_base)
Packit 6c4009
	{
Packit 6c4009
	  /* Increase size of existing backup buffer. */
Packit 6c4009
	  size_t new_size;
Packit 6c4009
	  size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
Packit 6c4009
	  char *new_buf;
Packit 6c4009
	  new_size = 2 * old_size;
Packit 6c4009
	  new_buf = (char *) malloc (new_size);
Packit 6c4009
	  if (new_buf == NULL)
Packit 6c4009
	    return EOF;
Packit 6c4009
	  memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
Packit 6c4009
		  old_size);
Packit 6c4009
	  free (fp->_IO_read_base);
Packit 6c4009
	  _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
Packit 6c4009
		    new_buf + new_size);
Packit 6c4009
	  fp->_IO_backup_base = fp->_IO_read_ptr;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      *--fp->_IO_read_ptr = c;
Packit 6c4009
    }
Packit 6c4009
  return (unsigned char) c;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_default_pbackfail)
Packit 6c4009
Packit 6c4009
off64_t
Packit 6c4009
_IO_default_seek (FILE *fp, off64_t offset, int dir)
Packit 6c4009
{
Packit 6c4009
  return _IO_pos_BAD;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_stat (FILE *fp, void *st)
Packit 6c4009
{
Packit 6c4009
  return EOF;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
ssize_t
Packit 6c4009
_IO_default_read (FILE *fp, void *data, ssize_t n)
Packit 6c4009
{
Packit 6c4009
  return -1;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
ssize_t
Packit 6c4009
_IO_default_write (FILE *fp, const void *data, ssize_t n)
Packit 6c4009
{
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
_IO_default_showmanyc (FILE *fp)
Packit 6c4009
{
Packit 6c4009
  return -1;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_default_imbue (FILE *fp, void *locale)
Packit 6c4009
{
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
_IO_ITER
Packit 6c4009
_IO_iter_begin (void)
Packit 6c4009
{
Packit 6c4009
  return (_IO_ITER) _IO_list_all;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_iter_begin)
Packit 6c4009
Packit 6c4009
_IO_ITER
Packit 6c4009
_IO_iter_end (void)
Packit 6c4009
{
Packit 6c4009
  return NULL;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_iter_end)
Packit 6c4009
Packit 6c4009
_IO_ITER
Packit 6c4009
_IO_iter_next (_IO_ITER iter)
Packit 6c4009
{
Packit 6c4009
  return iter->_chain;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_iter_next)
Packit 6c4009
Packit 6c4009
FILE *
Packit 6c4009
_IO_iter_file (_IO_ITER iter)
Packit 6c4009
{
Packit 6c4009
  return iter;
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_iter_file)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_list_lock (void)
Packit 6c4009
{
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_lock (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_list_lock)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_list_unlock (void)
Packit 6c4009
{
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_unlock (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_list_unlock)
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_IO_list_resetlock (void)
Packit 6c4009
{
Packit 6c4009
#ifdef _IO_MTSAFE_IO
Packit 6c4009
  _IO_lock_init (list_all_lock);
Packit 6c4009
#endif
Packit 6c4009
}
Packit 6c4009
libc_hidden_def (_IO_list_resetlock)
Packit 6c4009
Packit 6c4009
text_set_element(__libc_atexit, _IO_cleanup);