-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Paul Eggert on 5/30/2007 4:46 PM:
> Eric Blake <[EMAIL PROTECTED]> writes:
> 
>> I'm wondering how many of the other coreutils that use this freopen trick 
>> are 
>> affected,
> 
> Five more: head, tac, tail, tee, and tr.

The full list:

cat, cksum, head, md5sum (and thus sha*sum), tac, tail, tee, tr

> 
>> and whether we should use a wrapper function rather than duplicating 
>> all the logic.
> 
> My kneejerk reaction is to duplicate the logic.
> 
> Most likely we'll run into further problems like this, no?  E.g.,
> suppose stdout is open for both read and write, and we use "wb" on it?
> Won't we screw it up?

Nope.  Cygwin's freopen is smart enough to allow any subset of permissions
in the mode argument which are compatible with the underlying permissions
of the fd.  POSIX states that stdout is only open for writing on program
startup, even if the fd is open O_RDWR, so coreutils' existing use of "wb"
is correct modulo append flag.  But even if you do
freopen("file","w+",stdout), a later freopen(NULL,"wb",stdout) is not a
problem.  However, it is a bummer that POSIX states that freopen(NULL) is
implementation defined, so I can only guarantee cygwin's behavior.

I'm wondering if we could just add something like this to the binary-io
module, which we can then update as needed to compensate for any other
irregularities discovered in swapping stdio to binary mode:

/* Make sure FP is in binary mode.  Return FP on success,
   NULL on failure.  */
FILE *
fsetbinary (FILE *fp)
{
#ifdef __CYGWIN__
  int mode = fcntl (fileno (fp), F_GETFL);
  char *str;
  switch (mode & (O_ACCMODE | O_APPEND))
    {
    case O_RDONLY: str = "rb"; break;
    case O_WRONLY: str = "wb"; break;
    case O_RDWR: str = "r+b"; break;
    case O_WRONLY | O_APPEND: str = "ab"; break;
    case O_RDWR | O_APPEND: str = "a+b"; break;
    default: str = NULL;
    }
  if (!str)
    {
      fclose (fp);
      errno = EBADF;
      return NULL;
    }
# ifdef simple
  return freopen (NULL, str, fp);
# else
  fp = freopen (NULL, str, fp);
  if (fp)
    {
      fcntl (fileno (fp), F_SETFL, mode);
    }
  return result;
# endif
#else
  /* I'm not sure how mingw behaves with freopen(NULL,...).  */
  SET_BINARY (fileno (fp));
  return fp;
#endif
}

- --
Don't work too hard, make some time for fun as well!

Eric Blake             [EMAIL PROTECTED]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGXhZn84KuGfSFAYARAuh8AJ9t5fgfL3wSIivp+4SIHzxna59a8gCgxO1D
acSJCXRmeDRJCaxoFyTly1Q=
=z78R
-----END PGP SIGNATURE-----


_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to