[PATCH 3/6] Make fflush (NULL) flush input files (bug 32369)
DJ Delorie
dj@redhat.com
Wed Jan 15 06:01:10 GMT 2025
I was surprised at the way fwprintf worked, perhaps a comment explaining
that we expect the wide result to be the same as the narrow result
because we expect the wide chars to be converted to multibyte chars?
I'm used to seeing 16-bit unicode in files, and expected to see that
here too...
We don't have a separate test case for when ungetc() triggers this logic
but I don't think that's needed.
LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>
Joseph Myers <josmyers@redhat.com> writes:
> diff --git a/libio/genops.c b/libio/genops.c
> @@ -730,6 +730,13 @@ _IO_flush_all (void)
> )
> && _IO_OVERFLOW (fp, EOF) == EOF)
> result = EOF;
> + if (_IO_fileno (fp) >= 0
> + && ((fp->_mode <= 0 && fp->_IO_read_ptr < fp->_IO_read_end)
> + || (_IO_vtable_offset (fp) == 0
> + && fp->_mode > 0 && (fp->_wide_data->_IO_read_ptr
> + < fp->_wide_data->_IO_read_end)))
> + && _IO_SYNC (fp) != 0)
> + result = EOF;
This checks for read or wide read buffers having data; if we ungetc'd
we'd still evaluate true here. Ok.
> diff --git a/stdio-common/Makefile b/stdio-common/Makefile
> index b5f78c365b..48fbf05a85 100644
> --- a/stdio-common/Makefile
> +++ b/stdio-common/Makefile
> @@ -238,6 +238,7 @@ tests := \
> tst-fdopen \
> tst-fdopen2 \
> tst-ferror \
> + tst-fflush-all-input \
> tst-fgets \
> tst-fgets2 \
> tst-fileno \
Ok.
> diff --git a/stdio-common/tst-fflush-all-input.c b/stdio-common/tst-fflush-all-input.c
> new file mode 100644
> index 0000000000..e9df3a0c08
> --- /dev/null
> +++ b/stdio-common/tst-fflush-all-input.c
> @@ -0,0 +1,53 @@
> +/* Test fflush (NULL) flushes input files (bug 32369).
> + Copyright (C) 2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <wchar.h>
> +
> +#include <support/check.h>
> +#include <support/xstdio.h>
Ok.
> +int
> +do_test (void)
> +{
> + FILE *temp = tmpfile ();
> + TEST_VERIFY_EXIT (temp != NULL);
> + fprintf (temp, "abc");
> + TEST_COMPARE (fflush (temp), 0);
> + TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0);
> + TEST_COMPARE (fgetc (temp), 'a');
> + TEST_COMPARE (fflush (NULL), 0);
> + TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1);
> + xfclose (temp);
Ok.
> + /* Likewise, but in wide mode. */
> + temp = tmpfile ();
> + TEST_VERIFY_EXIT (temp != NULL);
> + fwprintf (temp, L"abc");
> + TEST_COMPARE (fflush (temp), 0);
> + TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0);
> + TEST_COMPARE (fgetwc (temp), L'a');
> + TEST_COMPARE (fflush (NULL), 0);
> + TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1);
Shouldn't this be sizeof(wchar_t), not 1 ? /me tests... no,
fwprintf(L"abc") writes three narrow chars to the file! Needs comment?
Needs specific locale? Are there any locales where we write this out as
a wide char and not a multi-byte char?
> + xfclose (temp);
> +
> + return 0;
> +}
> +
> +#include <support/test-driver.c>
Ok.
More information about the Libc-alpha
mailing list