bug-gnulib
[Top][All Lists]
Advanced

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

Comparing binary files with Diff 3.2 compiled with MinGW


From: Eli Zaretskii
Subject: Comparing binary files with Diff 3.2 compiled with MinGW
Date: Sat, 12 May 2012 19:17:01 +0300

At some point between Diffutils 2.8.7 and 2.9, the code that handles
binary files was removed from io.c.  The changes below resurrect the
correct behavior.  To accomplish this, I needed to add the binary-io
module, and make changes there as well.  Patches are below.

Thanks.

2012-05-12  Eli Zaretskii  <address@hidden>

        * lib/binary-io.h (SET_BINARY) [O_BINARY]: Return the previous mode.
        (UNSET_BINARY): New macro, to reset I/O to text mode.
        (SET_BINARY, UNSET_BINARY): Include _WIN32 in the conditional for
        MS systems.

        * src/io.c: Include binary-io.h.
        (sip, read_files): Switch file I/O to binary mode and back as
        appropriate, to support binary files on systems that distinguish
        between text and binary I/O.


--- src/io.c~0  2011-08-15 08:24:38.000000000 +0300
+++ src/io.c    2012-05-12 18:55:24.201750000 +0300
@@ -22,6 +22,7 @@
 #include <cmpbuf.h>
 #include <file-type.h>
 #include <xalloc.h>
+#include <binary-io.h>
 
 /* Rotate an unsigned value to the left.  */
 #define ROL(v, n) ((v) << (n) | (v) >> (sizeof (v) * CHAR_BIT - (n)))
@@ -110,12 +111,25 @@ sip (struct file_data *current, bool ski
       if (! skip_test)
        {
          /* Check first part of file to see if it's a binary file.  */
-
-         /* FIXME: if O_BINARY, this should revert to text mode
-            if the file is not binary.  */
+         bool binary_file;
+         int prev_mode = SET_BINARY (current->desc);
 
          file_block_read (current, current->bufsize);
-         return binary_file_p (current->buffer, current->buffered);
+         binary_file = binary_file_p (current->buffer, current->buffered);
+         if (prev_mode != O_BINARY)
+           {
+             /* Revert to text mode and seek back to the beginning to
+                reread the file.  Use relative seek, since file
+                descriptors like stdin might not start at offset
+                zero.  */
+
+             if (lseek (current->desc, -current->buffered, SEEK_CUR) == -1)
+               pfatal_with_name (current->name);
+             (void) UNSET_BINARY (current->desc);
+              current->buffered = 0;
+              current->eof = false;
+           }
+         return binary_file;
        }
     }
 
@@ -761,7 +775,8 @@ read_files (struct file_data filevec[], 
     }
   if (appears_binary)
     {
-      /* FIXME: If O_BINARY, this should set both files to binary mode.  */
+      (void) SET_BINARY (filevec[0].desc);
+      (void) SET_BINARY (filevec[1].desc);
       return true;
     }
 
--- lib/binary-io.h~1   2012-05-12 17:31:43.639250000 +0300
+++ lib/binary-io.h     2012-05-12 18:19:53.842375000 +0300
@@ -26,9 +26,14 @@
 #include <stdio.h>
 
 /* SET_BINARY (fd);
-   changes the file descriptor fd to perform binary I/O.  */
+   changes the file descriptor fd to perform binary I/O, returns
+   the previous I/O mode.
+
+   UNSET_BINARY (fd);
+   changes the file descriptor fd to perform text I/O, returns
+   the previous I/O mode. */
 #if O_BINARY
-# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__
+# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__ || defined 
_WIN32
 #  include <io.h> /* declares setmode() */
 # else
 #  define setmode _setmode
@@ -40,13 +45,15 @@
    /* Avoid putting stdin/stdout in binary mode if it is connected to
       the console, because that would make it impossible for the user
       to interrupt the program through Ctrl-C or Ctrl-Break.  */
-#  define SET_BINARY(fd) ((void) (!isatty (fd) ? (setmode (fd, O_BINARY), 0) : 
0))
+#  define SET_BINARY(fd) (!isatty (fd) ? setmode (fd, O_BINARY) : -1)
 # else
-#  define SET_BINARY(fd) ((void) setmode (fd, O_BINARY))
+#  define SET_BINARY(fd) (setmode (fd, O_BINARY))
 # endif
+# define UNSET_BINARY(fd) (setmode (fd, O_TEXT))
 #else
   /* On reasonable systems, binary I/O is the default.  */
-# define SET_BINARY(fd) /* do nothing */ ((void) 0)
+# define SET_BINARY(fd) /* do nothing */ (O_BINARY)
+# define UNSET_BINARY(fd) /* do nothing */ (-1)
 #endif
 
 #endif /* _BINARY_H */



reply via email to

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