Blame libio/fileops.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
Packit Service 82fcde
#include "libioP.h"
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
#include <sys/mman.h>
Packit Service 82fcde
#include <sys/param.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 <unistd.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include "../wcsmbs/wcsmbsload.h"
Packit Service 82fcde
#include "../iconv/gconv_charset.h"
Packit Service 82fcde
#include "../iconv/gconv_int.h"
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
#include <not-cancel.h>
Packit Service 82fcde
#include <kernel-features.h>
Packit Service 82fcde
Packit Service 82fcde
extern struct __gconv_trans_data __libio_translit attribute_hidden;
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 and also when the file is in append mode,
Packit Service 82fcde
   since switching from read to write mode automatically sends the position in
Packit Service 82fcde
   the external file system to the end of file.
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
_IO_new_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._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._fileno = -1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* External version of _IO_new_file_init_internal which switches off
Packit Service 82fcde
   vtable validation.  */
Packit Service 82fcde
void
Packit Service 82fcde
_IO_new_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_new_file_init_internal (fp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_new_file_close_it (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  int write_status;
Packit Service 82fcde
  if (!_IO_file_is_open (fp))
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
Packit Service 82fcde
  if ((fp->_flags & _IO_NO_WRITES) == 0
Packit Service 82fcde
      && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
Packit Service 82fcde
    write_status = _IO_do_flush (fp);
Packit Service 82fcde
  else
Packit Service 82fcde
    write_status = 0;
Packit Service 82fcde
Packit Service 82fcde
  _IO_unsave_markers (fp);
Packit Service 82fcde
Packit Service 82fcde
  int 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
  if (fp->_mode > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (_IO_have_wbackup (fp))
Packit Service 82fcde
	_IO_free_wbackup_area (fp);
Packit Service 82fcde
      _IO_wsetb (fp, NULL, NULL, 0);
Packit Service 82fcde
      _IO_wsetg (fp, NULL, NULL, NULL);
Packit Service 82fcde
      _IO_wsetp (fp, NULL, NULL);
Packit Service 82fcde
    }
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->_offset = _IO_pos_BAD;
Packit Service 82fcde
Packit Service 82fcde
  return close_status ? close_status : write_status;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it)
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
_IO_new_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_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
libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
_IO_file_open (FILE *fp, const char *filename, int posix_mode, int prot,
Packit Service 82fcde
	       int read_write, int is32not64)
Packit Service 82fcde
{
Packit Service 82fcde
  int fdesc;
Packit Service 82fcde
  if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
Packit Service 82fcde
    fdesc = __open_nocancel (filename,
Packit Service 82fcde
			     posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
Packit Service 82fcde
  else
Packit Service 82fcde
    fdesc = __open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
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
  /* For append mode, send the file offset to the end of the file.  Don't
Packit Service 82fcde
     update the offset cache though, since the file handle is not active.  */
Packit Service 82fcde
  if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS))
Packit Service 82fcde
      == (_IO_IS_APPENDING | _IO_NO_READS))
Packit Service 82fcde
    {
Packit Service 82fcde
      off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end);
Packit Service 82fcde
      if (new_pos == _IO_pos_BAD && errno != ESPIPE)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __close_nocancel (fdesc);
Packit Service 82fcde
	  return NULL;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  _IO_link_in ((struct _IO_FILE_plus *) fp);
Packit Service 82fcde
  return fp;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_open)
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
_IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
Packit Service 82fcde
		    int is32not64)
