Jim Meyering <jim <at> meyering.net> writes: > > I am about to use this from diff, so... > BTW, changed license from LGPL in coreutils to GPL here, since > it doesn't make sense to use error-generating code from a library.
xfreopen still doesn't deal with the problem of whether a stream should be reopened in append mode (that is, the difference between "w" and "a", based on whether O_APPEND is set on the underlying fd). This has been the source of a cygwin-specific patch to coreutils for some time now, and a topic that has reoccurred several times on the coreutils mailing list (although I haven't yet been concerned about it enough to push it to the top of my TODO list and actually write the patch). Besides, POSIX 2008 added some wording discouraging the use of freopen to change binary modes: | Since implementations are not required to support any stream mode changes | when the filename argument is NULL, portable applications cannot rely on the | use of freopen( ) to change the stream mode, and use of this feature is | discouraged. The feature was originally added to the ISO C standard in order | to facilitate changing stdin and stdout to binary mode. Since a ’b’ character | in the mode has no effect on POSIX systems, this use of the feature is | unnecessary in POSIX applications. However, even though the ’b’ is ignored, a | successful call to freopen(NULL, "wb", stdout) does have an effect. In | particular, for regular files it truncates the file and sets the fileposition | indicator for the stream to the start of the file. It is possible that these | side-effects are an unintended consequence of the way the feature is | specified in the ISO/IEC 9899: 1999 standard, but unless or until the ISOC | standard is changed, applications which successfully call freopen(NULL, "wb", | stdout) will behave in unexpected ways on conforming systems in situations | such as: | { appl file1; appl file2; } > file3 | which will result in file3 containing only the output from the second | invocation of appl. Paul Eggert originally tried using freopen(NULL) instead of setmode() in coreutils, on the grounds that only the former is standardized; and on the grounds that we care about the FILE* but do not have an idea of whether FILE* carries more state for binary vs. text than just the O_BINARY flag of the underlying fd. But I am really starting to thing that Paul's move to use freopen was the wrong thing to do, and that we should revert back to using the binary-io module from gnulib. All platforms which support a distinction between binary and text support setmode(), even if it is not standardized, and can use that to select binary mode without the portability hassle of freopen. And cygwin goes to great pains to ensure that setmode() on an fd also affects the hidden state of all FILE* visiting that fd. Another idea that I have had is to add a function to binary-io that converts a FILE* from text to binary (right now, binary-io is a bit awkward to use because it requires an fd rather than a FILE*), without the hassles currently associated with portably using freopen(NULL). -- Eric Blake