Blame gl/ftello.c

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