Blame libio/wfileops.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 Ulrich Drepper <drepper@cygnus.com>.
Packit Service 82fcde
   Based on the single byte version 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
#include <assert.h>
Packit Service 82fcde
#include <libioP.h>
Packit Service 82fcde
#include <wchar.h>
Packit Service 82fcde
#include <gconv.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
Packit Service 82fcde
/* Convert TO_DO wide character from DATA to FP.
Packit Service 82fcde
   Then mark FP as having empty buffers. */
Packit Service 82fcde
int
Packit Service 82fcde
_IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _IO_codecvt *cc = fp->_codecvt;
Packit Service 82fcde
Packit Service 82fcde
  if (to_do > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (fp->_IO_write_end == fp->_IO_write_ptr
Packit Service 82fcde
	  && fp->_IO_write_end != fp->_IO_write_base)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (_IO_new_do_write (fp, fp->_IO_write_base,
Packit Service 82fcde
				fp->_IO_write_ptr - fp->_IO_write_base) == EOF)
Packit Service 82fcde
	    return WEOF;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      do
Packit Service 82fcde
	{
Packit Service 82fcde
	  enum __codecvt_result result;
Packit Service 82fcde
	  const wchar_t *new_data;
Packit Service 82fcde
	  char mb_buf[MB_LEN_MAX];
Packit Service 82fcde
	  char *write_base, *write_ptr, *buf_end;
Packit Service 82fcde
Packit Service 82fcde
	  if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Make sure we have room for at least one multibyte
Packit Service 82fcde
		 character.  */
Packit Service 82fcde
	      write_ptr = write_base = mb_buf;
Packit Service 82fcde
	      buf_end = mb_buf + sizeof (mb_buf);
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      write_ptr = fp->_IO_write_ptr;
Packit Service 82fcde
	      write_base = fp->_IO_write_base;
Packit Service 82fcde
	      buf_end = fp->_IO_buf_end;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Now convert from the internal format into the external buffer.  */
Packit Service a3ed18
	  result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state,
Packit Service a3ed18
					data, data + to_do, &new_data,
Packit Service a3ed18
					write_ptr,
Packit Service a3ed18
					buf_end,
Packit Service a3ed18
					&write_ptr);
Packit Service 82fcde
Packit Service 82fcde
	  /* Write out what we produced so far.  */
Packit Service 82fcde
	  if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF)
Packit Service 82fcde
	    /* Something went wrong.  */
Packit Service 82fcde
	    return WEOF;
Packit Service 82fcde
Packit Service 82fcde
	  to_do -= new_data - data;
Packit Service 82fcde
Packit Service 82fcde
	  /* Next see whether we had problems during the conversion.  If yes,
Packit Service 82fcde
	     we cannot go on.  */
Packit Service 82fcde
	  if (result != __codecvt_ok
Packit Service 82fcde
	      && (result != __codecvt_partial || new_data - data == 0))
Packit Service 82fcde
	    break;
Packit Service 82fcde
Packit Service 82fcde
	  data = new_data;
Packit Service 82fcde
	}
Packit Service 82fcde
      while (to_do > 0);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
	     fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
  fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
Packit Service 82fcde
    = fp->_wide_data->_IO_buf_base;
Packit Service 82fcde
  fp->_wide_data->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED))
Packit Service 82fcde
				   ? fp->_wide_data->_IO_buf_base
Packit Service 82fcde
				   : fp->_wide_data->_IO_buf_end);
Packit Service 82fcde
Packit Service 82fcde
  return to_do == 0 ? 0 : WEOF;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_wdo_write)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
