[Top][All Lists]

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

Re: cat bug on cygwin

From: Eric Blake
Subject: Re: cat bug on cygwin
Date: Wed, 30 May 2007 18:27:19 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20070221 Thunderbird/ Mnenhy/

Hash: SHA1

According to Paul Eggert on 5/30/2007 4:46 PM:
> Eric Blake <address@hidden> 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.  */
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
  /* I'm not sure how mingw behaves with freopen(NULL,...).  */
  SET_BINARY (fileno (fp));
  return fp;

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

Eric Blake             address@hidden
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


reply via email to

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