From c66e4f69b6e4a1058ce10b236af1b80591a63931 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 16 Aug 2009 15:51:23 +0200 Subject: [PATCH] Clarify fpurge's effect on the file position. --- ChangeLog | 7 +++ lib/stdio.in.h | 3 + tests/test-fpurge.c | 157 +++++++++++++++++++++++++++++----------------------- 3 files changed, 99 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2233ff170..4257394fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2009-08-16 Bruno Haible + Clarify fpurge's effect on the file position. + * lib/stdio.in.h (fpurge): Specify the file position after fpurge. + * tests/test-fpurge.c (main): Make a second pass for checking the file + position. + +2009-08-16 Bruno Haible + * m4/fpurge.m4 (gl_FUNC_FPURGE): Don't compile fpurge.c if only the declaration of fpurge is missing. * tests/test-fpurge.c (main): Check that the file has not more contents diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 78e35d57b..0c33ed810 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -414,6 +414,9 @@ extern long rpl_ftell (FILE *fp); # if @REPLACE_FPURGE@ || !@HAVE_DECL_FPURGE@ /* Discard all pending buffered I/O data on STREAM. STREAM must not be wide-character oriented. + When discarding pending output, the file position is set back to where it + was before the write calls. When discarding pending input, the file + position is advanced to match the end of the previously read input. Return 0 if successful. Upon error, return -1 and set errno. */ extern int fpurge (FILE *gl_stream); # endif diff --git a/tests/test-fpurge.c b/tests/test-fpurge.c index 596dd75ae..13388ec39 100644 --- a/tests/test-fpurge.c +++ b/tests/test-fpurge.c @@ -40,74 +40,95 @@ int main () { - FILE *fp; - - /* Create a file with some contents. */ - fp = fopen (TESTFILE, "w"); - if (fp == NULL) - goto skip; - if (fwrite ("foobarsh", 1, 8, fp) < 8) - goto skip; - if (fclose (fp)) - goto skip; - - /* The file's contents is now "foobarsh". */ - - /* Open it in read-write mode. */ - fp = fopen (TESTFILE, "r+"); - if (fp == NULL) - goto skip; - if (fseek (fp, 3, SEEK_CUR)) - goto skip; - if (fwrite ("g", 1, 1, fp) < 1) - goto skip; - if (fflush (fp)) - goto skip; - if (fwrite ("bz", 1, 2, fp) < 2) - goto skip; - /* Discard pending write. */ - ASSERT (fpurge (fp) == 0); - ASSERT (fclose (fp) == 0); - - /* Open it in read-only mode. */ - fp = fopen (TESTFILE, "r"); - if (fp == NULL) - goto skip; - { - char buf[8]; - if (fread (buf, 1, 7, fp) < 7) - goto skip; - ASSERT (memcmp (buf, "foogars", 7) == 0); - } - /* Discard the buffered 'h', leaving position at EOF. */ - ASSERT (fpurge (fp) == 0); - ASSERT (getc (fp) == EOF); - ASSERT (fclose (fp) == 0); - - /* The file's contents is now "foogarsh". */ - - /* Ensure that purging a read does not corrupt subsequent writes. */ - fp = fopen (TESTFILE, "r+"); - if (fp == NULL) - goto skip; - if (fseek (fp, -1, SEEK_END)) - goto skip; - ASSERT (getc (fp) == 'h'); - ASSERT (getc (fp) == EOF); - ASSERT (fpurge (fp) == 0); - ASSERT (putc ('!', fp) == '!'); - ASSERT (fclose (fp) == 0); - fp = fopen (TESTFILE, "r"); - if (fp == NULL) - goto skip; - { - char buf[10]; - ASSERT (fread (buf, 1, 10, fp) == 9); - ASSERT (memcmp (buf, "foogarsh!", 9) == 0); - } - ASSERT (fclose (fp) == 0); - - /* The file's contents is now "foogarsh!". */ + int check_filepos; + + for (check_filepos = 0; check_filepos <= 1; check_filepos++) + { + FILE *fp; + + /* Create a file with some contents. */ + fp = fopen (TESTFILE, "w"); + if (fp == NULL) + goto skip; + if (fwrite ("foobarsh", 1, 8, fp) < 8) + goto skip; + if (fclose (fp)) + goto skip; + + /* The file's contents is now "foobarsh". */ + + /* Open it in read-write mode. */ + fp = fopen (TESTFILE, "r+"); + if (fp == NULL) + goto skip; + if (fseek (fp, 3, SEEK_CUR)) + goto skip; + if (fwrite ("g", 1, 1, fp) < 1) + goto skip; + if (fflush (fp)) + goto skip; + if (fwrite ("bz", 1, 2, fp) < 2) + goto skip; + /* Discard pending write. */ + ASSERT (fpurge (fp) == 0); + /* Verify that when discarding pending output, the file position is set + back to where it was before the write calls. */ + if (check_filepos) + ASSERT (ftell (fp) == 4); + ASSERT (fclose (fp) == 0); + + /* Open it in read-only mode. */ + fp = fopen (TESTFILE, "r"); + if (fp == NULL) + goto skip; + /* Verify that the pending writes before the fpurge were really + discarded. */ + { + char buf[8]; + if (fread (buf, 1, 7, fp) < 7) + goto skip; + ASSERT (memcmp (buf, "foogars", 7) == 0); + } + /* Discard the buffered 'h'. */ + if (check_filepos) + ASSERT (ftell (fp) == 7); + ASSERT (fpurge (fp) == 0); + /* Verify that when discarding pending input, the file position is + advanced to match the end of the previously read input. */ + if (check_filepos) + ASSERT (ftell (fp) == 8); + ASSERT (getc (fp) == EOF); + ASSERT (fclose (fp) == 0); + + /* The file's contents is now "foogarsh". */ + + /* Ensure that purging a read does not corrupt subsequent writes. */ + fp = fopen (TESTFILE, "r+"); + if (fp == NULL) + goto skip; + if (fseek (fp, -1, SEEK_END)) + goto skip; + ASSERT (getc (fp) == 'h'); + ASSERT (getc (fp) == EOF); + if (check_filepos) + ASSERT (ftell (fp) == 8); + ASSERT (fpurge (fp) == 0); + if (check_filepos) + ASSERT (ftell (fp) == 8); + ASSERT (putc ('!', fp) == '!'); + ASSERT (fclose (fp) == 0); + fp = fopen (TESTFILE, "r"); + if (fp == NULL) + goto skip; + { + char buf[10]; + ASSERT (fread (buf, 1, 10, fp) == 9); + ASSERT (memcmp (buf, "foogarsh!", 9) == 0); + } + ASSERT (fclose (fp) == 0); + + /* The file's contents is now "foogarsh!". */ + } remove (TESTFILE); return 0; -- 2.11.0