Packit Service 82fcde
{
Packit Service 82fcde
  int oflags = 0, omode;
Packit Service 82fcde
  int read_write;
Packit Service 82fcde
  int oprot = 0666;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  FILE *result;
Packit Service 82fcde
  const char *cs;
Packit Service 82fcde
  const char *last_recognized;
Packit Service 82fcde
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
  last_recognized = mode;
Packit Service 82fcde
  for (i = 1; i < 7; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      switch (*++mode)
Packit Service 82fcde
	{
Packit Service 82fcde
	case '\0':
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case '+':
Packit Service 82fcde
	  omode = O_RDWR;
Packit Service 82fcde
	  read_write &= _IO_IS_APPENDING;
Packit Service 82fcde
	  last_recognized = mode;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	case 'x':
Packit Service 82fcde
	  oflags |= O_EXCL;
Packit Service 82fcde
	  last_recognized = mode;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	case 'b':
Packit Service 82fcde
	  last_recognized = mode;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	case 'm':
Packit Service 82fcde
	  fp->_flags2 |= _IO_FLAGS2_MMAP;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	case 'c':
Packit Service 82fcde
	  fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	case 'e':
Packit Service 82fcde
	  oflags |= O_CLOEXEC;
Packit Service 82fcde
	  fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	default:
Packit Service 82fcde
	  /* Ignore.  */
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
Packit Service 82fcde
			  is32not64);
Packit Service 82fcde
Packit Service 82fcde
  if (result != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Test whether the mode string specifies the conversion.  */
Packit Service 82fcde
      cs = strstr (last_recognized + 1, ",ccs=");
Packit Service 82fcde
      if (cs != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Yep.  Load the appropriate conversions and set the orientation
Packit Service 82fcde
	     to wide.  */
Packit Service 82fcde
	  struct gconv_fcts fcts;
Packit Service 82fcde
	  struct _IO_codecvt *cc;
Packit Service 82fcde
	  char *endp = __strchrnul (cs + 5, ',');
Packit Service 82fcde
	  char *ccs = malloc (endp - (cs + 5) + 3);
Packit Service 82fcde
Packit Service 82fcde
	  if (ccs == NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      int malloc_err = errno;  /* Whatever malloc failed with.  */
Packit Service 82fcde
	      (void) _IO_file_close_it (fp);
Packit Service 82fcde
	      __set_errno (malloc_err);
Packit Service 82fcde
	      return NULL;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
Packit Service 82fcde
	  strip (ccs, ccs);
Packit Service 82fcde
Packit Service 82fcde
	  if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
Packit Service 82fcde
				   ? upstr (ccs, cs + 5) : ccs) != 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Something went wrong, we cannot load the conversion modules.
Packit Service 82fcde
		 This means we cannot proceed since the user explicitly asked
Packit Service 82fcde
		 for these.  */
Packit Service 82fcde
	      (void) _IO_file_close_it (fp);
Packit Service 82fcde
	      free (ccs);
Packit Service 82fcde
	      __set_errno (EINVAL);
Packit Service 82fcde
	      return NULL;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  free (ccs);
Packit Service 82fcde
Packit Service 82fcde
	  assert (fcts.towc_nsteps == 1);
Packit Service 82fcde
	  assert (fcts.tomb_nsteps == 1);
Packit Service 82fcde
Packit Service 82fcde
	  fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
Packit Service 82fcde
	  fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
Packit Service 82fcde
Packit Service 82fcde
	  /* Clear the state.  We start all over again.  */
Packit Service 82fcde
	  memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
Packit Service 82fcde
	  memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
Packit Service 82fcde
Packit Service 82fcde
	  cc = fp->_codecvt = &fp->_wide_data->_codecvt;
Packit Service 82fcde
Packit Service 1c5418
	  /* The functions are always the same.  */
Packit Service 1c5418
	  *cc = __libio_codecvt;
Packit Service 1c5418
Packit Service 82fcde
	  cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
Packit Service 82fcde
	  cc->__cd_in.__cd.__steps = fcts.towc;
Packit Service 82fcde
Packit Service 82fcde
	  cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
Packit Service 82fcde
	  cc->__cd_in.__cd.__data[0].__internal_use = 1;
Packit Service 82fcde
	  cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
Packit Service 82fcde
	  cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
Packit Service 82fcde
Packit Service 82fcde
	  cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
Packit Service 82fcde
	  cc->__cd_out.__cd.__steps = fcts.tomb;
Packit Service 82fcde
Packit Service 82fcde
	  cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
Packit Service 82fcde
	  cc->__cd_out.__cd.__data[0].__internal_use = 1;
Packit Service 82fcde
	  cc->__cd_out.__cd.__data[0].__flags
Packit Service 82fcde
	    = __GCONV_IS_LAST | __GCONV_TRANSLIT;
Packit Service 82fcde
	  cc->__cd_out.__cd.__data[0].__statep =
Packit Service 82fcde
	    &result->_wide_data->_IO_state;
Packit Service 82fcde
Packit Service 82fcde
	  /* From now on use the wide character callback functions.  */
Packit Service 82fcde
	  _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
Packit Service 82fcde
Packit Service 82fcde
	  /* Set the mode now.  */
Packit Service 82fcde
	  result->_mode = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
_IO_new_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->_offset = _IO_pos_BAD;
Packit Service 82fcde
  int save_errno = errno;
Packit Service 82fcde
  if (_IO_SEEKOFF (fp, (off64_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
  __set_errno (save_errno);
Packit Service 82fcde
  return fp;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
_IO_new_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
libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
FILE *
Packit Service 82fcde
_IO_file_setbuf_mmap (FILE *fp, char *p, ssize_t len)
Packit Service 82fcde
{
Packit Service 82fcde
  FILE *result;
Packit Service 82fcde
Packit Service 82fcde
  /* Change the function table.  */
Packit Service 82fcde
  _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
Packit Service 82fcde
  fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
Packit Service 82fcde
Packit Service 82fcde
  /* And perform the normal operation.  */
Packit Service 82fcde
  result = _IO_new_file_setbuf (fp, p, len);
Packit Service 82fcde
Packit Service 82fcde
  /* If the call failed, restore to using mmap.  */
Packit Service 82fcde
  if (result == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
Packit Service 82fcde
      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static size_t new_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
_IO_new_do_write (FILE *fp, const char *data, size_t to_do)
Packit Service 82fcde
{
Packit Service 82fcde
  return (to_do == 0
Packit Service 82fcde
	  || (size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_do_write, _IO_do_write)
Packit Service 82fcde
Packit Service 82fcde
static size_t
Packit Service 82fcde
new_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->_offset = _IO_pos_BAD;
Packit Service 82fcde
  else if (fp->_IO_read_end != fp->_IO_write_base)
Packit Service 82fcde
    {
Packit Service 82fcde
      off64_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->_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->_mode <= 0
Packit Service 82fcde
		       && (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
_IO_new_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
  /* FIXME This can/should be moved to genops ?? */
Packit Service 82fcde
  if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We used to flush all line-buffered stream.  This really isn't
Packit Service 82fcde
	 required by any standard.  My recollection is that
Packit Service 82fcde
	 traditional Unix systems did this for stdout.  stderr better
Packit Service 82fcde
	 not be line buffered.  So we do just that here
Packit Service 82fcde
	 explicitly.  --drepper */
Packit Service 82fcde
      _IO_acquire_lock (_IO_stdout);
Packit Service 82fcde
Packit Service 82fcde
      if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
Packit Service 82fcde
	  == (_IO_LINKED | _IO_LINE_BUF))
Packit Service 82fcde
	_IO_OVERFLOW (_IO_stdout, EOF);
Packit Service 82fcde
Packit Service 82fcde
      _IO_release_lock (_IO_stdout);
Packit Service 82fcde
    }
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
    {
Packit Service 82fcde
      /* If a stream is read to EOF, the calling application may switch active
Packit Service 82fcde
	 handles.  As a result, our offset cache would no longer be valid, so
Packit Service 82fcde
	 unset it.  */
Packit Service 82fcde
      fp->_offset = _IO_pos_BAD;
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fp->_offset != _IO_pos_BAD)
Packit Service 82fcde
    _IO_pos_adjust (fp->_offset, count);
Packit Service 82fcde
  return *(unsigned char *) fp->_IO_read_ptr;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
Packit Service 82fcde
Packit Service 82fcde
/* Guts of underflow callback if we mmap the file.  This stats the file and
Packit Service 82fcde
   updates the stream state to match.  In the normal case we return zero.
Packit Service 82fcde
   If the file is no longer eligible for mmap, its jump tables are reset to
Packit Service 82fcde
   the vanilla ones and we return nonzero.  */
Packit Service 82fcde
static int
Packit Service 82fcde
mmap_remap_check (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  struct stat64 st;
Packit Service 82fcde
Packit Service 82fcde
  if (_IO_SYSSTAT (fp, &st) == 0
Packit Service 82fcde
      && S_ISREG (st.st_mode) && st.st_size != 0
Packit Service 82fcde
      /* Limit the file size to 1MB for 32-bit machines.  */
Packit Service 82fcde
      && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024))
Packit Service 82fcde
    {
Packit Service 82fcde
      const size_t pagesize = __getpagesize ();
Packit Service 82fcde
# define ROUNDED(x)	(((x) + pagesize - 1) & ~(pagesize - 1))
Packit Service 82fcde
      if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end
Packit Service 82fcde
					  - fp->_IO_buf_base))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* We can trim off some pages past the end of the file.  */
Packit Service 82fcde
	  (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size),
Packit Service 82fcde
			   ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base)
Packit Service 82fcde
			   - ROUNDED (st.st_size));
Packit Service 82fcde
	  fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
Packit Service 82fcde
					       - fp->_IO_buf_base))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* The file added some pages.  We need to remap it.  */
Packit Service 82fcde
	  void *p;
Packit Service 82fcde
#if _G_HAVE_MREMAP
Packit Service 82fcde
	  p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
Packit Service 82fcde
						   - fp->_IO_buf_base),
Packit Service 82fcde
			ROUNDED (st.st_size), MREMAP_MAYMOVE);
Packit Service 82fcde
	  if (p == MAP_FAILED)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      (void) __munmap (fp->_IO_buf_base,
Packit Service 82fcde
			       fp->_IO_buf_end - fp->_IO_buf_base);
Packit Service 82fcde
	      goto punt;
Packit Service 82fcde
	    }
Packit Service 82fcde
#else
Packit Service 82fcde
	  (void) __munmap (fp->_IO_buf_base,
Packit Service 82fcde
			   fp->_IO_buf_end - fp->_IO_buf_base);
Packit Service 82fcde
	  p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
Packit Service 82fcde
			fp->_fileno, 0);
Packit Service 82fcde
	  if (p == MAP_FAILED)
Packit Service 82fcde
	    goto punt;
Packit Service 82fcde
#endif
Packit Service 82fcde
	  fp->_IO_buf_base = p;
Packit Service 82fcde
	  fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* The number of pages didn't change.  */
Packit Service 82fcde
	  fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
Packit Service 82fcde
	}
Packit Service 82fcde
# undef ROUNDED
Packit Service 82fcde
Packit Service 82fcde
      fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
      _IO_setg (fp, fp->_IO_buf_base,
Packit Service 82fcde
		fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
Packit Service 82fcde
		? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
Packit Service 82fcde
		fp->_IO_buf_end);
Packit Service 82fcde
Packit Service 82fcde
      /* If we are already positioned at or past the end of the file, don't
Packit Service 82fcde
	 change the current offset.  If not, seek past what we have mapped,
Packit Service 82fcde
	 mimicking the position left by a normal underflow reading into its
Packit Service 82fcde
	 buffer until EOF.  */
Packit Service 82fcde
Packit Service 82fcde
      if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (__lseek64 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base,
Packit Service 82fcde
			 SEEK_SET)
Packit Service 82fcde
	      != fp->_IO_buf_end - fp->_IO_buf_base)
