Date: Mon, 9 Nov 1998 16:20:15 -0600 (CST) From: dnelson@emsphone.com To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: bin/8637: fgetpos()/fsetpos() don't work for >2GB filesize Message-ID: <199811092220.QAA20439@dan.emsphone.com>
next in thread | raw e-mail | index | archive | help
>Number: 8637
>Category: bin
>Synopsis: fgetpos()/fsetpos() don't work for >2GB filesize
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Nov 9 14:30:00 PST 1998
>Last-Modified:
>Originator: Dan Nelson
>Organization:
Executive Marketing Services, Inc.
>Release: FreeBSD 2.2.7-STABLE i386
>Environment:
FreeBSD dan.emsphone.com 2.2.7-STABLE FreeBSD 2.2.7-STABLE #0: Sat Aug 8 15:03:34 CDT 1998 dan@dan.emsphone.com:/usr/src/sys/compile/DAN i386
>Description:
fgetpos() and fsetpos() call fseek and ftell to do their dirty work.
This means that all FILE* operations are limited to the 2GB limit
imposed by the "long" offset type.
>How-To-Repeat:
Create a 3GB file. Read 2.1GB into it. Call fsetpos(fgetpos()), and
note that you are not where you should be.
>Fix:
1. Rename ftell to ftello, and fseek to fseeko, which are X/Open standard
functions that take off_t offsets. All that had to be changed was the
prototypes, as the internals already used fpos_t.
2. add new fseek/ftell functions.
3. change fsetpos/fgetpos to use fseeko/ftello.
4. add protptypes to stdio.h.
One thing; our errno.h doesn't have an EOVERFLOW, so I used EFBIG in
ftell() for filesizes that exceed 2GB. This should probably get fixed.
-Dan Nelson
dnelson@emsphone.com
Index: fgetpos.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdio/fgetpos.c,v
retrieving revision 1.3
diff -u -r1.3 fgetpos.c
--- fgetpos.c 1996/06/22 10:33:09 1.3
+++ fgetpos.c 1998/11/09 20:12:33
@@ -57,7 +57,7 @@
#ifdef _THREAD_SAFE
_thread_flockfile(fp,__FILE__,__LINE__);
#endif
- retval = (*pos = ftell(fp)) == (fpos_t)-1;
+ retval = (*pos = ftello(fp)) == (fpos_t)-1;
#ifdef _THREAD_SAFE
_thread_funlockfile(fp);
#endif
Index: fseek.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdio/fseek.c,v
retrieving revision 1.4
diff -u -r1.4 fseek.c
--- fseek.c 1996/06/22 10:33:22 1.4
+++ fseek.c 1998/11/09 20:21:22
@@ -56,14 +56,23 @@
#define POS_ERR (-(fpos_t)1)
+int
+fseek(fp, offset, whence)
+ register FILE *fp;
+ long offset;
+ int whence;
+{
+ return (fseeko(fp, offset, whence));
+}
+
/*
* Seek the given file to the given offset.
* `Whence' must be one of the three SEEK_* macros.
*/
int
-fseek(fp, offset, whence)
+fseeko(fp, offset, whence)
register FILE *fp;
- long offset;
+ off_t offset;
int whence;
{
register fpos_t (*seekfn) __P((void *, fpos_t, int));
Index: fsetpos.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdio/fsetpos.c,v
retrieving revision 1.3
diff -u -r1.3 fsetpos.c
--- fsetpos.c 1996/06/22 10:33:23 1.3
+++ fsetpos.c 1998/11/09 20:12:47
@@ -52,5 +52,5 @@
FILE *iop;
const fpos_t *pos;
{
- return (fseek(iop, (long)*pos, SEEK_SET));
+ return (fseeko(iop, (off_t)*pos, SEEK_SET));
}
Index: ftell.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdio/ftell.c,v
retrieving revision 1.5
diff -u -r1.5 ftell.c
--- ftell.c 1996/06/22 10:33:25 1.5
+++ ftell.c 1998/11/09 21:59:47
@@ -44,17 +44,32 @@
#include <stdio.h>
#include <errno.h>
+#include <limits.h>
#include "local.h"
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
#endif
+/* standard ftell function. */
+long
+ftell(fp)
+ register FILE *fp;
+{
+ register off_t rv;
+ rv = ftello(fp);
+ if (rv > LONG_MAX) {
+ errno = EFBIG; /* XXX should be EOVERFLOW */
+ return (-1);
+ }
+ return (rv);
+}
+
/*
* ftell: return current offset.
*/
-long
-ftell(fp)
+off_t
+ftello(fp)
register FILE *fp;
{
register fpos_t pos;
Index: stdio.h
===================================================================
RCS file: /home/ncvs/src/include/stdio.h,v
retrieving revision 1.8.2.2
diff -u -r1.8.2.2 stdio.h
--- stdio.h 1998/02/17 00:48:17 1.8.2.2
+++ stdio.h 1998/11/09 20:32:03
@@ -234,8 +234,10 @@
FILE *freopen __P((const char *, const char *, FILE *));
int fscanf __P((FILE *, const char *, ...));
int fseek __P((FILE *, long, int));
+int fseeko __P((FILE *, off_t, int));
int fsetpos __P((FILE *, const fpos_t *));
long ftell __P((FILE *));
+off_t ftello __P((FILE *));
size_t fwrite __P((const void *, size_t, size_t, FILE *));
int getc __P((FILE *));
int getchar __P((void));
-Dan Nelson
dnelson@emsphone.com
>Audit-Trail:
>Unformatted:
Dan Nelson
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811092220.QAA20439>
