[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Gnulib's freopen replacement and MinGW
From: |
Bruno Haible |
Subject: |
Re: Gnulib's freopen replacement and MinGW |
Date: |
Mon, 07 May 2012 21:59:45 +0200 |
User-agent: |
KMail/4.7.4 (Linux/3.1.10-1.9-desktop; KDE/4.7.4; x86_64; ; ) |
Hi Eric,
Thank you for digging out the previous threads on this topic.
Eric Blake wrote:
> Waaaay back when, coreutils used to use SET_BINARY. We changed that to
> use freopen(NULL) because of the POSIX wording that allowed NULL to
> change mode, because cygwin honored the mode change, and because Paul
> preferred using a POSIX interface over a complete extension interface.
>
> Commit 8770c00ef, Jul 2005
> https://lists.gnu.org/archive/html/bug-coreutils/2005-07/msg00059.html
>
> Also, at one point, I proposed a patch to xfreopen, to which Bruno
> counterproposed a new API fchangemode() that would alter a FILE* to be
> binary without the baggage of freopen(NULL), although I never really
> pursued it:
>
> https://lists.gnu.org/archive/html/bug-gnulib/2010-03/msg00111.html
>
> Now it looks like we've come full circle, and that the POSIX wording of
> freopen(NULL) is so broken as to not be worth using via gnulib
Yes. Aside the issue with O_TEXT / O_BINARY being out of scope of POSIX,
there is also the issue with the file position. As I understand it,
freopen (NULL, ...) shall - if it succeeds - set the file position back
to 0. Citing POSIX [1]:
"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 file-position
indicator for the stream to the start of the file."
Similarly, for stdin, a successful call to freopen (NULL, "rb", stdin)
must rewind the read-position of stdin to 0. Thus when used in a program
'prog', in the command
{ dd of=/dev/null count=1; prog; } < regular_file
'prog' will start reading from the beginning of regular_file, as if the
dd command was not present. I think this is unintended. Most coreutils
will *just* want to switch to binary mode without rewinding.
So, I continue to be in favour of APIs which don't need to fiddle with
FILE internals and with the file position. Like the proposed [2] fsetbinary()
for O_BINARY, or an fchangemode() that supports at least O_RDONLY, O_WRONLY,
O_RDWR, O_APPEND, O_TEXT, O_BINARY.
Bruno
[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html
[2] https://lists.gnu.org/archive/html/bug-gnulib/2010-03/msg00111.html