Packit Service 82fcde
	    fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      return 0;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Life is no longer good for mmap.  Punt it.  */
Packit Service 82fcde
      (void) __munmap (fp->_IO_buf_base,
Packit Service 82fcde
		       fp->_IO_buf_end - fp->_IO_buf_base);
Packit Service 82fcde
    punt:
Packit Service 82fcde
      fp->_IO_buf_base = fp->_IO_buf_end = NULL;
Packit Service 82fcde
      _IO_setg (fp, NULL, NULL, NULL);
Packit Service 82fcde
      if (fp->_mode <= 0)
Packit Service 82fcde
	_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
Packit Service 82fcde
      else
Packit Service 82fcde
	_IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
Packit Service 82fcde
      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
Packit Service 82fcde
Packit Service 82fcde
      return 1;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Special callback replacing the underflow callbacks if we mmap the file.  */
Packit Service 82fcde
int
Packit Service 82fcde
_IO_file_underflow_mmap (FILE *fp)
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 (__glibc_unlikely (mmap_remap_check (fp)))
Packit Service 82fcde
    /* We punted to the regular file functions.  */
Packit Service 82fcde
    return _IO_UNDERFLOW (fp);
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
  fp->_flags |= _IO_EOF_SEEN;
Packit Service 82fcde
  return EOF;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
