crt/stdio/fseeki64: Copy-n-paste from `f{tell,seek}o64()`

The old implementation of `_ftelli64()` was introduced in 518dd33c326 in
2007. However it sometimes reports incorrect values. This program, after
being compiled with `i686-w64-mingw32-gcc`, outputs `-15` on the second
line on my Windows 7 Professional:

    #include <stdio.h>
    #include <assert.h>

    int main(void)
      {
        FILE* fp = fopen(__FILE__, "rb");
        assert(fp);
        printf("offset = %lld\n", (long long)_ftelli64(fp));

        char buf[1];
        ssize_t nread = fread(&buf, 1, 1, fp);
        assert(nread == 1);
        printf("offset = %lld\n", (long long)_ftelli64(fp));

        fclose(fp);
      }

This is apparently incorrect, as file offsets can't be negative.

If it was compiled with `x86_64-w64-mingw32-gcc`, it however outputs `1`
as expected.

Since 4d3b28a992, we have had 64-bit tell/seek functions. They should be
used to de-duplicate these implementations.

Signed-off-by: Liu Hao <lh_mouse@126.com>
diff --git a/mingw-w64-crt/stdio/fseeki64.c b/mingw-w64-crt/stdio/fseeki64.c
index fdb8f1c..f70062e 100644
--- a/mingw-w64-crt/stdio/fseeki64.c
+++ b/mingw-w64-crt/stdio/fseeki64.c
@@ -6,172 +6,45 @@
 #include <stdio.h>
 #include <io.h>
 #include <errno.h>
-#include <internal.h>
-
-#define _IOYOURBUF      0x0100
-#define _IOSETVBUF      0x0400
-#define _IOFEOF         0x0800
-#define _IOFLRTN        0x1000
-#define _IOCTRLZ        0x2000
-#define _IOCOMMIT       0x4000
-
-/* General use macros */
-
-#define inuse(s)        ((s)->_flag & (_IOREAD|_IOWRT|_IORW))
-#define mbuf(s)         ((s)->_flag & _IOMYBUF)
-#define nbuf(s)         ((s)->_flag & _IONBF)
-#define ybuf(s)         ((s)->_flag & _IOYOURBUF)
-#define bigbuf(s)       ((s)->_flag & (_IOMYBUF|_IOYOURBUF))
-#define anybuf(s)       ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF))
-
-#define _INTERNAL_BUFSIZ    4096
-#define _SMALL_BUFSIZ       512
-
-#define FOPEN           0x01    /* file handle open */
-#define FEOFLAG         0x02    /* end of file has been encountered */
-#define FCRLF           0x04    /* CR-LF across read buffer (in text mode) */
-#define FPIPE           0x08    /* file handle refers to a pipe */
-#define FNOINHERIT      0x10    /* file handle opened _O_NOINHERIT */
-#define FAPPEND         0x20    /* file handle opened O_APPEND */
-#define FDEV            0x40    /* file handle refers to device */
-#define FTEXT           0x80    /* file handle is in text mode */
-
-_CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd);
-__int64 __cdecl _ftelli64(FILE *str);
 
 #if !defined(__arm__) && !defined(__aarch64__) /* we have F_ARM_ANY(_fseeki64) in msvcrt.def.in */
-int __cdecl _flush (FILE *str);
-
-int __cdecl _flush (FILE *str)
+int __cdecl _fseeki64(FILE* stream, __int64 offset, int whence)
 {
-  FILE *stream;
-  int rc = 0; /* assume good return */
-  __int64 nchar;
-
-  stream = str;
-  if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream)
-      && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll)
-  {
-    if ( _write(_fileno(stream), stream->_base, nchar) == nchar) {
-      if (_IORW & stream->_flag)
-        stream->_flag &= ~_IOWRT;
-    } else {
-      stream->_flag |= _IOERR;
-      rc = EOF;
+  fpos_t pos;
+  if (whence == SEEK_CUR)
+    {
+      /* If stream is invalid, fgetpos sets errno. */
+      if (fgetpos (stream, &pos))
+        return (-1);
+      pos += (fpos_t) offset;
     }
-  }
-  stream->_ptr = stream->_base;
-  stream->_cnt = 0ll;
-  return rc;
+  else if (whence == SEEK_END)
+    {
+      /* If writing, we need to flush before getting file length.  */
+      fflush (stream);
+      pos = (fpos_t) (_filelengthi64 (_fileno (stream)) + offset);
+    }
+  else if (whence == SEEK_SET)
+    pos = (fpos_t) offset;
+  else
+    {
+      errno = EINVAL;
+      return (-1);
+    }
+  return fsetpos (stream, &pos);
 }
 
