Hi Stephane, On Mon, Sep 10, 2007 at 09:08:33AM +0100, Stephane Chazelas wrote: > thanks for replying, I gave a list in another email. I tried on > Solaris 7 and HPUX and both seem to flush the buffer upon an > unsuccessful fflush()
I see... I wonder how they work in regard of my original problem described in the Bug#429021, because it is possible to not discard data when write failed, but still clean buffer in fflush(). So, functions like fwrite, printf will not lose some previously written data on error, but fflush() will always have a clean output buffer at return, so it will not break existing software, which use dup2 trick. > On the other end, how would you force the flush of the buffer? The flush means to _deliver_ data, which is impossible in this case. > And how would you redirect stdout? We can use freopen() instead > of the hack above for files, but not for pipes or arbitrary fds > (as in >&3). I see... POSIX has fdopen to create a stream based on the existing file descriptor, but there is no function to change an existing stream like 'stdout'. So, I don't know any other portable solution except avoiding 'stdout'. For some implementations, you can just assign any FILE pointer to stdout like this: FILE* out = fdopen(fd, mode); if (out != NULL) { fclose(stdout); stdout = out; } else report_error(); but in general it does not work, because stdout is rvalue. > Erik Blake was suggesting to use freopen(NULL) (not > to fix that very problem but because of the fact that if you > reassign stdout to some resource of a different nature, you need > to tell stdio as stdio may need to operate differently), but > that's not very portable according to POSIX. Would freopen(NULL) > flush the output buffer? In Glibc, freopen: if (filename == NULL && _IO_fileno (fp) >= 0) { fd = __dup (_IO_fileno (fp)); if (fd != -1) filename = fd_to_filename (fd); } Then it closes, the original stream and opens a new one in the same place. So I believe it should work with glibc provided you do that you called it after dup2 and that your system have /proc, because fd_to_filename relies on it. freopen in newlib does not do anything special about NULL, so I believe it does not work with NULL. Perhaps, freopen("/dev/stdout") is a more portable way to do what you want. Regards, Dmitry