decide_maybe_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* We use the file in read-only mode.  This could mean we can
Packit Service 82fcde
     mmap the file and use it without any copying.  But not all
Packit Service 82fcde
     file descriptors are for mmap-able objects and on 32-bit
Packit Service 82fcde
     machines we don't want to map files which are too large since
Packit Service 82fcde
     this would require too much virtual memory.  */
Packit Service 82fcde
  struct stat64 st;
Packit Service 82fcde
Packit Service 82fcde
  if (_IO_SYSSTAT (fp, &st) == 0
Packit Service 82fcde
      && S_ISREG (st.st_mode) && st.st_size != 0
Packit Service 82fcde
      /* Limit the file size to 1MB for 32-bit machines.  */
Packit Service 82fcde
      && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)
Packit Service 82fcde
      /* Sanity check.  */
Packit Service 82fcde
      && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Try to map the file.  */
Packit Service 82fcde
      void *p;
Packit Service 82fcde
Packit Service 82fcde
      p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
Packit Service 82fcde
      if (p != MAP_FAILED)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* OK, we managed to map the file.  Set the buffer up and use a
Packit Service 82fcde
	     special jump table with simplified underflow functions which
Packit Service 82fcde
	     never tries to read anything from the file.  */
Packit Service 82fcde
Packit Service 82fcde
	  if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      (void) __munmap (p, st.st_size);
Packit Service 82fcde
	      fp->_offset = _IO_pos_BAD;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      _IO_setb (fp, p, (char *) p + st.st_size, 0);
Packit Service 82fcde
Packit Service 82fcde
	      if (fp->_offset == _IO_pos_BAD)
Packit Service 82fcde
		fp->_offset = 0;
Packit Service 82fcde
Packit Service 82fcde
	      _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
Packit Service 82fcde
	      fp->_offset = st.st_size;
