Blame libio/oldfileops.c

Packit Service 82fcde
/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Written by Per Bothner <bothner@cygnus.com>.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.
Packit Service 82fcde
Packit Service 82fcde
   As a special exception, if you link the code in this file with
Packit Service 82fcde
   files compiled with a GNU compiler to produce an executable,
Packit Service 82fcde
   that does not cause the resulting executable to be covered by
Packit Service 82fcde
   the GNU Lesser General Public License.  This exception does not
Packit Service 82fcde
   however invalidate any other reasons why the executable file
Packit Service 82fcde
   might be covered by the GNU Lesser General Public License.
Packit Service 82fcde
   This exception applies to code released by its copyright holders
Packit Service 82fcde
   in files containing the exception.  */
Packit Service 82fcde
Packit Service 82fcde
/* This is a compatibility file.  If we don't build the libc with
Packit Service 82fcde
   versioning don't compile this file.  */
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
Packit Service 82fcde
Packit Service 82fcde
#define _IO_USE_OLD_IO_FILE
Packit Service 82fcde
#include "libioP.h"
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
#include <sys/types.h>
Packit Service 82fcde
#include <sys/stat.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
Packit Service 82fcde
/* An fstream can be in at most one of put mode, get mode, or putback mode.
Packit Service 82fcde
   Putback mode is a variant of get mode.
Packit Service 82fcde
Packit Service 82fcde
   In a filebuf, there is only one current position, instead of two
Packit Service 82fcde
   separate get and put pointers.  In get mode, the current position
Packit Service 82fcde
   is that of gptr(); in put mode that of pptr().
Packit Service 82fcde
Packit Service 82fcde
   The position in the buffer that corresponds to the position
Packit Service 82fcde
   in external file system is normally _IO_read_end, except in putback
Packit Service 82fcde
   mode, when it is _IO_save_end.
Packit Service 82fcde
   If the field _fb._offset is >= 0, it gives the offset in
Packit Service 82fcde
   the file as a whole corresponding to eGptr(). (?)
Packit Service 82fcde
Packit Service 82fcde
   PUT MODE:
Packit Service 82fcde
   If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
Packit Service 82fcde
   and _IO_read_base are equal to each other.  These are usually equal
Packit Service 82fcde
   to _IO_buf_base, though not necessarily if we have switched from
Packit Service 82fcde
   get mode to put mode.  (The reason is to maintain the invariant
Packit Service 82fcde
   that _IO_read_end corresponds to the external file position.)
Packit Service 82fcde
   _IO_write_base is non-NULL and usually equal to _IO_buf_base.
Packit Service 82fcde
   We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
Packit Service 82fcde
   The un-flushed character are those between _IO_write_base and _IO_write_ptr.
Packit Service 82fcde
Packit Service 82fcde
   GET MODE:
Packit Service 82fcde
   If a filebuf is in get or putback mode, eback() != egptr().
Packit Service 82fcde
   In get mode, the unread characters are between gptr() and egptr().
Packit Service 82fcde
   The OS file position corresponds to that of egptr().
Packit Service 82fcde
Packit Service 82fcde
   PUTBACK MODE:
Packit Service 82fcde
   Putback mode is used to remember "excess" characters that have
Packit Service 82fcde
   been sputbackc'd in a separate putback buffer.
Packit Service 82fcde
   In putback mode, the get buffer points to the special putback buffer.
Packit Service 82fcde
   The unread characters are the characters between gptr() and egptr()
Packit Service 82fcde
   in the putback buffer, as well as the area between save_gptr()
Packit Service 82fcde
   and save_egptr(), which point into the original reserve buffer.
Packit Service 82fcde
   (The pointers save_gptr() and save_egptr() are the values
Packit Service 82fcde
   of gptr() and egptr() at the time putback mode was entered.)
Packit Service 82fcde
   The OS position corresponds to that of save_egptr().
Packit Service 82fcde
Packit Service 82fcde
   LINE BUFFERED OUTPUT:
Packit Service 82fcde
   During line buffered output, _IO_write_base==base() && epptr()==base().
Packit Service 82fcde
   However, ptr() may be anywhere between base() and ebuf().
Packit Service 82fcde
   This forces a call to filebuf::overflow(int C) on every put.
Packit Service 82fcde
   If there is more space in the buffer, and C is not a '\n',
Packit Service 82fcde
   then C is inserted, and pptr() incremented.
Packit Service 82fcde
Packit Service 82fcde
   UNBUFFERED STREAMS:
Packit Service 82fcde
   If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
Packit Service 82fcde
*/
Packit Service 82fcde
Packit Service 82fcde
#define CLOSED_FILEBUF_FLAGS \
Packit Service 82fcde
  (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_init_internal (struct _IO_FILE_plus *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* POSIX.1 allows another file handle to be used to change the position
Packit Service 82fcde
     of our file descriptor.  Hence we actually don't know the actual
Packit Service 82fcde
     position before we do the first fseek (and until a following fflush). */
Packit Service 82fcde
  fp->file._old_offset = _IO_pos_BAD;
Packit Service 82fcde
  fp->file._flags |= CLOSED_FILEBUF_FLAGS;
Packit Service 82fcde
Packit Service 82fcde
  _IO_link_in (fp);
Packit Service 82fcde
  fp->file._vtable_offset = ((int) sizeof (struct _IO_FILE)
Packit Service 82fcde
			     - (int) sizeof (struct _IO_FILE_complete));
Packit Service 82fcde
  fp->file._fileno = -1;
Packit Service 82fcde
Packit Service 82fcde
  if (__builtin_expect (&_IO_stdin_used != NULL, 1)
Packit Service 82fcde
      || (fp != (struct _IO_FILE_plus *) _IO_stdin
Packit Service 82fcde
	  && fp != (struct _IO_FILE_plus *) _IO_stdout
Packit Service 82fcde
	  && fp != (struct _IO_FILE_plus *) _IO_stderr))
Packit Service 82fcde
    /* The object is dynamically allocated and large enough.  Initialize
Packit Service 82fcde
       the _mode element as well.  */
Packit Service 82fcde
    ((struct _IO_FILE_complete *) fp)->_mode = -1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_init (struct _IO_FILE_plus *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  IO_set_accept_foreign_vtables (&_IO_vtable_check);
Packit Service 82fcde
  _IO_old_file_init_internal (fp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_close_it (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  int write_status, close_status;
Packit Service 82fcde
  if (!_IO_file_is_open (fp))
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
Packit Service 82fcde
  write_status = _IO_old_do_flush (fp);
Packit Service 82fcde
Packit Service 82fcde
  _IO_unsave_markers (fp);
Packit Service 82fcde
Packit Service 82fcde
  close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
Packit Service 82fcde
		  ? _IO_SYSCLOSE (fp) : 0);
Packit Service 82fcde
Packit Service 82fcde
  /* Free buffer. */
Packit Service 82fcde
  _IO_setb (fp, NULL, NULL, 0);
Packit Service 82fcde
  _IO_setg (fp, NULL, NULL, NULL);
Packit Service 82fcde
  _IO_setp (fp, NULL, NULL);
Packit Service 82fcde
Packit Service 82fcde
  _IO_un_link ((struct _IO_FILE_plus *) fp);
Packit Service 82fcde
  fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
Packit Service 82fcde
  fp->_fileno = -1;
Packit Service 82fcde
  fp->_old_offset = _IO_pos_BAD;
Packit Service 82fcde
Packit Service 82fcde
  return close_status ? close_status : write_status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_finish (FILE *fp, int dummy)
Packit Service 82fcde
{
Packit Service 82fcde
  if (_IO_file_is_open (fp))
Packit Service 82fcde
    {
Packit Service 82fcde
      _IO_old_do_flush (fp);
Packit Service 82fcde
      if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
Packit Service 82fcde
	_IO_SYSCLOSE (fp);
Packit Service 82fcde
    }
Packit Service 82fcde
  _IO_default_finish (fp, 0);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_fopen (FILE *fp, const char *filename, const char *mode)
Packit Service 82fcde
{
Packit Service 82fcde
  int oflags = 0, omode;
Packit Service 82fcde
  int read_write, fdesc;
Packit Service 82fcde
  int oprot = 0666;
Packit Service 82fcde
  if (_IO_file_is_open (fp))
Packit Service 82fcde
    return 0;
Packit Service 82fcde
  switch (*mode++)
Packit Service 82fcde
    {
Packit Service 82fcde
    case 'r':
Packit Service 82fcde
      omode = O_RDONLY;
Packit Service 82fcde
      read_write = _IO_NO_WRITES;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case 'w':
Packit Service 82fcde
      omode = O_WRONLY;
Packit Service 82fcde
      oflags = O_CREAT|O_TRUNC;
Packit Service 82fcde
      read_write = _IO_NO_READS;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case 'a':
Packit Service 82fcde
      omode = O_WRONLY;
Packit Service 82fcde
      oflags = O_CREAT|O_APPEND;
Packit Service 82fcde
      read_write = _IO_NO_READS|_IO_IS_APPENDING;
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      __set_errno (EINVAL);
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
Packit Service 82fcde
    {
Packit Service 82fcde
      omode = O_RDWR;
Packit Service 82fcde
      read_write &= _IO_IS_APPENDING;
Packit Service 82fcde
    }
Packit Service 82fcde
  fdesc = __open (filename, omode|oflags, oprot);
Packit Service 82fcde
  if (fdesc < 0)
Packit Service 82fcde
    return NULL;
Packit Service 82fcde
  fp->_fileno = fdesc;
Packit Service 82fcde
  _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
Packit Service 82fcde
  if (read_write & _IO_IS_APPENDING)
Packit Service 82fcde
    if (_IO_SEEKOFF (fp, (off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
Packit Service 82fcde
	== _IO_pos_BAD && errno != ESPIPE)
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
  _IO_link_in ((struct _IO_FILE_plus *) fp);
Packit Service 82fcde
  return fp;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_attach (FILE *fp, int fd)
Packit Service 82fcde
{
Packit Service 82fcde
  if (_IO_file_is_open (fp))
Packit Service 82fcde
    return NULL;
Packit Service 82fcde
  fp->_fileno = fd;
Packit Service 82fcde
  fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
Packit Service 82fcde
  fp->_flags |= _IO_DELETE_DONT_CLOSE;
Packit Service 82fcde
  /* Get the current position of the file. */
Packit Service 82fcde
  /* We have to do that since that may be junk. */
Packit Service 82fcde
  fp->_old_offset = _IO_pos_BAD;
Packit Service 82fcde
  if (_IO_SEEKOFF (fp, (off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
Packit Service 82fcde
      == _IO_pos_BAD && errno != ESPIPE)
Packit Service 82fcde
    return NULL;
Packit Service 82fcde
  return fp;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_setbuf (FILE *fp, char *p, ssize_t len)
Packit Service 82fcde
{
Packit Service 82fcde
    if (_IO_default_setbuf (fp, p, len) == NULL)
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
Packit Service 82fcde
    fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
Packit Service 82fcde
      = fp->_IO_buf_base;
Packit Service 82fcde
    _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
Packit Service 82fcde
    return fp;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int old_do_write (FILE *, const char *, size_t);
Packit Service 82fcde
Packit Service 82fcde
/* Write TO_DO bytes from DATA to FP.
Packit Service 82fcde
   Then mark FP as having empty buffers. */
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_do_write (FILE *fp, const char *data, size_t to_do)
Packit Service 82fcde
{
Packit Service 82fcde
  return (to_do == 0 || (size_t) old_do_write (fp, data, to_do) == to_do)
Packit Service 82fcde
	 ? 0 : EOF;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
old_do_write (FILE *fp, const char *data, size_t to_do)
Packit Service 82fcde
{
Packit Service 82fcde
  size_t count;
Packit Service 82fcde
  if (fp->_flags & _IO_IS_APPENDING)
Packit Service 82fcde
    /* On a system without a proper O_APPEND implementation,
Packit Service 82fcde
       you would need to sys_seek(0, SEEK_END) here, but is
Packit Service 82fcde
       not needed nor desirable for Unix- or Posix-like systems.
Packit Service 82fcde
       Instead, just indicate that offset (before and after) is
Packit Service 82fcde
       unpredictable. */
Packit Service 82fcde
    fp->_old_offset = _IO_pos_BAD;
Packit Service 82fcde
  else if (fp->_IO_read_end != fp->_IO_write_base)
Packit Service 82fcde
    {
Packit Service 82fcde
      off_t new_pos
Packit Service 82fcde
	= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
Packit Service 82fcde
      if (new_pos == _IO_pos_BAD)
Packit Service 82fcde
	return 0;
Packit Service 82fcde
      fp->_old_offset = new_pos;
Packit Service 82fcde
    }
Packit Service 82fcde
  count = _IO_SYSWRITE (fp, data, to_do);
Packit Service 82fcde
  if (fp->_cur_column && count)
Packit Service 82fcde
    fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
Packit Service 82fcde
  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
Packit Service 82fcde
  fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED))
Packit Service 82fcde
		       ? fp->_IO_buf_base : fp->_IO_buf_end);
Packit Service 82fcde
  return count;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_underflow (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  ssize_t count;
Packit Service 82fcde
Packit Service 82fcde
  /* C99 requires EOF to be "sticky".  */
Packit Service 82fcde
  if (fp->_flags & _IO_EOF_SEEN)
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_flags & _IO_NO_READS)
Packit Service 82fcde
    {
Packit Service 82fcde
      fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
      __set_errno (EBADF);
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit Service 82fcde
    return *(unsigned char *) fp->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_IO_buf_base == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Maybe we already have a push back pointer.  */
Packit Service 82fcde
      if (fp->_IO_save_base != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (fp->_IO_save_base);
Packit Service 82fcde
	  fp->_flags &= ~_IO_IN_BACKUP;
Packit Service 82fcde
	}
Packit Service 82fcde
      _IO_doallocbuf (fp);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Flush all line buffered files before reading. */
Packit Service 82fcde
  /* FIXME This can/should be moved to genops ?? */
Packit Service 82fcde
  if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
Packit Service 82fcde
    _IO_flush_all_linebuffered ();
Packit Service 82fcde
Packit Service 82fcde
  _IO_switch_to_get_mode (fp);
Packit Service 82fcde
Packit Service 82fcde
  /* This is very tricky. We have to adjust those
Packit Service 82fcde
     pointers before we call _IO_SYSREAD () since
Packit Service 82fcde
     we may longjump () out while waiting for
Packit Service 82fcde
     input. Those pointers may be screwed up. H.J. */
Packit Service 82fcde
  fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
Packit Service 82fcde
  fp->_IO_read_end = fp->_IO_buf_base;
Packit Service 82fcde
  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
Packit Service 82fcde
    = fp->_IO_buf_base;
Packit Service 82fcde
Packit Service 82fcde
  count = _IO_SYSREAD (fp, fp->_IO_buf_base,
Packit Service 82fcde
		       fp->_IO_buf_end - fp->_IO_buf_base);
Packit Service 82fcde
  if (count <= 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (count == 0)
Packit Service 82fcde
	fp->_flags |= _IO_EOF_SEEN;
Packit Service 82fcde
      else
Packit Service 82fcde
	fp->_flags |= _IO_ERR_SEEN, count = 0;
Packit Service 82fcde
  }
Packit Service 82fcde
  fp->_IO_read_end += count;
Packit Service 82fcde
  if (count == 0)
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
  if (fp->_old_offset != _IO_pos_BAD)
Packit Service 82fcde
    _IO_pos_adjust (fp->_old_offset, count);
Packit Service 82fcde
  return *(unsigned char *) fp->_IO_read_ptr;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_overflow (FILE *f, int ch)
Packit Service 82fcde
{
Packit Service 82fcde
  if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
Packit Service 82fcde
    {
Packit Service 82fcde
      f->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
      __set_errno (EBADF);
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* If currently reading or no buffer allocated. */
Packit Service 82fcde
  if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Allocate a buffer if needed. */
Packit Service 82fcde
      if (f->_IO_write_base == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  _IO_doallocbuf (f);
Packit Service 82fcde
	  _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
Packit Service 82fcde
	}
Packit Service 82fcde
      /* Otherwise must be currently reading.
Packit Service 82fcde
	 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
Packit Service 82fcde
	 logically slide the buffer forwards one block (by setting the
Packit Service 82fcde
	 read pointers to all point at the beginning of the block).  This
Packit Service 82fcde
	 makes room for subsequent output.
Packit Service 82fcde
	 Otherwise, set the read pointers to _IO_read_end (leaving that
Packit Service 82fcde
	 alone, so it can continue to correspond to the external position). */
Packit Service 82fcde
      if (f->_IO_read_ptr == f->_IO_buf_end)
Packit Service 82fcde
	f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
Packit Service 82fcde
      f->_IO_write_ptr = f->_IO_read_ptr;
Packit Service 82fcde
      f->_IO_write_base = f->_IO_write_ptr;
Packit Service 82fcde
      f->_IO_write_end = f->_IO_buf_end;
Packit Service 82fcde
      f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
Packit Service 82fcde
Packit Service 82fcde
      if (f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED))
Packit Service 82fcde
	f->_IO_write_end = f->_IO_write_ptr;
Packit Service 82fcde
      f->_flags |= _IO_CURRENTLY_PUTTING;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (ch == EOF)
Packit Service 82fcde
    return _IO_old_do_flush (f);
Packit Service 82fcde
  if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
Packit Service 82fcde
    if (_IO_old_do_flush (f) == EOF)
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
  *f->_IO_write_ptr++ = ch;
Packit Service 82fcde
  if ((f->_flags & _IO_UNBUFFERED)
Packit Service 82fcde
      || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
Packit Service 82fcde
    if (_IO_old_do_flush (f) == EOF)
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
  return (unsigned char) ch;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_sync (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  ssize_t delta;
Packit Service 82fcde
  int retval = 0;
Packit Service 82fcde
Packit Service 82fcde
  /*    char* ptr = cur_ptr(); */
Packit Service 82fcde
  if (fp->_IO_write_ptr > fp->_IO_write_base)
Packit Service 82fcde
    if (_IO_old_do_flush(fp)) return EOF;
Packit Service 82fcde
  delta = fp->_IO_read_ptr - fp->_IO_read_end;
Packit Service 82fcde
  if (delta != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
#ifdef TODO
Packit Service 82fcde
      if (_IO_in_backup (fp))
Packit Service 82fcde
	delta -= eGptr () - Gbase ();
Packit Service 82fcde
#endif
Packit Service 82fcde
      off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
Packit Service 82fcde
      if (new_pos != (off_t) EOF)
Packit Service 82fcde
	fp->_IO_read_end = fp->_IO_read_ptr;
Packit Service 82fcde
      else if (errno == ESPIPE)
Packit Service 82fcde
	; /* Ignore error from unseekable devices. */
Packit Service 82fcde
      else
Packit Service 82fcde
	retval = EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (retval != EOF)
Packit Service 82fcde
    fp->_old_offset = _IO_pos_BAD;
Packit Service 82fcde
  /* FIXME: Cleanup - can this be shared? */
Packit Service 82fcde
  /*    setg(base(), ptr, ptr); */
Packit Service 82fcde
  return retval;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
off64_t
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_seekoff (FILE *fp, off64_t offset, int dir, int mode)
Packit Service 82fcde
{
Packit Service 82fcde
  off_t result;
Packit Service 82fcde
  off64_t delta, new_offset;
Packit Service 82fcde
  long count;
Packit Service 82fcde
  /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
Packit Service 82fcde
     offset of the underlying file must be exact.  */
Packit Service 82fcde
  int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
Packit Service 82fcde
		       && fp->_IO_write_base == fp->_IO_write_ptr);
Packit Service 82fcde
Packit Service 82fcde
  if (mode == 0)
Packit Service 82fcde
    dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
Packit Service 82fcde
Packit Service 82fcde
  /* Flush unwritten characters.
Packit Service 82fcde
     (This may do an unneeded write if we seek within the buffer.
Packit Service 82fcde
     But to be able to switch to reading, we would need to set
Packit Service 82fcde
     egptr to pptr.  That can't be done in the current design,
Packit Service 82fcde
     which assumes file_ptr() is eGptr.  Anyway, since we probably
Packit Service 82fcde
     end up flushing when we close(), it doesn't make much difference.)
Packit Service 82fcde
     FIXME: simulate mem-mapped files. */
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
Packit Service 82fcde
    if (_IO_switch_to_get_mode (fp))
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_IO_buf_base == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* It could be that we already have a pushback buffer.  */
Packit Service 82fcde
      if (fp->_IO_read_base != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (fp->_IO_read_base);
Packit Service 82fcde
	  fp->_flags &= ~_IO_IN_BACKUP;
Packit Service 82fcde
	}
Packit Service 82fcde
      _IO_doallocbuf (fp);
Packit Service 82fcde
      _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
      _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  switch (dir)
Packit Service 82fcde
    {
Packit Service 82fcde
    case _IO_seek_cur:
Packit Service 82fcde
      /* Adjust for read-ahead (bytes is buffer). */
Packit Service 82fcde
      offset -= fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
      if (fp->_old_offset == _IO_pos_BAD)
Packit Service 82fcde
	goto dumb;
Packit Service 82fcde
      /* Make offset absolute, assuming current pointer is file_ptr(). */
Packit Service 82fcde
      offset += fp->_old_offset;
Packit Service 82fcde
Packit Service 82fcde
      dir = _IO_seek_set;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case _IO_seek_set:
Packit Service 82fcde
      break;
Packit Service 82fcde
    case _IO_seek_end:
Packit Service 82fcde
      {
Packit Service 82fcde
	struct stat64 st;
Packit Service 82fcde
	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
Packit Service 82fcde
	  {
Packit Service 82fcde
	    offset += st.st_size;
Packit Service 82fcde
	    dir = _IO_seek_set;
Packit Service 82fcde
	  }
Packit Service 82fcde
	else
Packit Service 82fcde
	  goto dumb;
Packit Service 82fcde
      }
Packit Service 82fcde
    }
Packit Service 82fcde
  /* At this point, dir==_IO_seek_set. */
Packit Service 82fcde
Packit Service 82fcde
  /* If we are only interested in the current position we've found it now.  */
Packit Service 82fcde
  if (mode == 0)
Packit Service 82fcde
    return offset;
Packit Service 82fcde
Packit Service 82fcde
  /* If destination is within current buffer, optimize: */
Packit Service 82fcde
  if (fp->_old_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
Packit Service 82fcde
      && !_IO_in_backup (fp))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Offset relative to start of main get area. */
Packit Service 82fcde
      off_t rel_offset = (offset - fp->_old_offset
Packit Service 82fcde
                          + (fp->_IO_read_end - fp->_IO_read_base));
Packit Service 82fcde
      if (rel_offset >= 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
Packit Service 82fcde
			fp->_IO_read_end);
Packit Service 82fcde
	      _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
	      {
Packit Service 82fcde
		_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
		goto resync;
Packit Service 82fcde
	      }
Packit Service 82fcde
	    }
Packit Service 82fcde
#ifdef TODO
Packit Service 82fcde
	    /* If we have streammarkers, seek forward by reading ahead. */
Packit Service 82fcde
	    if (_IO_have_markers (fp))
Packit Service 82fcde
	      {
Packit Service 82fcde
		int to_skip = rel_offset
Packit Service 82fcde
		  - (fp->_IO_read_ptr - fp->_IO_read_base);
Packit Service 82fcde
		if (ignore (to_skip) != to_skip)
Packit Service 82fcde
		  goto dumb;
Packit Service 82fcde
		_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
		goto resync;
Packit Service 82fcde
	      }
Packit Service 82fcde
#endif
Packit Service 82fcde
	}
Packit Service 82fcde
#ifdef TODO
Packit Service 82fcde
      if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (!_IO_in_backup (fp))
Packit Service 82fcde
	    _IO_switch_to_backup_area (fp);
Packit Service 82fcde
	  gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
Packit Service 82fcde
	  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
	  goto resync;
Packit Service 82fcde
	}
Packit Service 82fcde
#endif
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#ifdef TODO
Packit Service 82fcde
  _IO_unsave_markers (fp);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_flags & _IO_NO_READS)
Packit Service 82fcde
    goto dumb;
Packit Service 82fcde
Packit Service 82fcde
  /* Try to seek to a block boundary, to improve kernel page management. */
Packit Service 82fcde
  new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
Packit Service 82fcde
  delta = offset - new_offset;
Packit Service 82fcde
  if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
Packit Service 82fcde
    {
Packit Service 82fcde
      new_offset = offset;
Packit Service 82fcde
      delta = 0;
Packit Service 82fcde
    }
Packit Service 82fcde
  result = _IO_SYSSEEK (fp, new_offset, 0);
Packit Service 82fcde
  if (result < 0)
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
  if (delta == 0)
Packit Service 82fcde
    count = 0;
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      count = _IO_SYSREAD (fp, fp->_IO_buf_base,
Packit Service 82fcde
			   (must_be_exact
Packit Service 82fcde
			    ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
Packit Service 82fcde
      if (count < delta)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* We weren't allowed to read, but try to seek the remainder. */
Packit Service 82fcde
	  offset = count == EOF ? delta : delta-count;
Packit Service 82fcde
	  dir = _IO_seek_cur;
Packit Service 82fcde
	  goto dumb;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
Packit Service 82fcde
	    fp->_IO_buf_base + count);
Packit Service 82fcde
  _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
  fp->_old_offset = result + count;
Packit Service 82fcde
  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
  return offset;
Packit Service 82fcde
 dumb:
Packit Service 82fcde
Packit Service 82fcde
  _IO_unsave_markers (fp);
Packit Service 82fcde
  result = _IO_SYSSEEK (fp, offset, dir);
Packit Service 82fcde
  if (result != EOF)
Packit Service 82fcde
    {
Packit Service 82fcde
      _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
      fp->_old_offset = result;
Packit Service 82fcde
      _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
      _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
Packit Service 82fcde
    }
Packit Service 82fcde
  return result;
Packit Service 82fcde
Packit Service 82fcde
resync:
Packit Service 82fcde
  /* We need to do it since it is possible that the file offset in
Packit Service 82fcde
     the kernel may be changed behind our back. It may happen when
Packit Service 82fcde
     we fopen a file and then do a fork. One process may access the
Packit Service 82fcde
     file and the kernel file offset will be changed. */
Packit Service 82fcde
  if (fp->_old_offset >= 0)
Packit Service 82fcde
    _IO_SYSSEEK (fp, fp->_old_offset, 0);
Packit Service 82fcde
Packit Service 82fcde
  return offset;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
ssize_t
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_write (FILE *f, const void *data, ssize_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  ssize_t to_do = n;
Packit Service 82fcde
  while (to_do > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      ssize_t count = __write (f->_fileno, data, to_do);
Packit Service 82fcde
      if (count == EOF)
Packit Service 82fcde
	{
Packit Service 82fcde
	  f->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
      to_do -= count;
Packit Service 82fcde
      data = (void *) ((char *) data + count);
Packit Service 82fcde
    }
Packit Service 82fcde
  n -= to_do;
Packit Service 82fcde
  if (f->_old_offset >= 0)
Packit Service 82fcde
    f->_old_offset += n;
Packit Service 82fcde
  return n;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
size_t
Packit Service 82fcde
attribute_compat_text_section
Packit Service 82fcde
_IO_old_file_xsputn (FILE *f, const void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  const char *s = (char *) data;
Packit Service 82fcde
  size_t to_do = n;
Packit Service 82fcde
  int must_flush = 0;
Packit Service 82fcde
  size_t count = 0;
Packit Service 82fcde
Packit Service 82fcde
  if (n <= 0)
Packit Service 82fcde
    return 0;
Packit Service 82fcde
  /* This is an optimized implementation.
Packit Service 82fcde
     If the amount to be written straddles a block boundary
Packit Service 82fcde
     (or the filebuf is unbuffered), use sys_write directly. */
Packit Service 82fcde
Packit Service 82fcde
  /* First figure out how much space is available in the buffer. */
Packit Service 82fcde
  if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
Packit Service 82fcde
    {
Packit Service 82fcde
      count = f->_IO_buf_end - f->_IO_write_ptr;
Packit Service 82fcde
      if (count >= n)
Packit Service 82fcde
	{
Packit Service 82fcde
	  const char *p;
Packit Service 82fcde
	  for (p = s + n; p > s; )
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (*--p == '\n')
Packit Service 82fcde
		{
Packit Service 82fcde
		  count = p - s + 1;
Packit Service 82fcde
		  must_flush = 1;
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (f->_IO_write_end > f->_IO_write_ptr)
Packit Service 82fcde
    count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
Packit Service 82fcde
Packit Service 82fcde
  /* Then fill the buffer. */
Packit Service 82fcde
  if (count > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (count > to_do)
Packit Service 82fcde
	count = to_do;
Packit Service 82fcde
      if (count > 20)
Packit Service 82fcde
	{
Packit Service 82fcde
	  f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
Packit Service 82fcde
	  s += count;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  char *p = f->_IO_write_ptr;
Packit Service 82fcde
	  int i = (int) count;
Packit Service 82fcde
	  while (--i >= 0)
Packit Service 82fcde
	    *p++ = *s++;
Packit Service 82fcde
	  f->_IO_write_ptr = p;
Packit Service 82fcde
	}
Packit Service 82fcde
      to_do -= count;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (to_do + must_flush > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t block_size, do_write;
Packit Service 82fcde
      /* Next flush the (full) buffer. */
Packit Service 82fcde
      if (__overflow (f, EOF) == EOF)
Packit Service 82fcde
	return to_do == 0 ? EOF : n - to_do;
Packit Service 82fcde
Packit Service 82fcde
      /* Try to maintain alignment: write a whole number of blocks.
Packit Service 82fcde
	 dont_write is what gets left over. */
Packit Service 82fcde
      block_size = f->_IO_buf_end - f->_IO_buf_base;
Packit Service 82fcde
      do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
Packit Service 82fcde
Packit Service 82fcde
      if (do_write)
Packit Service 82fcde
	{
Packit Service 82fcde
	  count = old_do_write (f, s, do_write);
Packit Service 82fcde
	  to_do -= count;
Packit Service 82fcde
	  if (count < do_write)
Packit Service 82fcde
	    return n - to_do;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Now write out the remainder.  Normally, this will fit in the
Packit Service 82fcde
	 buffer, but it's somewhat messier for line-buffered files,
Packit Service 82fcde
	 so we let _IO_default_xsputn handle the general case. */
Packit Service 82fcde
      if (to_do)
Packit Service 82fcde
	to_do -= _IO_default_xsputn (f, s+do_write, to_do);
Packit Service 82fcde
    }
Packit Service 82fcde
  return n - to_do;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_old_file_jumps libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_old_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, _IO_old_file_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, _IO_old_file_underflow),
Packit Service 82fcde
  JUMP_INIT(uflow, _IO_default_uflow),
Packit Service 82fcde
  JUMP_INIT(pbackfail, _IO_default_pbackfail),
Packit Service 82fcde
  JUMP_INIT(xsputn, _IO_old_file_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_default_xsgetn),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_old_file_seekoff),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, _IO_old_file_setbuf),
Packit Service 82fcde
  JUMP_INIT(sync, _IO_old_file_sync),
Packit Service 82fcde
  JUMP_INIT(doallocate, _IO_file_doallocate),
Packit Service 82fcde
  JUMP_INIT(read, _IO_file_read),
Packit Service 82fcde
  JUMP_INIT(write, _IO_old_file_write),
Packit Service 82fcde
  JUMP_INIT(seek, _IO_file_seek),
Packit Service 82fcde
  JUMP_INIT(close, _IO_file_close),
Packit Service 82fcde
  JUMP_INIT(stat, _IO_file_stat)
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
compat_symbol (libc, _IO_old_do_write, _IO_do_write, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_attach, _IO_file_attach, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_close_it, _IO_file_close_it, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_finish, _IO_file_finish, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_fopen, _IO_file_fopen, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_init, _IO_file_init, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_setbuf, _IO_file_setbuf, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_sync, _IO_file_sync, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_overflow, _IO_file_overflow, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_seekoff, _IO_file_seekoff, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_underflow, _IO_file_underflow, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_write, _IO_file_write, GLIBC_2_0);
Packit Service 82fcde
compat_symbol (libc, _IO_old_file_xsputn, _IO_file_xsputn, GLIBC_2_0);
Packit Service 82fcde
Packit Service 82fcde
#endif