The following testcase shows a r/w incompatibility between glibc-2.2.5-37 (updated rh7.3) and glibc-2.2.90-17 (beta limbo). Steps are: 1. fopen() file in "r" mode 2. append data to this file: 2.a: fopen() file in "a" mode 2.b: fprintf() on file 2.c: fclose() file 3. fseek() to old end of file. 4. fgets() With glibc-2.2.5-37: appended data are correctly read in step 4. baud:~/Bug$ echo "Hello" >/tmp/foo baud:~/Bug$ gcc -Wall -o test test.c baud:~/Bug$ ./test Ok. With glibc-2.2.90-17: no data can be read in step 4. baud:~/Bug$ echo "Hello" >/tmp/foo baud:~/Bug$ gcc -Wall -o test test.c baud:~/Bug$ ./test Error: fgets() 0: Success Could not read appended data. I don't know what the libc standard requires for this testcase. Could you tell me if this is a bug or only an incompatibility? In the case it is not a bug, then mutt should be fixed, because this is what causes problems when checking new mails appended by sendmail to a 'mbox' mailbox.
Created attachment 68444 [details] testcase in C (58 lines)
Yes, I know about this very well. The above testcase really is triggering undefined behaviour, but from what I saw on mutt it does what is required, ie. an fflush call in between. Roland just checked in a fix for this, http://sources.redhat.com/ml/libc-hacker/2002-08/msg00006.html I'll give it some testing later today.
fflush() does not help... I changed my testcase as shown below and I still have the same error in fgets(). --- test.c 2002-08-02 15:05:01 +0200 +++ test.c 2002-08-02 15:00:30 +0200 @@ -44,6 +44,9 @@ /* Try to read appended data */ + rc = fflush (fp); + check_rc (rc != 0, "fflush()"); + rc = fseek (fp, end, SEEK_SET); check_rc (rc != 0, "fseek()");
Well, from a standards point of view it matters. That glibc until now did not do this properly for mmap stdio is a bug.
Obviously, fragments of the file are mapped all over the place ;) In the present state, it cannot work. open("/tmp/foo", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0664, st_size=6, ...}) = 0 mmap2(NULL, 6, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40013000 ^^^^^^^ ^^^^^^^^^^ stat64("/tmp/foo", {st_mode=S_IFREG|0664, st_size=6, ...}) = 0 open("/tmp/foo", O_WRONLY|O_APPEND|O_CREAT, 0666) = 4 fstat64(4, {st_mode=S_IFREG|0664, st_size=6, ...}) = 0 mmap2(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0)=0x40014000 ^^^^^^^^^^ fstat64(4, {st_mode=S_IFREG|0664, st_size=6, ...}) = 0 _llseek(4, 6, [6], SEEK_SET) = 0 ^^^^^^^^^^^^^^^^ write(4, "...appended data...\n", 20) = 20 ^^^^^^^^^^^^^^^^^^^^^ close(4) = 0 munmap(0x40014000, 4096) = 0
From libc/libio/bug-mmap-fflush.c (Roland McGrath 07/31): if (strncmp (buffer, "From ", 5) != 0) abort (); At least, now I am sure... I am not the only one to have mailbox problems ;) And yes, this is stol^H^H^H^Hborrowed from mutt! ;)
Current glibc cvs works for me. Hope this will be backport soon to rawhide.
Fixed in -21. Thanks.