Problem: fwrite and fseek.

Problem: fwrite and fseek.

Post by Ulrich Hell » Fri, 11 Jun 1993 19:30:58



I think I've found a bug in the buffered io
library. The following code does work on
other systems but not on any version of
LINUX/GNU_C available to me now. (2.2.2d/jump4.1,
2.3.3/jump4.3.3 from SLS 1.01, 2.4.0/libc.4.4
from tsx-11)

The code below performs the following actions:
1)      Open a file for writing and reading
2)      Write two lines into the file           ("1111.." and "2121..")
3)      Flush buffers
4)      Seek to the end of the first line
5)      Flush buffers again
6)      Write another two lines                 ("2222.." and "3333..")
        This step should overwrite the second
        line written by step 2) ("2121..")
        and append another line.
7)      Close file and terminate

Obviously, one would expect the file to
contain three lines after the program
has been executed:

1111111111      |
2222222222      |<--- Expected result
3333333333      |

But here comes what the file actually
looks like:

2222222222      |
3333333333      |<--- Real result

It seems that step 4 failed and set the
write pointer to 0 instead of 11 (=length
of each line). If you call "ftell" after
step 4) or 5), it returns the correct value: 11.
"ftell" returns a value of 11 again after
the next call of "fwrite". That fwrite
overwrites the FIRST line (position 0-10)
instead of the SECOND line (position 11-21).

I have found two by-passes for the problem:
A)      Turn off buffering via "setvbuf(...,_IONBUF,...)"
B)      Skip step 5 (fflush after fseek)

By-pass A) is inacceptable because I want
BUFFERED I/O to minimize execution time.
Solution B) works just in this very small
program. I am working on a quite complex
program which uses buffered I/O very
extensively. The program runs perfectly on
other platforms. It crashes almost immediately
on LINUX when I embed all "fseek"s by
"fflush"s. If I delete all "fflush"s (or
just the "fflush"s after the "fseek"s), the
program runs significantly better, but
sooner or later mysterious errors occur.
The program runs perfectly stable when
using "solution" A).

I just asked a friend of mine to verify
the problem to prevent me from posting
stupid things. He found out that there's
another solution for the problem:

C) Call setvbuf(..., _IOFBF, 129).

Any buffer size seems to be OK
which can be written as 2^n + 1 and
which is bigger than 9.

uli.

------------------------------------------------------------------------------

/*--CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE--*/
#include <stdio.h>

char line1[]  = "1111111111\n";
char line21[] = "2121212121\n";
char line22[] = "2222222222\n";
char line3[]  = "3333333333\n";
/* char buffer[1000]; */

int main(int argc, char *argv[])
{
        FILE    *f;
        int     len = strlen(line1);

        f = fopen("tst.out", "wb+");        /* step 1 */
        /*
        ** setvbuf(f, buffer, _IOFBF, 129);
        **            - or -
        ** setvbuf(f, NULL, _IONBF, 0);
        */
        fwrite(line1, 1, len, f);
        fwrite(line21, 1, len, f);      /* step 2 */
        fflush(f);                      /* step 3 */
        fseek(f, 1*len, SEEK_SET);      /* step 4 */
        fflush(f);                      /* step 5 */
        fwrite(line22, 1, len, f);
        fwrite(line3, 1, len, f);       /* step 6 */
        fclose(f);
        return(0);                      /* step 7 */

Quote:}

/*--CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE----CUT-HERE--*/
--
------------------------------------------------------------------------------

 
 
 

1. weird problem with (fseek/ftell/fwrite/putc)

Hello,
as I tried to compile zoo using gcc 2.11c / linux 0.96a & patch1
I got a problem which I tracked down to the following:

when adding a file to an archive zoo first creates an empty directory
entry in the archive, then compresses the file and stores it and then
fseeks back to the position of the directory entry and overwrites it.

This works fine with standard compression.

If high compression is used, the compressed file is not stored using
blocktype read/write operations, but using putc. I inserted an ftell
into the code after the following fseek, which reports the right
position. Nevertheless the following fwrite doesn't go there, but
on the next 1024 bytes boundary. No need to say that this corrupts
the archive.

If this is a bug, is it in the gcc libraries or in the kernel?
Is there any immediate fix? I would like the zoo high compression
to work reliably to use zoo for my backups.

Thanks for 'listening',
        Greg

2. NETSCAPE server,location header

3. Matrox Mystique ands X.

4. updating linux - a howto about directory structure?

5. Problem fread/fwriting sockets

6. Sony 33A CDRON & Linux

7. fwrite problem

8. synchronous over a serial driver

9. Q: Input piped via stdin and fseek() problem

10. Problem with fwrite()

11. problem in C using fwrite

12. fseek problem

13. NFS performance problem with fseek()