Packit Service 82fcde
Packit Service 82fcde
	      if (fp->_mode <= 0)
Packit Service 82fcde
		_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
Packit Service 82fcde
	      else
Packit Service 82fcde
		_IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap;
Packit Service 82fcde
	      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
Packit Service 82fcde
Packit Service 82fcde
	      return;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* We couldn't use mmap, so revert to the vanilla file operations.  */
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_mode <= 0)
Packit Service 82fcde
    _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
Packit Service 82fcde
  else
Packit Service 82fcde
    _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
Packit Service 82fcde
  fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_file_underflow_maybe_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* This is the first read attempt.  Choose mmap or vanilla operations
Packit Service 82fcde
     and then punt to the chosen underflow routine.  */
Packit Service 82fcde
  decide_maybe_mmap (fp);
Packit Service 82fcde
  return _IO_UNDERFLOW (fp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_new_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 || f->_IO_write_base == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Allocate a buffer if needed. */
Packit Service 82fcde
      if (f->_IO_write_base == NULL)
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 (__glibc_unlikely (_IO_in_backup (f)))
Packit Service 82fcde
	{
Packit Service 82fcde
	  size_t nbackup = f->_IO_read_end - f->_IO_read_ptr;
Packit Service 82fcde
	  _IO_free_backup_area (f);
Packit Service 82fcde
	  f->_IO_read_base -= MIN (nbackup,
Packit Service 82fcde
				   f->_IO_read_base - f->_IO_buf_base);
Packit Service 82fcde
	  f->_IO_read_ptr = f->_IO_read_base;
Packit Service 82fcde
	}
Packit Service 82fcde
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
      f->_flags |= _IO_CURRENTLY_PUTTING;
Packit Service 82fcde
      if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED))
Packit Service 82fcde
	f->_IO_write_end = f->_IO_write_ptr;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (ch == EOF)
Packit Service 82fcde
    return _IO_do_write (f, f->_IO_write_base,
Packit Service 82fcde
			 f->_IO_write_ptr - f->_IO_write_base);
Packit Service 82fcde
  if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
Packit Service 82fcde
    if (_IO_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_do_write (f, f->_IO_write_base,
Packit Service 82fcde
		      f->_IO_write_ptr - f->_IO_write_base) == EOF)
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
  return (unsigned char) ch;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_new_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_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
      off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
Packit Service 82fcde
      if (new_pos != (off64_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->_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
libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
_IO_file_sync_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  if (fp->_IO_read_ptr != fp->_IO_read_end)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base,
Packit Service 82fcde
		     SEEK_SET)
Packit Service 82fcde
	  != fp->_IO_read_ptr - fp->_IO_buf_base)
