Gnulib's freopen replacement and MinGW

Eli Zaretskii <[email protected]>
Newsgroups gmane.comp.gnu.utils.bugs,gmane.comp.lib.gnulib.bugs
Message-ID <[email protected]>
Diffutils 3.2 call xfreopen with its first argument NULL, expecting
the underlying reopen to handle this.  However, the MS runtime does
not implement the Posix semantics of such a call, and so, for example,
MinGW-compiled cmp fails when invoked to compare its stdin with a
file:

  D:\gnu\diffutils-3.2\src>cat cmp.c | cmp cmp.c -
  cmp: failed to reopen `stdin' with mode `rb': No such file or directory

The following change fixes this:

2012-05-05  Eli Zaretskii  <[email protected]>

	* lib/freopen.c [_WIN32]: Include io.h and fcntl.h.
	(rpl_freopen) [_WIN32]: If the first argument is NULL, call
	_setmode to switch STREAM to either binary or text mode, as
	specified by MODE.

--- lib/freopen.c~0	2011-09-02 01:35:11.000000000 +0300
+++ lib/freopen.c	2012-05-05 13:46:36.389000000 +0300
@@ -37,11 +37,23 @@ orig_freopen (const char *filename, cons
 
 #include <string.h>
 
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#include <io.h>
+#include <fcntl.h>
+#endif
+
 FILE *
 rpl_freopen (const char *filename, const char *mode, FILE *stream)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  if (filename != NULL && strcmp (filename, "/dev/null") == 0)
+  if (filename == NULL)
+    {
+      if (strchr (mode, 'b'))
+	return _setmode (_fileno (stream), _O_BINARY) == -1 ? NULL : stream;
+      else
+	return _setmode (_fileno (stream), _O_TEXT) == -1 ? NULL : stream;
+    }
+  else if (strcmp (filename, "/dev/null") == 0)
     filename = "NUL";
 #endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.