Chet Ramey wrote: > That's a dangerous assumption. You can't always assume that fflush will > succeed. And when it fails, newer versions of glibc leave data in the > stdio buffer. Now, the assumption is that when fflush fails, it fails > due to some problem with the underlying file descriptor, and, further, > that that file descriptor will never change or repair itself. Under > those conditions, it's ok for stdio/fflush to leave the data. > > However, bash will change the file descriptor underlying a stdio buffer > when it performs redirection. In that case, subsequent writes will > succeed, and those writes will include the data left by the previous > failed fflush. > > When bash changes file descriptors, it needs to make sure that the > stdio buffers are empty. I chose to use fflush for this purpose > (reluctantly), even though it's less than completely portable. There > aren't any good portable solutions for the issue.
Thanks for explaining. I think an alternative for bash would be to temporarily set the file descriptor to point to /dev/null and do a second fflush. Like this (error checking omitted): FILE *fp = ... /* stdout or stderr */; if (fflush (fp) < 0) { #if GNULIB_PROVIDES_FPURGE fpurge (fp); #else int fd = fileno (fp); int saved_fd = dup (fd); int sink_fd = open ("/dev/null", O_WRONLY); dup2 (sink_fd, fd); fflush (fp); close (sink_fd); dup2 (saved_fd, fd); close (saved_fd); #endif } Unfortunately, it's hard to incorporate this portability fallback in gnulib because fpurge should also work on input streams and should set back the file position on output streams. Bruno