[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Austin group ruling on ungetc vs. fflush
From: |
Bruno Haible |
Subject: |
Re: Austin group ruling on ungetc vs. fflush |
Date: |
Thu, 15 Jan 2009 12:23:50 +0100 |
User-agent: |
KMail/1.9.9 |
Hi Eric,
> A while ago, we wrote some unit tests that failed on a number of systems
> with different behaviors of fflush after ungetc (particularly if you used
> ungetc to push back a different byte than what was originally read). At
> the time, Bruno ended up commenting the tests out until we had an official
> ruling from the POSIX folks on what should happen.
>
> Well, the topic finally came up in yesterday's meeting:
>
> https://www.opengroup.org/sophocles/show_mail.tpl?CALLER=index.tpl&source=L&listname=austin-group-l&id=11808
>
> For more details, browse to
> http://www.opengroup.org/austin/aardvark/latest/xshbug3.txt
> and search for Enhancement Request Number 17
>
> in particular, the new wording states that after fflush, "the file offset
> of the underlying open file description shall be set to the file position
> of the stream, and any characters pushed back onto the stream by ungetc()
> or ungetwc() that have not subsequently been read from the stream shall be
> discarded."
Thanks a lot for pursuing this issue until it came to a resolution!!
> We ought to go ahead and reinstate the proper unit tests for these
> behaviors, as well as improve the fflush and other modules (and perhaps
> add an ungetc module) to make this behavior consistent across platforms.
I agree. The appended patch enables two fflush-after-ungetc tests. It
passes on AIX, HP-UX, IRIX, OSF/1, Solaris, but fails on glibc, *BSD,
mingw platforms. More work to be done for these platforms...
2009-01-15 Bruno Haible <address@hidden>
* tests/test-fflush2.sh: Invoke test-fflush2 twice.
* tests/test-fflush2.c (ASSERT): Always fail.
(main): Add two tests for fflush() after ungetc(), taking into account
the Austin Group's clarification.
Suggested by Eric Blake.
*** tests/test-fflush2.c.orig 2009-01-15 12:16:35.000000000 +0100
--- tests/test-fflush2.c 2009-01-15 12:00:16.000000000 +0100
***************
*** 1,5 ****
/* Test of POSIX compatible fflush() function.
! Copyright (C) 2008 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,5 ----
/* Test of POSIX compatible fflush() function.
! Copyright (C) 2008-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
***************
*** 20,28 ****
#include <stdlib.h>
! /* This test can only be made to work on specific platforms. */
! #if defined _IO_ferror_unlocked || defined __sferror /* GNU libc, BeOS;
FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
! # define ASSERT(expr) \
do \
{ \
if (!(expr)) \
--- 20,26 ----
#include <stdlib.h>
! #define ASSERT(expr) \
do \
{ \
if (!(expr)) \
***************
*** 33,89 ****
} \
} \
while (0)
- #else
- # define ASSERT(expr) \
- do \
- { \
- if (!(expr)) \
- { \
- printf ("Skipping test: expected failure on this platform\n"); \
- exit (77); \
- } \
- } \
- while (0)
- #endif
int
main (int argc, char **argv)
{
- #if 0
- /* Check fflush after a backup ungetc() call. This is case 1 in terms of
- <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>.
- The Austin Group has not yet decided how this should behave. */
- #endif
- #if 0
- /* Check fflush after a non-backup ungetc() call. This is case 2 in terms
of
- <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>.
- The Austin Group has not yet decided how this should behave. */
- /* Check that fflush after a non-backup ungetc() call discards the ungetc
- buffer. This is mandated by POSIX
- <http://www.opengroup.org/susv3/functions/ungetc.html>:
- "The value of the file-position indicator for the stream after
- reading or discarding all pushed-back bytes shall be the same
- as it was before the bytes were pushed back." */
int c;
! c = fgetc (stdin);
! ASSERT (c == '#');
! c = fgetc (stdin);
! ASSERT (c == '!');
! /* Here the file-position indicator must be 2. */
! c = ungetc ('@', stdin);
! ASSERT (c == '@');
! fflush (stdin);
! /* Here the file-position indicator must be 2 again. */
! c = fgetc (stdin);
! ASSERT (c == '/');
! #endif
! return 0;
}
--- 31,115 ----
} \
} \
while (0)
int
main (int argc, char **argv)
{
int c;
! if (argc > 1)
! switch (argv[1][0])
! {
! case '1':
! /* Check fflush after a backup ungetc() call. This is case 1a in
! terms of
! <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>,
! according to the Austin Group's resolution on 2009-01-08. */
!
! c = fgetc (stdin);
! ASSERT (c == '#');
!
! c = fgetc (stdin);
! ASSERT (c == '!');
!
! /* Here the file-position indicator must be 2. */
!
! c = ungetc ('!', stdin);
! ASSERT (c == '!');
!
! fflush (stdin);
!
! /* Here the file-position indicator must be 1. */
!
! c = fgetc (stdin);
! ASSERT (c == '!');
!
! c = fgetc (stdin);
! ASSERT (c == '/');
!
! return 0;
!
! case '2':
! /* Check fflush after a non-backup ungetc() call. This is case 2a in
! terms of
! <http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00131.html>,
! according to the Austin Group's resolution on 2009-01-08. */
! /* Check that fflush after a non-backup ungetc() call discards the
! ungetc buffer. This is mandated by POSIX
! <http://www.opengroup.org/susv3/functions/ungetc.html>:
! "The value of the file-position indicator for the stream after
! reading or discarding all pushed-back bytes shall be the same
! as it was before the bytes were pushed back."
! <http://www.opengroup.org/austin/aardvark/latest/xshbug3.txt>
! "[After fflush(),] the file offset of the underlying open file
! description shall be set to the file position of the stream, and
! any characters pushed back onto the stream by ungetc() or
! ungetwc() that have not subsequently been read from the stream
! shall be discarded." */
!
! c = fgetc (stdin);
! ASSERT (c == '#');
!
! c = fgetc (stdin);
! ASSERT (c == '!');
!
! /* Here the file-position indicator must be 2. */
! c = ungetc ('@', stdin);
! ASSERT (c == '@');
! fflush (stdin);
! /* Here the file-position indicator must be 1. */
! c = fgetc (stdin);
! ASSERT (c == '!');
! c = fgetc (stdin);
! ASSERT (c == '/');
! return 0;
! }
! return 1;
}
*** tests/test-fflush2.sh.orig 2009-01-15 12:16:35.000000000 +0100
--- tests/test-fflush2.sh 2009-01-15 11:24:32.000000000 +0100
***************
*** 2,8 ****
# Execute the test only with seekable input stream.
# The behaviour of fflush() on a non-seekable input stream is undefined.
! ./test-fflush2${EXEEXT} < "$srcdir/test-fflush2.sh" || exit $?
#cat "$srcdir/test-fflush2.sh" | ./test-fflush2${EXEEXT} || exit $?
exit 0
--- 2,9 ----
# Execute the test only with seekable input stream.
# The behaviour of fflush() on a non-seekable input stream is undefined.
! ./test-fflush2${EXEEXT} 1 < "$srcdir/test-fflush2.sh" || exit $?
! ./test-fflush2${EXEEXT} 2 < "$srcdir/test-fflush2.sh" || exit $?
#cat "$srcdir/test-fflush2.sh" | ./test-fflush2${EXEEXT} || exit $?
exit 0
Re: Austin group ruling on ungetc vs. fflush, Bruno Haible, 2009/01/15