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>