-int __cdecl _fseeki64(FILE *str,__int64 offset,int whence)
-{
-        FILE *stream;
-        /* Init stream pointer */
-        stream = str;
-        errno=0;
-        if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END)))
-	{
-	  errno=EINVAL;
-	  return -1;
-        }
-        /* Clear EOF flag */
-        stream->_flag &= ~_IOEOF;
-
-        if (whence == SEEK_CUR) {
-	  offset += _ftelli64(stream);
-	  whence = SEEK_SET;
-	}
-        /* Flush buffer as necessary */
-        _flush(stream);
-
-        /* If file opened for read/write, clear flags since we don't know
-           what the user is going to do next. If the file was opened for
-           read access only, decrease _bufsiz so that the next _filbuf
-           won't cost quite so much */
-
-        if (stream->_flag & _IORW)
-                stream->_flag &= ~(_IOWRT|_IOREAD);
-        else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) &&
-                  !(stream->_flag & _IOSETVBUF) )
-                stream->_bufsiz = _SMALL_BUFSIZ;
-
-        /* Seek to the desired locale and return. */
-
-        return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0);
-}
-
-int __cdecl (*__MINGW_IMP_SYMBOL(_fseeki64))(FILE *, __int64, int) = _fseeki64;
+int __cdecl (*__MINGW_IMP_SYMBOL(_fseeki64))(FILE*, __int64, int) = _fseeki64;
 #endif /* !defined(__arm__) && !defined(__aarch64__) */
 
-__int64 __cdecl _ftelli64(FILE *str)
+__int64 __cdecl _ftelli64(FILE* stream)
 {
-        FILE *stream;
-        size_t offset;
-        __int64 filepos;
-        register char *p;
-        char *max;
-        int fd;
-        size_t rdcnt = 0;
-
-	errno=0;
-        stream = str;
-        fd = _fileno(stream);
-        if (stream->_cnt < 0ll) stream->_cnt = 0ll;
-    if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L)
-      return -1ll;
-
-    if (!bigbuf(stream))            /* _IONBF or no buffering designated */
-      return (filepos - (__int64) stream->_cnt);
-
-    offset = (size_t)(stream->_ptr - stream->_base);
-
-    if (stream->_flag & (_IOWRT|_IOREAD))
-      {
-        if (_osfile(fd) & FTEXT)
-          for (p = stream->_base; p < stream->_ptr; p++)
-            if (*p == '\n')  /* adjust for '\r' */
-              offset++;
-      }
-      else if (!(stream->_flag & _IORW)) {
-        errno=EINVAL;
-        return -1ll;
-      }
-      if (filepos == 0ll)
-        return ((__int64)offset);
-
-      if (stream->_flag & _IOREAD)    /* go to preceding sector */
-        {
-          if (stream->_cnt == 0ll)  /* filepos holds correct location */
-            offset = 0ll;
-          else
-            {
-	          rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base));
-		      if (_osfile(fd) & FTEXT) {
-		        if (_lseeki64(fd, 0ll, SEEK_END) == filepos) {
-			      max = stream->_base + rdcnt;
-			    for (p = stream->_base; p < max; p++)
-			      if (*p == '\n') /* adjust for '\r' */
-			        rdcnt++;
-			    if (stream->_flag & _IOCTRLZ)
-			      ++rdcnt;
-		      } else {
-		        _lseeki64(fd, filepos, SEEK_SET);
-		        if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) &&
-		            !(stream->_flag & _IOSETVBUF))
-			      rdcnt = _SMALL_BUFSIZ;
-		        else
-		          rdcnt = stream->_bufsiz;
-		        if  (_osfile(fd) & FCRLF)
-		          ++rdcnt;
-		      }
-		    } /* end if FTEXT */
-	    }
-	  filepos -= (__int64)rdcnt;
-    } /* end else stream->_cnt != 0 */
-  return (filepos + (__int64)offset);
+  fpos_t pos;
+  if (fgetpos (stream, &pos))
+    return -1LL;
+  else
+    return (__int64) pos;
 }
 
-__int64 __cdecl (*__MINGW_IMP_SYMBOL(_ftelli64))(FILE *) = _ftelli64;
+__int64 __cdecl (*__MINGW_IMP_SYMBOL(_ftelli64))(FILE*) = _ftelli64;