wint_t
Packit Service 82fcde
_IO_wfile_underflow (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _IO_codecvt *cd;
Packit Service 82fcde
  enum __codecvt_result status;
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 WEOF;
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (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 WEOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
Packit Service 82fcde
    return *fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  cd = fp->_codecvt;
Packit Service 82fcde
Packit Service 82fcde
  /* Maybe there is something left in the external buffer.  */
Packit Service 82fcde
  if (fp->_IO_read_ptr < fp->_IO_read_end)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* There is more in the external.  Convert it.  */
Packit Service 82fcde
      const char *read_stop = (const char *) fp->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
      fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
Packit Service 82fcde
      fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
Packit Service 82fcde
	fp->_wide_data->_IO_buf_base;
Packit Service a3ed18
      status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
Packit Service a3ed18
				   fp->_IO_read_ptr, fp->_IO_read_end,
Packit Service a3ed18
				   &read_stop,
Packit Service a3ed18
				   fp->_wide_data->_IO_read_ptr,
Packit Service a3ed18
				   fp->_wide_data->_IO_buf_end,
Packit Service a3ed18
				   &fp->_wide_data->_IO_read_end);
Packit Service 82fcde
Packit Service 82fcde
      fp->_IO_read_base = fp->_IO_read_ptr;
Packit Service 82fcde
      fp->_IO_read_ptr = (char *) read_stop;
Packit Service 82fcde
Packit Service 82fcde
      /* If we managed to generate some text return the next character.  */
Packit Service 82fcde
      if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
Packit Service 82fcde
	return *fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
      if (status == __codecvt_error)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (EILSEQ);
Packit Service 82fcde
	  fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  return WEOF;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Move the remaining content of the read buffer to the beginning.  */
Packit Service 82fcde
      memmove (fp->_IO_buf_base, fp->_IO_read_ptr,
Packit Service 82fcde
	       fp->_IO_read_end - fp->_IO_read_ptr);
Packit Service 82fcde
      fp->_IO_read_end = (fp->_IO_buf_base
Packit Service 82fcde
			  + (fp->_IO_read_end - fp->_IO_read_ptr));
Packit Service 82fcde
      fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end =
Packit Service 82fcde
      fp->_IO_buf_base;
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
      fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end =
Packit Service 82fcde
	fp->_IO_buf_base;
Packit Service 82fcde
    }
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
Packit Service 82fcde
  if (fp->_wide_data->_IO_buf_base == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Maybe we already have a push back pointer.  */
Packit Service 82fcde
      if (fp->_wide_data->_IO_save_base != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (fp->_wide_data->_IO_save_base);
Packit Service 82fcde
	  fp->_flags &= ~_IO_IN_BACKUP;
Packit Service 82fcde
	}
Packit Service 82fcde
      _IO_wdoallocbuf (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
  fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
Packit Service 82fcde
    fp->_wide_data->_IO_buf_base;
Packit Service 82fcde
  fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_buf_base;
Packit Service 82fcde
  fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr =
Packit Service 82fcde
    fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base;
Packit Service 82fcde
Packit Service 82fcde
  const char *read_ptr_copy;
Packit Service 82fcde
  char accbuf[MB_LEN_MAX];
Packit Service 82fcde
  size_t naccbuf = 0;
Packit Service 82fcde
 again:
Packit Service 82fcde
  count = _IO_SYSREAD (fp, fp->_IO_read_end,
Packit Service 82fcde
		       fp->_IO_buf_end - fp->_IO_read_end);
Packit Service 82fcde
  if (count <= 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (count == 0 && naccbuf == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  fp->_flags |= _IO_EOF_SEEN;
Packit Service 82fcde
	  fp->_offset = _IO_pos_BAD;
Packit Service 82fcde
	}
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 (naccbuf != 0)
Packit Service 82fcde
	/* There are some bytes in the external buffer but they don't
Packit Service 82fcde
	   convert to anything.  */
Packit Service 82fcde
	__set_errno (EILSEQ);
Packit Service 82fcde
      return WEOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fp->_offset != _IO_pos_BAD)
Packit Service 82fcde
    _IO_pos_adjust (fp->_offset, count);
Packit Service 82fcde
Packit Service 82fcde
  /* Now convert the read input.  */
Packit Service 82fcde
  fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
Packit Service 82fcde
  fp->_IO_read_base = fp->_IO_read_ptr;
Packit Service 82fcde
  const char *from = fp->_IO_read_ptr;
Packit Service 82fcde
  const char *to = fp->_IO_read_end;
Packit Service 82fcde
  size_t to_copy = count;
Packit Service 82fcde
  if (__glibc_unlikely (naccbuf != 0))
Packit Service 82fcde
    {
Packit Service 82fcde
      to_copy = MIN (sizeof (accbuf) - naccbuf, count);
Packit Service 82fcde
      to = __mempcpy (&accbuf[naccbuf], from, to_copy);
Packit Service 82fcde
      naccbuf += to_copy;
Packit Service 82fcde
      from = accbuf;
Packit Service 82fcde
    }
Packit Service a3ed18
  status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
Packit Service a3ed18
			       from, to, &read_ptr_copy,
Packit Service a3ed18
			       fp->_wide_data->_IO_read_end,
Packit Service a3ed18
			       fp->_wide_data->_IO_buf_end,
Packit Service a3ed18
			       &fp->_wide_data->_IO_read_end);
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (naccbuf != 0))
Packit Service 82fcde
    fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]);
