Blame gl/ftello.c

Packit aea12f
/* An ftello() function that works around platform bugs.
Packit Service 991b93
   Copyright (C) 2007, 2009-2020 Free Software Foundation, Inc.
Packit aea12f
Packit aea12f
   This program is free software: you can redistribute it and/or modify
Packit Service 991b93
   it under the terms of the GNU Lesser General Public License as published by
Packit Service 991b93
   the Free Software Foundation; either version 2.1 of the License, or
Packit aea12f
   (at your option) any later version.
Packit aea12f
Packit aea12f
   This program is distributed in the hope that it will be useful,
Packit aea12f
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 991b93
   GNU Lesser General Public License for more details.
Packit aea12f
Packit Service 991b93
   You should have received a copy of the GNU Lesser General Public License
Packit aea12f
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit aea12f
Packit aea12f
#include <config.h>
Packit aea12f
Packit aea12f
/* Specification.  */
Packit aea12f
#include <stdio.h>
Packit aea12f
Packit aea12f
/* Get lseek.  */
Packit aea12f
#include <unistd.h>
Packit aea12f
Packit aea12f
#include "stdio-impl.h"
Packit aea12f
Packit aea12f
off_t
Packit aea12f
ftello (FILE *fp)
Packit aea12f
#undef ftello
Packit aea12f
#if !HAVE_FTELLO
Packit aea12f
# undef ftell
Packit aea12f
# define ftello ftell
Packit aea12f
#endif
Packit aea12f
#if _GL_WINDOWS_64_BIT_OFF_T
Packit aea12f
# undef ftello
Packit aea12f
# if HAVE__FTELLI64 /* msvc, mingw64 */
Packit aea12f
#  define ftello _ftelli64
Packit aea12f
# else /* mingw */
Packit aea12f
#  define ftello ftello64
Packit aea12f
# endif
Packit aea12f
#endif
Packit aea12f
{
Packit aea12f
#if LSEEK_PIPE_BROKEN
Packit aea12f
  /* mingw gives bogus answers rather than failure on non-seekable files.  */
Packit aea12f
  if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
Packit aea12f
    return -1;
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#if FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE /* Solaris */
Packit aea12f
  /* The Solaris stdio leaves the _IOREAD flag set after reading from a file
Packit aea12f
     reaches EOF and the program then starts writing to the file.  ftello
Packit aea12f
     gets confused by this.  */
Packit aea12f
  if (fp_->_flag & _IOWRT)
Packit aea12f
    {
Packit aea12f
      off_t pos;
Packit aea12f
Packit aea12f
      /* Call ftello nevertheless, for the side effects that it does on fp.  */
Packit aea12f
      ftello (fp);
Packit aea12f
Packit aea12f
      /* Compute the file position ourselves.  */
Packit aea12f
      pos = lseek (fileno (fp), (off_t) 0, SEEK_CUR);
Packit aea12f
      if (pos >= 0)
Packit aea12f
        {
Packit aea12f
          if ((fp_->_flag & _IONBF) == 0 && fp_->_base != NULL)
Packit aea12f
            pos += fp_->_ptr - fp_->_base;
Packit aea12f
        }
Packit aea12f
      return pos;
Packit aea12f
    }
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#if defined __SL64 && defined __SCLE /* Cygwin */
Packit aea12f
  if ((fp->_flags & __SL64) == 0)
Packit aea12f
    {
Packit aea12f
      /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
Packit aea12f
         mode; but has an ftello that requires 64-bit mode.  */
Packit aea12f
      FILE *tmp = fopen ("/dev/null", "r");
Packit aea12f
      if (!tmp)
Packit aea12f
        return -1;
Packit aea12f
      fp->_flags |= __SL64;
Packit aea12f
      fp->_seek64 = tmp->_seek64;
Packit aea12f
      fclose (tmp);
Packit aea12f
    }
Packit aea12f
#endif
Packit aea12f
  return ftello (fp);
Packit aea12f
}