Bug 21761 - write system call does not recognize prior fseek
write system call does not recognize prior fseek
Status: CLOSED NOTABUG
Product: Red Hat Linux
Classification: Retired
Component: libc (Show other bugs)
6.2
i686 Linux
medium Severity high
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2000-12-05 14:26 EST by Karl D. Paxton
Modified: 2008-05-01 11:37 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2000-12-05 19:32:56 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Karl D. Paxton 2000-12-05 14:26:59 EST
On a file opened for read & write (r+ or w+), a write() system call does 
not honor a prior fseek(), but writes its data at the file position that 
was in effect before the fseek().

Problem found in Linux 6.2 (Zoot), kernel 2.2.14-6.1.1smp, duplicated in 
Linux 7.0 (Guinness), kernel 2.2.16-22.

I have a small test program which demonstrates the problem nicely.  Can 
send it via e-mail or ftp if you wish.  The gist of it is:

    fwrite() 20 integers.
    fseek() back into the middle of that.
    write() another integer.

The value put out by the final write() should appear in the middle of the 
data file when the program is done.  In fact, it gets put at the end of
the file.

I ran this program on HP-UX and AIX to verify that Linux's behavior is 
indeed different from "standard" UNIX.

There is a work-around, but I called the severity "high" because a data 
file can be corrupted by this problem.
Comment 1 Jakub Jelinek 2000-12-06 04:51:22 EST
If you mean test like:
#include <stdio.h>
#include <unistd.h>

int main()
{
  FILE *f = fopen ("/tmp/xxx", "w+");
  int i;

  for (i = 0; i < 20; i++)
    fwrite ("244", 3, 1, f);
  fseek (f, 15, SEEK_SET);
  write (fileno (f), "355", 3);
  fclose (f);
}
then there is really no guarantee that fseek will move the underlying file
descriptor position.
See http://www.opennc.org/onlinepubs/007908799/xsh/fseek.html
where it explicitely states that:
If the most recent operation, other than ftell(), on a given stream is
fflush(), the file offset in the underlying open file description will be
adjusted to reflect the location specified by fseek().

There is nothing about underlying file descriptor unless you call fflush
before it. And indeed, if I add fflush (f) in the above example either right
before the fseek or right after the fseek, 355 will be present at offset 15
(otherwise it can wind up at offset 60).

So in my eyes you just rely on undefined behaviour.

Note You need to log in before you can comment on or make changes to this bug.