bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] xfreopen: keep append mode when converting stdout to binary


From: Bruno Haible
Subject: Re: [PATCH] xfreopen: keep append mode when converting stdout to binary
Date: Thu, 11 Mar 2010 00:43:47 +0100
User-agent: KMail/1.9.9

Hi Eric,

> For a long time, we've had reports against coreutils about improper
> use of freopen(NULL) on platforms with non-zero O_BINARY: basically,
> when built out of the box, things like 'cat a >> b' would overwrite
> data in b, because the freopen(NULL,"wb",stdout) lost the O_APPEND
> flag.

I don't think this functionality belongs in the xfreopen() function.
xfreopen() is defined as freopen() + error checking. Making its semantics
different from the one of freopen() will provoke bugs in some callers
in the future. If someone passes the mode = "wb" argument, he certainly
expects to use the open() flags O_WRONLY|O_CREAT|O_TRUNC, as listed in POSIX
<http://www.opengroup.org/onlinepubs/9699919799/functions/freopen.html>.
No one will understand, when reading code like the one in src/head.c:

  if (O_BINARY && ! isatty (STDOUT_FILENO))
    xfreopen (NULL, "wb", stdout);

that this may use "ab" instead of "wb".

I would find it better to leave xfreopen alone and add a function

  /* Returns the current mode of FP, combined with the additional
     open_flags.  Allowed open_flags are O_APPEND, O_TEXT, O_BINARY,
     or a combination of these.  */
  const char *fgetmode (FILE *fp, int open_flags)

Then src/head.c is changed to:

  if (O_BINARY && ! isatty (STDOUT_FILENO))
    xfreopen (NULL, fgetmode (stdout, O_WRONLY | O_BINARY), stdout);

Or, alternatively, add a new function [x]fchangemode that relies on
[x]freopen:

  /* Changes the mode of FP, but keeping those flags that are set
     in kept_flags and adding flags that are set in added_flags.
     Allowed values for kept_flags and added_flags are O_RDONLY,
     O_WRONLY, O_RDWR, O_APPEND, O_TEXT, O_BINARY, or a combination of
     these.  */
  void fchangemode (FILE *fp, int kept_flags, int added_flags);

Then change src/head.c to read:

  if (O_BINARY && ! isatty (STDOUT_FILENO))
    xfchangemode (stdout, O_APPEND, O_WRONLY | O_BINARY);

Note how this is different from freopen: freopen (NULL, "wb", stdout)
would be equivalent to
    fchangemode (stdout, 0, O_WRONLY | O_BINARY);

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]