From nobody@FreeBSD.ORG Mon Jul  5 17:02:59 1999
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id E6B0B15001; Mon,  5 Jul 1999 17:02:59 -0700 (PDT)
Message-Id: <19990706000259.E6B0B15001@hub.freebsd.org>
Date: Mon,  5 Jul 1999 17:02:59 -0700 (PDT)
From: kientzle@acm.org
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: fseek(f,o,SEEK_CUR) broken on large files
X-Send-Pr-Version: www-1.0

>Number:         12526
>Category:       misc
>Synopsis:       fseek(f,o,SEEK_CUR) broken on large files
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dt
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul  5 17:10:00 PDT 1999
>Closed-Date:    Tue Jul 20 04:46:28 PDT 1999
>Last-Modified:  Tue Jul 20 04:51:23 PDT 1999
>Originator:     Tim Kientzle
>Release:        FreeBSD 3.1-RELEASE i386
>Organization:
Independent software consultant
>Environment:
FreeBSD clover.kientzle.com 3.1-RELEASE FreeBSD 3.1-RELEASE #10: Thu Jul  1 13:48:43 PDT 1999     root@clover.kientzle.com:/usr/src/sys/compile/CLOVER  i386
>Description:
fseek() does not properly handle SEEK_CUR if the resulting
file position would exceed 2^31.

(Remember that SEEK_CUR and SEEK_END can both be used to seek
beyond 2^31 even though fseek only accepts a 32-bit signed long offset.)
>How-To-Repeat:
In a 4gig file, perform:

fseek(f,0x7fffffffL, SEEK_SET);
fseek(f,0x7fffffffL, SEEK_CUR); /* This seek silently fails */
>Fix:
fseek() correctly uses 64-bit fpos_t arithmetic to compute the new
file offset when converting SEEK_CUR to SEEK_SET, but then assigns the
64-bit result into the 32-bit 'offset' variable.

This can be fixed by changing the variable 'offset' to a 64-bit fpos_t
type, which in turn requires renaming the actual argument to maintain
the ANSI-dictated interface.  The three lines marked 'TBKK' below are
the necessary changes.
        
/usr/src/lib/libc/stdio/fseek.c:

int
fseek(fp, offset32, whence) /* TBKK: renamed 'offset' to 'offset32' */
        register FILE *fp;
        long offset32; /* TBKK: renamed 'offset' to 'offset32' */
        int whence;
{
        register fpos_t (*seekfn) __P((void *, fpos_t, int));
        fpos_t target, curoff;
        fpos_t offset = offset32; /* TBKK: added 64-bit offset variable */



>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->feedback 
State-Changed-By: sheldonh 
State-Changed-When: Fri Jul 9 07:21:24 PDT 1999 
State-Changed-Why:  
Could you try with a more recent release of FreeBSD? 3.2-RELEASE has 
bene out for a while now, and the code you're talking about has changed 
since 3.2-RELEASE. 
Responsible-Changed-From-To: freebsd-bugs->sheldonh 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Mon Jul 19 03:06:35 PDT 1999 
Responsible-Changed-Why:  
Tim's going to try to whip up a small How-To-Repeat program for me, 
since he's not in a position to test with a more recent version 
at this time. 
State-Changed-From-To: feedback->closed 
State-Changed-By: sheldonh 
State-Changed-When: Tue Jul 20 04:46:28 PDT 1999 
State-Changed-Why:  
Fixed in rev 1.8 of src/lib/libc/stdio/fseek.c, based on Dan Nelson's 
patch on PR 8637, and MFC'd. 


Responsible-Changed-From-To: sheldonh->dt 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Tue Jul 20 04:46:28 PDT 1999 
Responsible-Changed-Why:  
Dmitrij committed the fix. 
>Unformatted:
