We're seeing the following unusual behavior of the program below on Red Hat Advanced Server 4, Update 4: $ cat t.c && gcc t.c && rm -f foo.out && ./a.out > foo.out && ls -l foo.out && du -k foo.out #include <stdio.h> #include <wchar.h> int main () { puts (""); ungetwc ('A', stdout); fwide (stdout, 0); return 0; } -rw-r--r-- 1 sebor devel 182888783729 May 24 16:44 foo.out 16 foo.out The output of strace on the program is in the attached file. Here's info on libc: $ ldd a.out && /lib64/tls/libc.so.6 libc.so.6 => /lib64/tls/libc.so.6 (0x000000381b500000) /lib64/ld-linux-x86-64.so.2 (0x000000381b100000) GNU C Library stable release version 2.3.4, by Roland McGrath et al. Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 3.4.6 20060404 (Red Hat 3.4.6-2). Compiled on a Linux 2.4.20 system on 2006-07-04. Available extensions: GNU libio by Per Bothner crypt add-on version 2.1 by Michael Glad and others Native POSIX Threads Library by Ulrich Drepper et al RT using linux kernel aio The C stubs add-on version 2.1.2. GNU Libidn by Simon Josefsson BIND-8.2.3-T5B NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk Thread-local storage support included. For bug reporting instructions, please see: <http://www.gnu.org/software/libc/bugs.html>.
Created attachment 155405 [details] Output of strace ./a.out >/dev/null 2>/dev/pts/1
This testcase violates ISO C99, 7.19.2(5): "wide character input/output functions shall not be applied to a byte-oriented stream." puts is a byte output function, therefore the stream after puts is byte-oriented. ungetwc is wide input/output function and thus must not be used until you reorient the stream.
I suspected the program was invalid but didn't look carefully enough for where the standard says so. Thanks for taking the time to provide the reference! Even though the program is not valid I thought you might like to know about this type of behavior and consider making a change. I note that Enterprise Linux 5 creates a file of 0 size so it looks like the change may have already been implemented.
Why should we slow all correctly built programs to accomodate an invalid program?