Packit Service 82fcde
  else
Packit Service 82fcde
    fp->_IO_read_ptr = (char *) read_ptr_copy;
Packit Service 82fcde
  if (fp->_wide_data->_IO_read_end == fp->_wide_data->_IO_buf_base)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (status == __codecvt_error)
Packit Service 82fcde
	{
Packit Service 82fcde
	out_eilseq:
Packit Service 82fcde
	  __set_errno (EILSEQ);
Packit Service 82fcde
	  fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  return WEOF;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* The read bytes make no complete character.  Try reading again.  */
Packit Service 82fcde
      assert (status == __codecvt_partial);
Packit Service 82fcde
Packit Service 82fcde
      if (naccbuf == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (fp->_IO_read_base < fp->_IO_read_ptr)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Partially used the buffer for some input data that
Packit Service 82fcde
		 produces no output.  */
Packit Service 82fcde
	      size_t avail = fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
	      memmove (fp->_IO_read_base, fp->_IO_read_ptr, avail);
Packit Service 82fcde
	      fp->_IO_read_ptr = fp->_IO_read_base;
Packit Service 82fcde
	      fp->_IO_read_end -= avail;
Packit Service 82fcde
	      goto again;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  naccbuf = fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
	  if (naccbuf >= sizeof (accbuf))
Packit Service 82fcde
	    goto out_eilseq;
Packit Service 82fcde
Packit Service 82fcde
	  memcpy (accbuf, fp->_IO_read_ptr, naccbuf);
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  size_t used = read_ptr_copy - accbuf;
Packit Service 82fcde
	  if (used > 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      memmove (accbuf, read_ptr_copy, naccbuf - used);
Packit Service 82fcde
	      naccbuf -= used;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  if (naccbuf == sizeof (accbuf))
Packit Service 82fcde
	    goto out_eilseq;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      fp->_IO_read_ptr = fp->_IO_read_end = fp->_IO_read_base;
Packit Service 82fcde
Packit Service 82fcde
      goto again;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return *fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_wfile_underflow)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static wint_t
Packit Service 82fcde
_IO_wfile_underflow_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _IO_codecvt *cd;
Packit Service 82fcde
  const char *read_stop;
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (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 WEOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
Packit Service 82fcde
    return *fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  cd = fp->_codecvt;
Packit Service 82fcde
Packit Service 82fcde
  /* Maybe there is something left in the external buffer.  */
Packit Service 82fcde
  if (fp->_IO_read_ptr >= fp->_IO_read_end
Packit Service 82fcde
      /* No.  But maybe the read buffer is not fully set up.  */
Packit Service 82fcde
      && _IO_file_underflow_mmap (fp) == EOF)
Packit Service 82fcde
    /* Nothing available.  _IO_file_underflow_mmap has set the EOF or error
Packit Service 82fcde
       flags as appropriate.  */
Packit Service 82fcde
    return WEOF;
Packit Service 82fcde
Packit Service 82fcde
  /* There is more in the external.  Convert it.  */
Packit Service 82fcde
  read_stop = (const char *) fp->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_wide_data->_IO_buf_base == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Maybe we already have a push back pointer.  */
Packit Service 82fcde
      if (fp->_wide_data->_IO_save_base != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (fp->_wide_data->_IO_save_base);
Packit Service 82fcde
	  fp->_flags &= ~_IO_IN_BACKUP;
Packit Service 82fcde
	}
Packit Service 82fcde
      _IO_wdoallocbuf (fp);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
Packit Service 82fcde
  fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
Packit Service 82fcde
    fp->_wide_data->_IO_buf_base;
Packit Service a3ed18
  __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
Packit Service a3ed18
		      fp->_IO_read_ptr, fp->_IO_read_end,
Packit Service a3ed18
		      &read_stop,
Packit Service a3ed18
		      fp->_wide_data->_IO_read_ptr,
Packit Service a3ed18
		      fp->_wide_data->_IO_buf_end,
Packit Service a3ed18
		      &fp->_wide_data->_IO_read_end);
Packit Service 82fcde
Packit Service 82fcde
  fp->_IO_read_ptr = (char *) read_stop;
Packit Service 82fcde
Packit Service 82fcde
  /* If we managed to generate some text return the next character.  */
Packit Service 82fcde
  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
Packit Service 82fcde
    return *fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
Packit Service 82fcde
  /* There is some garbage at the end of the file.  */
Packit Service 82fcde
  __set_errno (EILSEQ);
Packit Service 82fcde
  fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
  return WEOF;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static wint_t
Packit Service 82fcde
_IO_wfile_underflow_maybe_mmap (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  /* This is the first read attempt.  Doing the underflow will choose mmap
Packit Service 82fcde
     or vanilla operations and then punt to the chosen underflow routine.
Packit Service 82fcde
     Then we can punt to ours.  */
Packit Service 82fcde
  if (_IO_file_underflow_maybe_mmap (fp) == EOF)
Packit Service 82fcde
    return WEOF;
Packit Service 82fcde
Packit Service 82fcde
  return _IO_WUNDERFLOW (fp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
wint_t
Packit Service 82fcde
_IO_wfile_overflow (FILE *f, wint_t wch)
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 WEOF;
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->_wide_data->_IO_write_base == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  _IO_wdoallocbuf (f);
Packit Service 82fcde
	  _IO_free_wbackup_area (f);
Packit Service 82fcde
	  _IO_wsetg (f, f->_wide_data->_IO_buf_base,
Packit Service 82fcde
		     f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base);
Packit Service 82fcde
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
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Otherwise must be currently reading.  If _IO_read_ptr
Packit Service 82fcde
	     (and hence also _IO_read_end) is at the buffer end,
Packit Service 82fcde
	     logically slide the buffer forwards one block (by setting
Packit Service 82fcde
	     the read pointers to all point at the beginning of the
Packit Service 82fcde
	     block).  This makes room for subsequent output.
Packit Service 82fcde
	     Otherwise, set the read pointers to _IO_read_end (leaving
Packit Service 82fcde
	     that alone, so it can continue to correspond to the
Packit Service 82fcde
	     external position). */
Packit Service 82fcde
	  if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
Packit Service 82fcde
	      f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr =
Packit Service 82fcde
		f->_wide_data->_IO_buf_base;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr;
Packit Service 82fcde
      f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr;
Packit Service 82fcde
      f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end;
Packit Service 82fcde
      f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr =
Packit Service 82fcde
	f->_wide_data->_IO_read_end;
Packit Service 82fcde
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->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED))
Packit Service 82fcde
	f->_wide_data->_IO_write_end = f->_wide_data->_IO_write_ptr;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (wch == WEOF)
Packit Service 82fcde
    return _IO_do_flush (f);
Packit Service 82fcde
  if (f->_wide_data->_IO_write_ptr == f->_wide_data->_IO_buf_end)
Packit Service 82fcde
    /* Buffer is really full */
Packit Service 82fcde
    if (_IO_do_flush (f) == EOF)
Packit Service 82fcde
      return WEOF;
Packit Service 82fcde
  *f->_wide_data->_IO_write_ptr++ = wch;
Packit Service 82fcde
  if ((f->_flags & _IO_UNBUFFERED)
Packit Service 82fcde
      || ((f->_flags & _IO_LINE_BUF) && wch == L'\n'))
Packit Service 82fcde
    if (_IO_do_flush (f) == EOF)
Packit Service 82fcde
      return WEOF;
Packit Service 82fcde
  return wch;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_wfile_overflow)
Packit Service 82fcde
Packit Service 82fcde
wint_t
Packit Service 82fcde
_IO_wfile_sync (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  ssize_t delta;
Packit Service 82fcde
  wint_t retval = 0;
Packit Service 82fcde
Packit Service 82fcde
  /*    char* ptr = cur_ptr(); */
Packit Service 82fcde
  if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
Packit Service 82fcde
    if (_IO_do_flush (fp))
Packit Service 82fcde
      return WEOF;
Packit Service 82fcde
  delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
Packit Service 82fcde
  if (delta != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We have to find out how many bytes we have to go back in the
Packit Service 82fcde
	 external buffer.  */
Packit Service 82fcde
      struct _IO_codecvt *cv = fp->_codecvt;
Packit Service 82fcde
      off64_t new_pos;
Packit Service 82fcde
Packit Service a3ed18
      int clen = __libio_codecvt_encoding (cv);
Packit Service 82fcde
Packit Service 82fcde
      if (clen > 0)
Packit Service 82fcde
	/* It is easy, a fixed number of input bytes are used for each
Packit Service 82fcde
	   wide character.  */
Packit Service 82fcde
	delta *= clen;
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* We have to find out the hard way how much to back off.
Packit Service 82fcde
	     To do this we determine how much input we needed to
Packit Service 82fcde
	     generate the wide characters up to the current reading
Packit Service 82fcde
	     position.  */
Packit Service 82fcde
	  int nread;
Packit Service 62d074
	  size_t wnread = (fp->_wide_data->_IO_read_ptr
Packit Service 62d074
			   - fp->_wide_data->_IO_read_base);
Packit Service 82fcde
	  fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
Packit Service a3ed18
	  nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state,
Packit Service a3ed18
					  fp->_IO_read_base,
Packit Service a3ed18
					  fp->_IO_read_end, wnread);
Packit Service 82fcde
	  fp->_IO_read_ptr = fp->_IO_read_base + nread;
Packit Service 82fcde
	  delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      new_pos = _IO_SYSSEEK (fp, delta, 1);
Packit Service 82fcde
      if (new_pos != (off64_t) EOF)
Packit Service 82fcde
	{
Packit Service 82fcde
	  fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
	  fp->_IO_read_end = fp->_IO_read_ptr;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (errno == ESPIPE)
Packit Service 82fcde
	; /* Ignore error from unseekable devices. */
Packit Service 82fcde
      else
Packit Service 82fcde
	retval = WEOF;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (retval != WEOF)
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_def (_IO_wfile_sync)
Packit Service 82fcde
Packit Service 82fcde
/* Adjust the internal buffer pointers to reflect the state in the external
Packit Service 82fcde
   buffer.  The content between fp->_IO_read_base and fp->_IO_read_ptr is
Packit Service 82fcde
   assumed to be converted and available in the range
Packit Service 82fcde
   fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end.
Packit Service 82fcde
Packit Service 82fcde
   Returns 0 on success and -1 on error with the _IO_ERR_SEEN flag set.  */
Packit Service 82fcde
static int
Packit Service 82fcde
adjust_wide_data (FILE *fp, bool do_convert)
Packit Service 82fcde
{
Packit Service 82fcde
  struct _IO_codecvt *cv = fp->_codecvt;
Packit Service 82fcde
Packit Service a3ed18
  int clen = __libio_codecvt_encoding (cv);
Packit Service 82fcde
Packit Service 82fcde
  /* Take the easy way out for constant length encodings if we don't need to
Packit Service 82fcde
     convert.  */
Packit Service 82fcde
  if (!do_convert && clen > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base)
Packit Service 82fcde
				       / clen);
Packit Service 82fcde
      goto done;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  enum __codecvt_result status;
Packit Service 82fcde
  const char *read_stop = (const char *) fp->_IO_read_base;
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
Packit Service 82fcde
      fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
Packit Service a3ed18
      status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state,
Packit Service a3ed18
				   fp->_IO_read_base, fp->_IO_read_ptr,
Packit Service a3ed18
				   &read_stop,
Packit Service a3ed18
				   fp->_wide_data->_IO_read_base,
Packit Service a3ed18
				   fp->_wide_data->_IO_buf_end,
Packit Service a3ed18
				   &fp->_wide_data->_IO_read_end);
Packit Service 82fcde
Packit Service 82fcde
      /* Should we return EILSEQ?  */
Packit Service 82fcde
      if (__glibc_unlikely (status == __codecvt_error))
Packit Service 82fcde
	{
Packit Service 82fcde
	  fp->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
	  return -1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  while (__builtin_expect (status == __codecvt_partial, 0));
Packit Service 82fcde
Packit Service 82fcde
done:
Packit Service 82fcde
  /* Now seek to _IO_read_end to behave as if we have read it all in.  */
Packit Service 82fcde
  fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* ftell{,o} implementation for wide mode.  Don't modify any state of the file
Packit Service 82fcde
   pointer while we try to get the current state of the stream except in one
Packit Service 82fcde
   case, which is when we have unflushed writes in append mode.  */
Packit Service 82fcde
static off64_t
Packit Service 82fcde
do_ftell_wide (FILE *fp)
Packit Service 82fcde
{
Packit Service 82fcde
  off64_t result, offset = 0;
Packit Service 82fcde
Packit Service 82fcde
  /* No point looking for offsets in the buffer if it hasn't even been
Packit Service 82fcde
     allocated.  */
Packit Service 82fcde
  if (fp->_wide_data->_IO_buf_base != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      const wchar_t *wide_read_base;
Packit Service 82fcde
      const wchar_t *wide_read_ptr;
Packit Service 82fcde
      const wchar_t *wide_read_end;
Packit Service 82fcde
      bool unflushed_writes = (fp->_wide_data->_IO_write_ptr
Packit Service 82fcde
			       > fp->_wide_data->_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
      /* XXX For wide stream with backup store it is not very
Packit Service 82fcde
	 reasonable to determine the offset.  The pushed-back
Packit Service 82fcde
	 character might require a state change and we need not be
Packit Service 82fcde
	 able to compute the initial state by reverse transformation
Packit Service 82fcde
	 since there is no guarantee of symmetry.  So we don't even
Packit Service 82fcde
	 try and return an error.  */
Packit Service 82fcde
      if (_IO_in_backup (fp))
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      __set_errno (EINVAL);
Packit Service 82fcde
	      return -1;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Nothing in the backup store, so note the backed up pointers
Packit Service 82fcde
	     without changing the state.  */
Packit Service 82fcde
	  wide_read_base = fp->_wide_data->_IO_save_base;
Packit Service 82fcde
	  wide_read_ptr = wide_read_base;
Packit Service 82fcde
	  wide_read_end = fp->_wide_data->_IO_save_end;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  wide_read_base = fp->_wide_data->_IO_read_base;
Packit Service 82fcde
	  wide_read_ptr = fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
	  wide_read_end = fp->_wide_data->_IO_read_end;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      struct _IO_codecvt *cv = fp->_codecvt;
Packit Service a3ed18
      int clen = __libio_codecvt_encoding (cv);
Packit Service 82fcde
Packit Service 82fcde
      if (!unflushed_writes)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (clen > 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      offset -= (wide_read_end - wide_read_ptr) * clen;
Packit Service 82fcde
	      offset -= fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      int nread;
Packit Service 82fcde
Packit Service 82fcde
	      size_t delta = wide_read_ptr - wide_read_base;
Packit Service 82fcde
	      __mbstate_t state = fp->_wide_data->_IO_last_state;
Packit Service a3ed18
	      nread = __libio_codecvt_length (cv, &state,
Packit Service a3ed18
					      fp->_IO_read_base,
Packit Service a3ed18
					      fp->_IO_read_end, delta);
Packit Service 82fcde
	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (clen > 0)
Packit Service 82fcde
	    offset += (fp->_wide_data->_IO_write_ptr
Packit Service 82fcde
		       - fp->_wide_data->_IO_write_base) * clen;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      size_t delta = (fp->_wide_data->_IO_write_ptr
Packit Service 82fcde
			      - fp->_wide_data->_IO_write_base);
Packit Service 82fcde
Packit Service 82fcde
	      /* Allocate enough space for the conversion.  */
Packit Service 82fcde
	      size_t outsize = delta * sizeof (wchar_t);
Packit Service 82fcde
	      char *out = malloc (outsize);
Packit Service 82fcde
	      char *outstop = out;
Packit Service 82fcde
	      const wchar_t *in = fp->_wide_data->_IO_write_base;
Packit Service 82fcde
Packit Service 82fcde
	      enum __codecvt_result status;
Packit Service 82fcde
Packit Service 82fcde
	      __mbstate_t state = fp->_wide_data->_IO_last_state;
Packit Service a3ed18
	      status = __libio_codecvt_out (cv, &state, in, in + delta, &in,
Packit Service a3ed18
					    out, out + outsize, &outstop);
Packit Service 82fcde
Packit Service 82fcde
	      /* We don't check for __codecvt_partial because it can be
Packit Service 82fcde
		 returned on one of two conditions: either the output
Packit Service 82fcde
		 buffer is full or the input sequence is incomplete.  We
Packit Service 82fcde
		 take care to allocate enough buffer and our input
Packit Service 82fcde
		 sequences must be complete since they are accepted as
Packit Service 82fcde
		 wchar_t; if not, then that is an error.  */
Packit Service 82fcde
	      if (__glibc_unlikely (status != __codecvt_ok))
Packit Service 82fcde
		{
Packit Service 82fcde
		  free (out);
Packit Service 82fcde
		  return WEOF;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      offset += outstop - out;
Packit Service 82fcde
	      free (out);
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* We don't trust _IO_read_end to represent the current file offset
Packit Service 82fcde
	     when writing in append mode because the value would have to be
Packit Service 82fcde
	     shifted to the end of the file during a flush.  Use the write base
Packit Service 82fcde
	     instead, along with the new offset we got above when we did a seek
Packit Service 82fcde
	     to the end of the file.  */
Packit Service 82fcde
	  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
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_wfile_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 int 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_wide (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->_wide_data->_IO_read_base
Packit Service 82fcde
			== fp->_wide_data->_IO_read_end)
Packit Service 82fcde
		       && (fp->_wide_data->_IO_write_base
Packit Service 82fcde
			   == fp->_wide_data->_IO_write_ptr));
Packit Service 82fcde
Packit Service 82fcde
  bool was_writing = ((fp->_wide_data->_IO_write_ptr
Packit Service 82fcde
		       > fp->_wide_data->_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_wget_mode (fp))
Packit Service 82fcde
    return WEOF;
Packit Service 82fcde
Packit Service 82fcde
  if (fp->_wide_data->_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->_wide_data->_IO_read_base != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (fp->_wide_data->_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
      _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		 fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
      _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		 fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  switch (dir)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct _IO_codecvt *cv;
Packit Service 82fcde
      int clen;
Packit Service 82fcde
Packit Service 82fcde
    case _IO_seek_cur:
Packit Service 82fcde
      /* Adjust for read-ahead (bytes is buffer).  To do this we must
Packit Service 82fcde
	 find out which position in the external buffer corresponds to
Packit Service 82fcde
	 the current position in the internal buffer.  */
Packit Service 82fcde
      cv = fp->_codecvt;
Packit Service a3ed18
      clen = __libio_codecvt_encoding (cv);
Packit Service 82fcde
Packit Service 82fcde
      if (mode != 0 || !was_writing)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (clen > 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      offset -= (fp->_wide_data->_IO_read_end
Packit Service 82fcde
			 - fp->_wide_data->_IO_read_ptr) * clen;
Packit Service 82fcde
	      /* Adjust by readahead in external buffer.  */
Packit Service 82fcde
	      offset -= fp->_IO_read_end - fp->_IO_read_ptr;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      int nread;
Packit Service 82fcde
Packit Service 82fcde
	      delta = (fp->_wide_data->_IO_read_ptr
Packit Service 82fcde
		       - fp->_wide_data->_IO_read_base);
Packit Service 82fcde
	      fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
Packit Service a3ed18
	      nread = __libio_codecvt_length (cv,
Packit Service a3ed18
					      &fp->_wide_data->_IO_state,
Packit Service a3ed18
					      fp->_IO_read_base,
Packit Service a3ed18
					      fp->_IO_read_end, delta);
Packit Service 82fcde
	      fp->_IO_read_ptr = fp->_IO_read_base + nread;
Packit Service 82fcde
	      fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
Packit Service 82fcde
	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (fp->_offset == _IO_pos_BAD)
Packit Service 82fcde
	goto dumb;
Packit Service 82fcde
Packit Service 82fcde
      /* Make offset absolute, assuming current pointer is file_ptr(). */
Packit Service 82fcde
      offset += fp->_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
Packit Service 82fcde
  _IO_free_wbackup_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
	  _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		     fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		     fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
	  _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		     fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
Packit Service 82fcde
	  if (adjust_wide_data (fp, false))
Packit Service 82fcde
	    goto dumb;
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
  _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
	     fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
  _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
Packit Service 82fcde
  if (adjust_wide_data (fp, true))
Packit Service 82fcde
    goto dumb;
Packit Service 82fcde
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
      _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		 fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
Packit Service 82fcde
      _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
Packit Service 82fcde
		 fp->_wide_data->_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_def (_IO_wfile_seekoff)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
size_t
Packit Service 82fcde
_IO_wfile_xsputn (FILE *f, const void *data, size_t n)
Packit Service 82fcde
{
Packit Service 82fcde
  const wchar_t *s = (const wchar_t *) data;
Packit Service 82fcde
  size_t to_do = n;
Packit Service 82fcde
  int must_flush = 0;
Packit Service 82fcde
  size_t count;
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
  count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr;
Packit Service 82fcde
  if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
Packit Service 82fcde
    {
Packit Service 82fcde
      count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr;
Packit Service 82fcde
      if (count >= n)
Packit Service 82fcde
	{
Packit Service 82fcde
	  const wchar_t *p;
Packit Service 82fcde
	  for (p = s + n; p > s; )
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (*--p == L'\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
  /* 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->_wide_data->_IO_write_ptr =
Packit Service 82fcde
	    __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
Packit Service 82fcde
	  s += count;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  wchar_t *p = f->_wide_data->_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->_wide_data->_IO_write_ptr = p;
Packit Service 82fcde
	}
Packit Service 82fcde
      to_do -= count;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (to_do > 0)
Packit Service 82fcde
    to_do -= _IO_wdefault_xsputn (f, s, to_do);
Packit Service 82fcde
  if (must_flush
Packit Service 82fcde
      && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base)
Packit Service 82fcde
    _IO_wdo_write (f, f->_wide_data->_IO_write_base,
Packit Service 82fcde
		   f->_wide_data->_IO_write_ptr
Packit Service 82fcde
		   - f->_wide_data->_IO_write_base);
Packit Service 82fcde
Packit Service 82fcde
  return n - to_do;
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (_IO_wfile_xsputn)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_wfile_jumps libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_new_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow),
Packit Service 82fcde
  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
Packit Service 82fcde
  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
Packit Service 82fcde
  JUMP_INIT(xsputn, _IO_wfile_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_wfile_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_sync_t) _IO_wfile_sync),
Packit Service 82fcde
  JUMP_INIT(doallocate, _IO_wfile_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_wfile_jumps)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
const struct _IO_jump_t _IO_wfile_jumps_mmap libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_new_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
Packit Service 82fcde
  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
Packit Service 82fcde
  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
Packit Service 82fcde
  JUMP_INIT(xsputn, _IO_wfile_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_wfile_seekoff),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
Packit Service 82fcde
  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
Packit Service 82fcde
  JUMP_INIT(doallocate, _IO_wfile_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_wfile_jumps_maybe_mmap libio_vtable =
Packit Service 82fcde
{
Packit Service 82fcde
  JUMP_INIT_DUMMY,
Packit Service 82fcde
  JUMP_INIT(finish, _IO_new_file_finish),
Packit Service 82fcde
  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
Packit Service 82fcde
  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap),
Packit Service 82fcde
  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
Packit Service 82fcde
  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
Packit Service 82fcde
  JUMP_INIT(xsputn, _IO_wfile_xsputn),
Packit Service 82fcde
  JUMP_INIT(xsgetn, _IO_file_xsgetn),
Packit Service 82fcde
  JUMP_INIT(seekoff, _IO_wfile_seekoff),
Packit Service 82fcde
  JUMP_INIT(seekpos, _IO_default_seekpos),
Packit Service 82fcde
  JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
Packit Service 82fcde
  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
Packit Service 82fcde
  JUMP_INIT(doallocate, _IO_wfile_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
};