2025c zic.c calls fflush(3) on read only file pointer.
Hello, This is undefined behavior. NetBSD returns EOF and sets errno to EBADFD. I am not sure why fflush(3) is called explicitly now, since fclose(3) does it anyway. Best, christos
Looks like this changed recently: https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fflush.html So, I guess this is fine now and NetBSD is broken. Best, christos
On Thu, 18 Dec 2025 at 16:41, Christos Zoulas via tz <tz@iana.org> wrote:
Looks like this changed recently: fflush <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fflus...> pubs.opengroup.org <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fflus...> [image: favicon.ico] <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fflus...> <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fflus...>
So, I guess this is fine now and NetBSD is broken.
It was undefined in POSIX.1-2001: https://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html But well-defined in POSIX.1-2008: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html So "recently" is at least 17 years ago :-)
Thanks for reporting the bug and the POSIX versions. zic should work even on POSIX.1-2001 platforms, so I installed the attached. This should let zic work even on unmodified NetBSD.
does anyone implement the ungetc() part or am i misunderstanding what that's trying to say? #include <stdio.h> int main() { FILE* fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); printf("%c\n", fgetc(fp)); fclose(fp); fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); fflush(fp); printf("%c\n", fgetc(fp)); fclose(fp); return 0; } where this file is /tmp/x.c gives me x and # whether or not the flush is there, for both glibc and macOS. On Thu, Dec 18, 2025 at 12:24 PM Paul Eggert via tz <tz@iana.org> wrote:
Thanks for reporting the bug and the POSIX versions. zic should work even on POSIX.1-2001 platforms, so I installed the attached. This should let zic work even on unmodified NetBSD.
* enh via tz:
does anyone implement the ungetc() part or am i misunderstanding what that's trying to say?
#include <stdio.h> int main() { FILE* fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); printf("%c\n", fgetc(fp)); fclose(fp);
fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); fflush(fp); printf("%c\n", fgetc(fp)); fclose(fp);
return 0; }
where this file is /tmp/x.c gives me x and # whether or not the flush is there, for both glibc and macOS.
Not sure if this is what you mean. We changed glibc fairly recently: commit 377e9733b50ce41e496c467ddcc112f73c88f3bd Author: Joseph Myers <josmyers@redhat.com> Date: Tue Jan 28 19:38:27 2025 +0000 Fix fflush after ungetc on input file (bug 5994) As discussed in bug 5994 (plus duplicates), POSIX requires fflush after ungetc to discard pushed-back characters but preserve the file position indicator. For this purpose, each ungetc decrements the file position indicator by 1; it is unspecified after ungetc at the start of the file, and after ungetwc, so no special handling is needed for either of those cases. This is fixed with appropriate logic in _IO_new_file_sync. I haven't made any attempt to test or change things in this area for the "old" functions; the case of files using mmap is addressed in a subsequent patch (and there seem to be no problems in this area with files opened with fmemopen). Tested for x86_64. Thanks, Florian
On Thu, Dec 18, 2025 at 3:04 PM Florian Weimer <fweimer@redhat.com> wrote:
* enh via tz:
does anyone implement the ungetc() part or am i misunderstanding what that's trying to say?
#include <stdio.h> int main() { FILE* fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); printf("%c\n", fgetc(fp)); fclose(fp);
fp = fopen("/tmp/x.c", "r"); ungetc('x', fp); fflush(fp); printf("%c\n", fgetc(fp)); fclose(fp);
return 0; }
where this file is /tmp/x.c gives me x and # whether or not the flush is there, for both glibc and macOS.
Not sure if this is what you mean. We changed glibc fairly recently:
commit 377e9733b50ce41e496c467ddcc112f73c88f3bd Author: Joseph Myers <josmyers@redhat.com> Date: Tue Jan 28 19:38:27 2025 +0000
ah, i should probably have said "Debian GLIBC 2.41-12+gl0" rather than just "glibc". the test in that sha does look very like my test, even down to the input starting with "#include" :-) presumably yet another case where posix just copied down what solaris did rather than checking what everyone was actually doing.
Fix fflush after ungetc on input file (bug 5994)
As discussed in bug 5994 (plus duplicates), POSIX requires fflush after ungetc to discard pushed-back characters but preserve the file position indicator. For this purpose, each ungetc decrements the file position indicator by 1; it is unspecified after ungetc at the start of the file, and after ungetwc, so no special handling is needed for either of those cases.
This is fixed with appropriate logic in _IO_new_file_sync. I haven't made any attempt to test or change things in this area for the "old" functions; the case of files using mmap is addressed in a subsequent patch (and there seem to be no problems in this area with files opened with fmemopen).
Tested for x86_64.
Thanks, Florian
On 2025-12-18 13:53, enh via tz wrote:
On Thu, Dec 18, 2025 at 3:04 PM Florian Weimer <fweimer@redhat.com> wrote:
* enh via tz:
does anyone implement the ungetc() part or am i misunderstanding what that's trying to say?
Not sure if this is what you mean. We changed glibc fairly recently:
commit 377e9733b50ce41e496c467ddcc112f73c88f3bd Author: Joseph Myers <josmyers@redhat.com> Date: Tue Jan 28 19:38:27 2025 +0000
ah, i should probably have said "Debian GLIBC 2.41-12+gl0" rather than just "glibc".
the test in that sha does look very like my test, even down to the input starting with "#include" :-)
presumably yet another case where posix just copied down what solaris did rather than checking what everyone was actually doing.
From function notes, POSIX originally copied SVID, based on what AT&T and Sun Unix groups found in common between their implementations, as they mostly refer to existing standards, and may lessen or drop requirements if enough other implementations' documentation is available and differ.
Fix fflush after ungetc on input file (bug 5994)
Tested for x86_64.
-- Take care. Thanks, Brian Inglis Calgary, Alberta, Canada
La perfection est atteinte Perfection is achieved non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add mais lorsqu'il n'y a plus rien à retrancher but when there is no more to cut -- Antoine de Saint-Exupéry
participants (6)
-
Brian Inglis -
Christos Zoulas -
enh -
Florian Weimer -
Jonathan Wakely -
Paul Eggert