Packit Service 82fcde
	{
Packit Service 82fcde
	  fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  return EOF;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
Packit Service 82fcde
  fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* ftell{,o} implementation.  The only time we modify the state of the stream
Packit Service 82fcde
   is when we have unflushed writes.  In that case we seek to the end and
Packit Service 82fcde
   record that offset in the stream object.  */
Packit Service 82fcde
static off64_t
Packit Service 82fcde
do_ftell (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  off64_t result, offset = 0;
Packit Service 82fcde
Packit Service 82fcde
  /* No point looking at unflushed data if we haven't allocated buffers
Packit Service 82fcde
     yet.  */
Packit Service 82fcde
  if (fp->_IO_buf_base != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      bool unflushed_writes = fp->_IO_write_ptr > fp->_IO_write_base;
Packit Service 82fcde
Packit Service 82fcde
      bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
Packit Service 82fcde
Packit Service 82fcde
      /* When we have unflushed writes in append mode, seek to the end of the
Packit Service 82fcde
	 file and record that offset.  This is the only time we change the file
Packit Service 82fcde
	 stream state and it is safe since the file handle is active.  */
Packit Service 82fcde
      if (unflushed_writes && append_mode)
Packit Service 82fcde
	{
Packit Service 82fcde
	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
Packit Service 82fcde
	  if (result == _IO_pos_BAD)
Packit Service 82fcde
	    return EOF;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    fp->_offset = result;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Adjust for unflushed data.  */
Packit Service 82fcde
      if (!unflushed_writes)
Packit Service 82fcde
	offset -= fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
      /* We don't trust _IO_read_end to represent the current file offset when
Packit Service 82fcde
	 writing in append mode because the value would have to be shifted to
Packit Service 82fcde
	 the end of the file during a flush.  Use the write base instead, along
Packit Service 82fcde
	 with the new offset we got above when we did a seek to the end of the
Packit Service 82fcde
	 file.  */
Packit Service 82fcde
      else if (append_mode)
Packit Service 82fcde
	offset += fp->_IO_write_ptr - fp->_IO_write_base;
Packit Service 82fcde
      /* For all other modes, _IO_read_end represents the file offset.  */
Packit Service 82fcde
      else
Packit Service 82fcde
	offset += fp->_IO_write_ptr - fp->_IO_read_end;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_offset != _IO_pos_BAD)
Packit Service 82fcde
    result = fp->_offset;
Packit Service 82fcde
  else
Packit Service 82fcde
    result = _IO_SYSSEEK (fp, 0, _IO_seek_cur);
Packit Service 82fcde
Packit Service 82fcde
  if (result == EOF)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  result += offset;
Packit Service 82fcde
Packit Service 82fcde
  if (result < 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      __set_errno (EINVAL);
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
off64_t
Packit Service 82fcde
_IO_new_file_seekoff (FILE *fp, off64_t offset, int dir, int mode)
Packit Service 82fcde
{
Packit Service 82fcde
  off64_t result;
Packit Service 82fcde
  off64_t delta, new_offset;
Packit Service 82fcde
  long count;
Packit Service 82fcde
Packit Service 82fcde
  /* Short-circuit into a separate function.  We don't want to mix any
Packit Service 82fcde
     functionality and we don't want to touch anything inside the FILE
Packit Service 82fcde
     object. */
Packit Service 82fcde
  if (mode == 0)
Packit Service 82fcde
    return do_ftell (fp);
Packit Service 82fcde
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
  bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
Packit Service 82fcde
		      || _IO_in_put_mode (fp));
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
  if (was_writing && _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
Packit Service 82fcde
      if (fp->_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->_offset;
Packit Service 82fcde
      if (offset < 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (EINVAL);
Packit Service 82fcde
	  return EOF;
Packit Service 82fcde
	}
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
Packit Service 82fcde
  _IO_free_backup_area (fp);
Packit Service 82fcde
Packit Service 82fcde
  /* At this point, dir==_IO_seek_set. */
Packit Service 82fcde
Packit Service 82fcde
  /* If destination is within current buffer, optimize: */
Packit Service 82fcde
  if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
Packit Service 82fcde
      && !_IO_in_backup (fp))
Packit Service 82fcde
    {
Packit Service 82fcde
      off64_t start_offset = (fp->_offset
Packit Service 82fcde
                              - (fp->_IO_read_end - fp->_IO_buf_base));
Packit Service 82fcde
      if (offset >= start_offset && offset < fp->_offset)
Packit Service 82fcde
	{
Packit Service 82fcde
	  _IO_setg (fp, fp->_IO_buf_base,
Packit Service 82fcde
		    fp->_IO_buf_base + (offset - start_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
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->_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->_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->_offset >= 0)
Packit Service 82fcde
    _IO_SYSSEEK (fp, fp->_offset, 0);
Packit Service 82fcde
Packit Service 82fcde
  return offset;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
Packit Service 82fcde
Packit Service 82fcde
off64_t
Packit Service 82fcde
_IO_file_seekoff_mmap (FILE *fp, off64_t offset, int dir, int mode)
Packit Service 82fcde
{
Packit Service 82fcde
  off64_t result;
Packit Service 82fcde
Packit Service 82fcde
  /* If we are only interested in the current position, calculate it and
Packit Service 82fcde
     return right now.  This calculation does the right thing when we are
Packit Service 82fcde
     using a pushback buffer, but in the usual case has the same value as
Packit Service 82fcde
     (fp->_IO_read_ptr - fp->_IO_buf_base).  */
Packit Service 82fcde
  if (mode == 0)
Packit Service 82fcde
    return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
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_ptr - fp->_IO_read_base;
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
      offset += fp->_IO_buf_end - fp->_IO_buf_base;
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* At this point, dir==_IO_seek_set. */
Packit Service 82fcde
Packit Service 82fcde
  if (offset < 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* No negative offsets are valid.  */
Packit Service 82fcde
      __set_errno (EINVAL);
Packit Service 82fcde
      return EOF;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  result = _IO_SYSSEEK (fp, offset, 0);
Packit Service 82fcde
  if (result < 0)
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
Packit Service 82fcde
  if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
Packit Service 82fcde
    /* One can fseek arbitrarily past the end of the file
Packit Service 82fcde
       and it is meaningless until one attempts to read.
Packit Service 82fcde
       Leave the buffer pointers in EOF state until underflow.  */
Packit Service 82fcde
    _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
Packit Service 82fcde
  else
Packit Service 82fcde
    /* Adjust the read pointers to match the file position,
Packit Service 82fcde
       but so the next read attempt will call underflow.  */
Packit Service 82fcde
    _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
Packit Service 82fcde
	      fp->_IO_buf_base + offset);
Packit Service 82fcde
Packit Service 82fcde
  fp->_offset = result;
Packit Service 82fcde
Packit Service 82fcde
  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
Packit Service 82fcde
Packit Service 82fcde
  return offset;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static off64_t
Packit Service 82fcde
_IO_file_seekoff_maybe_mmap (FILE *fp, off64_t offset, int dir,
Packit Service 82fcde
			     int mode)
Packit Service 82fcde
{
Packit Service 82fcde
  /* We only get here when we haven't tried to read anything yet.
Packit Service 82fcde
     So there is nothing more useful for us to do here than just
Packit Service 82fcde
     the underlying lseek call.  */
Packit Service 82fcde
Packit Service 82fcde
  off64_t result = _IO_SYSSEEK (fp, offset, dir);
Packit Service 82fcde
  if (result < 0)
Packit Service 82fcde
    return EOF;
Packit Service 82fcde
Packit Service 82fcde
  fp->_offset = result;
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
ssize_t
Packit Service 82fcde
_IO_file_read (FILE *fp, void *buf, ssize_t size)
Packit Service 82fcde
{
Packit Service 82fcde
  return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
Packit Service 82fcde
	  ? __read_nocancel (fp->_fileno, buf, size)
Packit Service 82fcde
	  : __read (fp->_fileno, buf, size));
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_read)
Packit Service 82fcde
Packit Service 82fcde
off64_t
Packit Service 82fcde
_IO_file_seek (FILE *fp, off64_t offset, int dir)
Packit Service 82fcde
{
Packit Service 82fcde
  return __lseek64 (fp->_fileno, offset, dir);
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_seek)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_file_stat (FILE *fp, void *st)
Packit Service 82fcde
{
Packit Service 82fcde
  return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st);
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_stat)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_file_close_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* In addition to closing the file descriptor we have to unmap the file.  */
Packit Service 82fcde
  (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
Packit Service 82fcde
  fp->_IO_buf_base = fp->_IO_buf_end = NULL;
Packit Service 82fcde
  /* Cancelling close should be avoided if possible since it leaves an
Packit Service 82fcde
     unrecoverable state behind.  */
Packit Service 82fcde
  return __close_nocancel (fp->_fileno);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
_IO_file_close (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Cancelling close should be avoided if possible since it leaves an
Packit Service 82fcde
     unrecoverable state behind.  */
Packit Service 82fcde
  return __close_nocancel (fp->_fileno);
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_close)
Packit Service 82fcde
Packit Service 82fcde
ssize_t
Packit Service 82fcde
_IO_new_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 = (__builtin_expect (f->_flags2
Packit Service 82fcde
                                         & _IO_FLAGS2_NOTCANCEL, 0)
Packit Service 82fcde
			   ? __write_nocancel (f->_fileno, data, to_do)
Packit Service 82fcde
			   : __write (f->_fileno, data, to_do));
Packit Service 82fcde
      if (count < 0)
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->_offset >= 0)
Packit Service 82fcde
    f->_offset += n;
Packit Service 82fcde
  return n;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
size_t
Packit Service 82fcde
_IO_new_file_xsputn (FILE *f, const void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  const char *s = (const 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
      f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
Packit Service 82fcde
      s += count;
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 (_IO_OVERFLOW (f, EOF) == EOF)
Packit Service 82fcde
	/* If nothing else has to be written we must not signal the
Packit Service 82fcde
	   caller that everything has been written.  */
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
      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 = new_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
libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
Packit Service 82fcde
Packit Service 82fcde
size_t
Packit Service 82fcde
_IO_file_xsgetn (FILE *fp, void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  size_t want, have;
Packit Service 82fcde
  ssize_t count;
Packit Service 82fcde
  char *s = data;
Packit Service 82fcde
Packit Service 82fcde
  want = n;
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
  while (want > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      have = fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
      if (want <= have)
Packit Service 82fcde
	{
Packit Service 82fcde
	  memcpy (s, fp->_IO_read_ptr, want);
Packit Service 82fcde
	  fp->_IO_read_ptr += want;
Packit Service 82fcde
	  want = 0;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (have > 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      s = __mempcpy (s, fp->_IO_read_ptr, have);
Packit Service 82fcde
	      want -= have;
Packit Service 82fcde
	      fp->_IO_read_ptr += have;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Check for backup and repeat */
Packit Service 82fcde
	  if (_IO_in_backup (fp))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      _IO_switch_to_main_get_area (fp);
Packit Service 82fcde
	      continue;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* If we now want less than a buffer, underflow and repeat
Packit Service 82fcde
	     the copy.  Otherwise, _IO_SYSREAD directly to
Packit Service 82fcde
	     the user buffer. */
Packit Service 82fcde
	  if (fp->_IO_buf_base
Packit Service 82fcde
	      && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (__underflow (fp) == EOF)
Packit Service 82fcde
		break;
Packit Service 82fcde
Packit Service 82fcde
	      continue;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* These must be set before the sysread as we might longjmp out
Packit Service 82fcde
	     waiting for input. */
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
	  /* Try to maintain alignment: read a whole number of blocks.  */
Packit Service 82fcde
	  count = want;
Packit Service 82fcde
	  if (fp->_IO_buf_base)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
Packit Service 82fcde
	      if (block_size >= 128)
Packit Service 82fcde
		count -= want % block_size;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  count = _IO_SYSREAD (fp, s, count);
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;
Packit Service 82fcde
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  s += count;
Packit Service 82fcde
	  want -= count;
Packit Service 82fcde
	  if (fp->_offset != _IO_pos_BAD)
Packit Service 82fcde
	    _IO_pos_adjust (fp->_offset, count);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return n - want;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_file_xsgetn)
Packit Service 82fcde
Packit Service 82fcde
static size_t
Packit Service 82fcde
_IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  size_t have;
Packit Service 82fcde
  char *read_ptr = fp->_IO_read_ptr;
Packit Service 82fcde
  char *s = (char *) data;
Packit Service 82fcde
Packit Service 82fcde
  have = fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  if (have < n)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (__glibc_unlikely (_IO_in_backup (fp)))
Packit Service 82fcde
	{
Packit Service 82fcde
	  s = __mempcpy (s, read_ptr, have);
Packit Service 82fcde
	  n -= have;
Packit Service 82fcde
	  _IO_switch_to_main_get_area (fp);
Packit Service 82fcde
	  read_ptr = fp->_IO_read_ptr;
Packit Service 82fcde
	  have = fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (have < n)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Check that we are mapping all of the file, in case it grew.  */
Packit Service 82fcde
	  if (__glibc_unlikely (mmap_remap_check (fp)))
Packit Service 82fcde
	    /* We punted mmap, so complete with the vanilla code.  */
Packit Service 82fcde
	    return s - (char *) data + _IO_XSGETN (fp, data, n);
Packit Service 82fcde
Packit Service 82fcde
	  read_ptr = fp->_IO_read_ptr;
Packit Service 82fcde
	  have = fp->_IO_read_end - read_ptr;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (have < n)
Packit Service 82fcde
    fp->_flags |= _IO_EOF_SEEN;
Packit Service 82fcde
Packit Service 82fcde
  if (have != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      have = MIN (have, n);
Packit Service 82fcde
      s = __mempcpy (s, read_ptr, have);
Packit Service 82fcde
      fp->_IO_read_ptr = read_ptr + have;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return s - (char *) data;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static size_t
Packit Service 82fcde
_IO_file_xsgetn_maybe_mmap (FILE *fp, void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  /* We only get here if this is the first attempt to read something.
Packit Service 82fcde
     Decide which operations to use and then punt to the chosen one.  */
Packit Service 82fcde
Packit Service 82fcde
  decide_maybe_mmap (fp);
Packit Service 82fcde
  return _IO_XSGETN (fp, data, n);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
Packit Service 82fcde
versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_file_jumps libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, _IO_file_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, _IO_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_file_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_new_file_seekoff),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, _IO_new_file_setbuf),
Packit Service 82fcde
  JUMP_INIT(sync, _IO_new_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_new_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
  JUMP_INIT(showmanyc, _IO_default_showmanyc),
Packit Service 82fcde
  JUMP_INIT(imbue, _IO_default_imbue)
Packit Service 82fcde
};
Packit Service 82fcde
libc_hidden_data_def (_IO_file_jumps)
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, _IO_file_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, _IO_file_underflow_mmap),
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_new_file_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
Packit Service 82fcde
  JUMP_INIT(sync, _IO_file_sync_mmap),
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_new_file_write),
Packit Service 82fcde
  JUMP_INIT(seek, _IO_file_seek),
Packit Service 82fcde
  JUMP_INIT(close, _IO_file_close_mmap),
Packit Service 82fcde
  JUMP_INIT(stat, _IO_file_stat),
Packit Service 82fcde
  JUMP_INIT(showmanyc, _IO_default_showmanyc),
Packit Service 82fcde
  JUMP_INIT(imbue, _IO_default_imbue)
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, _IO_file_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
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_new_file_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
Packit Service 82fcde
  JUMP_INIT(sync, _IO_new_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_new_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
  JUMP_INIT(showmanyc, _IO_default_showmanyc),
Packit Service 82fcde
  JUMP_INIT(imbue, _IO_default_imbue)
Packit Service 82fcde
};