NetBSD Problem Report #8359

Received: (qmail 5033 invoked from network); 9 Sep 1999 00:40:45 -0000
Message-Id: <199909090040.RAA13665@nooksack.ldc.cs.wwu.edu>
Date: Wed, 8 Sep 1999 17:40:48 -0700 (PDT)
From: cgd@netbsd.org
Reply-To: cgd@netbsd.org
To: gnats-bugs@gnats.netbsd.org
Subject: ANSI fread() and fwrite() interactions aren't sufficiently documented
X-Send-Pr-Version: www-1.0

>Number:         8359
>Category:       lib
>Synopsis:       ANSI fread() and fwrite() interactions aren't sufficiently documented
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          closed
>Class:          doc-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Sep 09 16:35:01 +0000 1999
>Closed-Date:    Fri Dec 19 20:21:07 +0000 2008
>Last-Modified:  Tue Dec 23 03:55:01 +0000 2008
>Originator:     Chris Demetriou
>Release:        1.4.1
>Organization:
>Environment:
irrelevant.  NetBSD 1.4.1 (manual pages)
>Description:
ANSI specifies that fread() and fwrite() apparently can't be intermingled
in a program in what i'd describe as the naive, or straightforward, way:

For instance, the program:

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

main(int argc, char *argv[])
{
        FILE *f;
        int rv, v[4];

        f = fopen(argv[1], "r+");
        assert(f != NULL);

        rv = fseek(f, 16, SEEK_SET);
        assert (rv != -1);

        printf("%ld\n", ftell(f));

        rv = fread(v, sizeof v, 1, f);
        assert (rv != -1);

        printf("%ld\n", ftell(f));

        v[0] = 0;
        rv = fwrite(&v[0], sizeof v[0], 1, f);

        printf("%ld\n", ftell(f));
}

is apparently _NOT_ correct ANSI C, because in order to write
at the naively expected location (the location of the file pointer
after the read), you need to seek first.

Other systems, e.g. linux, do what is expected, but I understand that
our behaviour is allowed by the relevant standards.  However, this
limitation is not documented in our manual pages, or in K&R, or in
any place obvious to a "naive" C programmer such as myself.

>How-To-Repeat:
take the program above, compile it on linux.  run it like:

4 [zaphod1] tmp % dd if=/dev/zero of=bar bs=1024 count=1
1+0 records in
1+0 records out
5 [zaphod1] tmp % ./a.out bar
16
32
36

Note that the written data went to the expected place.

then compile and run it on NetBSD, and note that the output is:

50 [bacon] tmp % dd if=/dev/zero of=bar bs=1024 count=1
1+0 records in
1+0 records out
1024 bytes transferred in 1 secs (1024 bytes/sec)
51 [bacon] tmp % ./a.out bar
16
32
1028

and in fact the file's been _extended_ with the data that
was written rather than having a few bytes rewritten in place.

Look at K&R (ed. 2) and our manual pages for explanation of the
difference, which is, uh, non-intuitive.  Find none.  Consult your
favorite C gurus, and have them explain it to you.  Wonder how
you (and your boss, who's the person who presented you the
non-functional code to begin with) have never managed to trip
this issue before...
>Fix:
Update the manual pages to explain why this obvious fread()/fwrite()
sequence is not correct.

If ambitious, and the efficiency cost of actually making the code
work as expected isn't significant, fix the manual page _and_ fix
the code so that it works like sane people would expect.  8-)
It'd be interesting to know how many systems produce weird-but-allowed
results like we do...
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed
State-Changed-By: christos@NetBSD.org
State-Changed-When: Fri, 19 Dec 2008 15:21:07 -0500
State-Changed-Why:
fixed, thanks


From: Soren Jacobsen <snj@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/8359 CVS commit: [netbsd-5] src/lib/libc/stdio
Date: Tue, 23 Dec 2008 03:50:57 +0000 (UTC)

 Module Name:	src
 Committed By:	snj
 Date:		Tue Dec 23 03:50:57 UTC 2008

 Modified Files:
 	src/lib/libc/stdio [netbsd-5]: fread.3

 Log Message:
 Pull up following revision(s) (requested by christos in ticket #201):
 	lib/libc/stdio/fread.3: revision 1.13
 PR/8359: Chris Demetriou: Document fread/fwrite mixing behavior.


 To generate a diff of this commit:
 cvs rdiff -r1.12 -r1.12.38.1 src/lib/libc/stdio/fread.3

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.