2012-05-12  Eli Zaretskii  <eliz@gnu.org>

        * 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 __MINGW32__ 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.


2012-05-08  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* src/cmp.c: Include binary-io.h instead of xfreopen.h.
	(main): Use SET_BINARY instead of xfreopen to change file mode to
	O_BINARY.

	* src/diff.c: Include binary-io.h instead of xfreopen.h.
	(main): Use SET_BINARY instead of xfreopen to change file mode to
	O_BINARY.

	* lib/binary-io.h: Added to provide SET_BINARY definition.


2012-05-07  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* lib/cmpbuf.c [SA_RESTART]: Define SA_RESTART to zero if not defined.

	* lib/mbrtowc.c [__DJGPP__]: Define EILSEQ if not defined.

	* lib/mbsrtowcs.c [__DJGPP__]: Define EILSEQ if not defined.

	* lib/open.c [__DJGPP__]: Include "dosname.h" for ISSLASH definition.

	* lib/progname.c [MSDOS]: Define new macro GET_LAST_SLASH to find
	the last directory separator character.  On DOS-like systems these
	are slash, backslash or colon.  For POSIX this is simple a slash.

	* lib/tempname.c: New macro HAVE_DIFFERENT_TMPDIR.  Value depends on
	if the OS is posix or not.
	(direxists): Use ISSLASH to check for the OS dependent directory
	separator character.  Use HAVE_DIFFERENT_TMPDIR to check for TMP and
	TEMP too, if none of them are defined or do not point to an existing
	directory default to the current directory.

	* lib/wcrtomb.c [__DJGPP__]: Define EILSEQ if not defined.

	* src/cmp.c (main): Use CANONICALIZE_PATH to canonicalize the passed
	file names.
	(main): Use STRIP_EXTENSION to strip path and extension from argv[0].

	* src/diff.c (main): Use STRIP_EXTENSION to strip path and extension
	from argv[0].
	(main): Use CANONICALIZE_PATH to canonicalize the passed file names.

	* src/diff3.c (main): Use STRIP_EXTENSION to strip path and extension
	from argv[0].
	(main): Use CANONICALIZE_PATH to canonicalize the passed file names.

	* src/sdiff.c (main): Use CANONICALIZE_PATH to canonicalize the passed
	file names.
	(main): Use STRIP_EXTENSION to strip path and extension from argv[0].
	(temporary_file) [HAVE_LFN_SUPPORT]: Use HAVE_LFN_SUPPORT to determinate
	at run time the temp file pattern to be used.

	* src/system.h [DJGPP]: New macro CANONICALIZE_PATH defined.  For all
	other systems this is a no-ops.
	[DJGPP]: New macros HAVE_LFN_SUPPORT and STRIP_FULL_PATH_AND_EXTENSION
	defined.  For all other systems these are no-ops.
	[SA_RESTART]: Define SA_RESTART to zero if not defined.





diff -aprNU5 diffutils-3.2.orig/lib/binary-io.h diffutils-3.2/lib/binary-io.h
--- diffutils-3.2.orig/lib/binary-io.h	1970-01-01 00:00:00 +0000
+++ diffutils-3.2/lib/binary-io.h	2012-05-12 22:42:32 +0000
@@ -0,0 +1,59 @@
+/* Binary mode I/O.
+   Copyright (C) 2001, 2003, 2005, 2008-2012 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BINARY_H
+#define _BINARY_H
+
+/* For systems that distinguish between text and binary I/O.
+   O_BINARY is guaranteed by the gnulib <fcntl.h>. */
+#include <fcntl.h>
+
+/* The MSVC7 <stdio.h> doesn't like to be included after '#define fileno ...',
+   so we include it here first.  */
+#include <stdio.h>
+
+/* SET_BINARY (fd);
+   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__ || __MINGW32__
+#  include <io.h> /* declares setmode() */
+# else
+#  define setmode _setmode
+#  undef fileno
+#  define fileno _fileno
+# endif
+# ifdef __DJGPP__
+#  include <unistd.h> /* declares isatty() */
+   /* 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) (!isatty (fd) ? setmode (fd, O_BINARY) : -1)
+# else
+#  define SET_BINARY(fd) ((void) 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 */ (O_BINARY)
+# define UNSET_BINARY(fd) /* do nothing */ (-1)
+#endif
+
+#endif /* _BINARY_H */
diff -aprNU5 diffutils-3.2.orig/lib/cmpbuf.c diffutils-3.2/lib/cmpbuf.c
--- diffutils-3.2.orig/lib/cmpbuf.c	2011-01-03 21:08:42 +0000
+++ diffutils-3.2/lib/cmpbuf.c	2012-05-12 22:42:32 +0000
@@ -30,10 +30,14 @@
 
 #ifndef SSIZE_MAX
 # define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
 #endif
 
+#ifndef SA_RESTART
+# define SA_RESTART 0
+#endif
+
 #undef MIN
 #define MIN(a, b) ((a) <= (b) ? (a) : (b))
 
 /* Read NBYTES bytes from descriptor FD into BUF.
    NBYTES must not be SIZE_MAX.
diff -aprNU5 diffutils-3.2.orig/lib/mbrtowc.c diffutils-3.2/lib/mbrtowc.c
--- diffutils-3.2.orig/lib/mbrtowc.c	2011-05-18 18:31:30 +0000
+++ diffutils-3.2/lib/mbrtowc.c	2012-05-12 22:42:32 +0000
@@ -15,10 +15,16 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#if defined(__DJGPP__) && !defined(EILSEQ)
+# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined(__STRICT_ANSI__)
+#   define EILSEQ   41
+# endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
+#endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #if GNULIB_defined_mbstate_t
 /* Implement mbrtowc() on top of mbtowc().  */
diff -aprNU5 diffutils-3.2.orig/lib/mbsrtowcs.c diffutils-3.2/lib/mbsrtowcs.c
--- diffutils-3.2.orig/lib/mbsrtowcs.c	2011-03-26 12:45:44 +0000
+++ diffutils-3.2/lib/mbsrtowcs.c	2012-05-12 22:42:32 +0000
@@ -15,10 +15,16 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#if defined(__DJGPP__) && !defined(EILSEQ)
+# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined(__STRICT_ANSI__)
+#   define EILSEQ   41
+# endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
+#endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #include <errno.h>
 #include <limits.h>
diff -aprNU5 diffutils-3.2.orig/lib/open.c diffutils-3.2/lib/open.c
--- diffutils-3.2.orig/lib/open.c	2011-09-01 22:35:10 +0000
+++ diffutils-3.2/lib/open.c	2012-05-12 22:42:32 +0000
@@ -31,10 +31,14 @@ static inline int
 orig_open (const char *filename, int flags, mode_t mode)
 {
   return open (filename, flags, mode);
 }
 
+#ifdef __DJGPP__
+# include "dosname.h"
+#endif
+
 /* Specification.  */
 #include <fcntl.h>
 
 #include <errno.h>
 #include <stdarg.h>
@@ -103,11 +107,11 @@ open (const char *filename, int flags, .
        - if O_WRONLY or O_RDWR is specified, open() must fail because the
          file does not contain a '.' directory.  */
   if (flags & (O_CREAT | O_WRONLY | O_RDWR))
     {
       size_t len = strlen (filename);
-      if (len > 0 && filename[len - 1] == '/')
+      if (len > 0 && ISSLASH (filename[len - 1]))
         {
           errno = EISDIR;
           return -1;
         }
     }
@@ -154,11 +158,11 @@ open (const char *filename, int flags, .
      with ENOTDIR.  */
   if (fd >= 0)
     {
       /* We know len is positive, since open did not fail with ENOENT.  */
       size_t len = strlen (filename);
-      if (filename[len - 1] == '/')
+      if (ISSLASH (filename[len - 1]))
         {
           struct stat statbuf;
 
           if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
             {
diff -aprNU5 diffutils-3.2.orig/lib/progname.c diffutils-3.2/lib/progname.c
--- diffutils-3.2.orig/lib/progname.c	2011-01-03 21:04:38 +0000
+++ diffutils-3.2/lib/progname.c	2012-05-12 22:42:32 +0000
@@ -25,10 +25,33 @@
 #include <errno.h> /* get program_invocation_name declaration */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+/* MS-DOS and similar non-Posix systems have some peculiarities:
+    - they use both `/' and `\\' as directory separator in file names;
+    - they can have a drive letter X: prepended to a file name;
+   These are all parameterized here.  */
+
+#ifdef MSDOS
+# include <libc/unconst.h>
+# undef  IS_SLASH
+# define IS_SLASH(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# define GET_LAST_SLASH(filename)                  \
+  ({                                               \
+      char *_slash = unconst((filename), char *);  \
+      while (*_slash++)                            \
+        ;                                          \
+      while ((--_slash - (filename)))              \
+        if (IS_SLASH(*_slash))                     \
+          break;                                   \
+      _slash;                                      \
+  })
+#else
+# define GET_LAST_SLASH(filename)  (strrchr((filename), '/'))
+#endif
+
 
 /* String containing name the program is called with.
    To be initialized by main().  */
 const char *program_name = NULL;
 
@@ -54,13 +77,21 @@ set_program_name (const char *argv0)
       fputs ("A NULL argv[0] was passed through an exec system call.\n",
              stderr);
       abort ();
     }
 
-  slash = strrchr (argv0, '/');
+  slash = GET_LAST_SLASH (argv0);
   base = (slash != NULL ? slash + 1 : argv0);
-  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
+  if (base - argv0 >= 7 && (strncmp (base - 7, "/.libs/", 7) == 0
+#ifdef MSDOS
+     || strncmp (base - 7, "\\.libs/", 7) == 0
+     || strncmp (base - 7, "\\.libs\\", 7) == 0
+     || strncmp (base - 7, "/_libs/", 7) == 0
+     || strncmp (base - 7, "\\_libs/", 7) == 0
+     || strncmp (base - 7, "\\_libs\\", 7) == 0
+#endif
+     ))
     {
       argv0 = base;
       if (strncmp (base, "lt-", 3) == 0)
         {
           argv0 = base + 3;
diff -aprNU5 diffutils-3.2.orig/lib/tempname.c diffutils-3.2/lib/tempname.c
--- diffutils-3.2.orig/lib/tempname.c	2011-01-03 21:04:38 +0000
+++ diffutils-3.2/lib/tempname.c	2012-05-12 22:42:32 +0000
@@ -28,10 +28,16 @@
 #include <errno.h>
 #ifndef __set_errno
 # define __set_errno(Val) errno = (Val)
 #endif
 
+#ifdef MSDOS
+# define HAVE_DIFFERENT_TMPDIR  1
+#else
+# define HAVE_DIFFERENT_TMPDIR  0
+#endif
+
 #include <stdio.h>
 #ifndef P_tmpdir
 # define P_tmpdir "/tmp"
 #endif
 #ifndef TMP_MAX
@@ -141,30 +147,41 @@ __path_search (char *tmpl, size_t tmpl_l
   if (try_tmpdir)
     {
       d = __secure_getenv ("TMPDIR");
       if (d != NULL && direxists (d))
         dir = d;
+#if HAVE_DIFFERENT_TMPDIR
+      else if ((d = __secure_getenv ("TMP")) && direxists (d))
+	dir = d;
+      else if ((d = __secure_getenv ("TEMP")) && direxists (d))
+	dir = d;
+#endif
       else if (dir != NULL && direxists (dir))
         /* nothing */ ;
       else
         dir = NULL;
     }
   if (dir == NULL)
     {
       if (direxists (P_tmpdir))
         dir = P_tmpdir;
+#if !HAVE_DIFFERENT_TMPDIR
       else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
         dir = "/tmp";
+#else
+      else if (strcmp (P_tmpdir, ".") != 0 && direxists ("."))
+	dir = "./";
+#endif
       else
         {
           __set_errno (ENOENT);
           return -1;
         }
     }
 
   dlen = strlen (dir);
-  while (dlen > 1 && dir[dlen - 1] == '/')
+  while (dlen > 1 && ISSLASH (dir[dlen - 1]))
     dlen--;                     /* remove trailing slashes */
 
   /* check we have room for "${dir}/${pfx}XXXXXX\0" */
   if (tmpl_len < dlen + 1 + plen + 6 + 1)
     {
diff -aprNU5 diffutils-3.2.orig/lib/wcrtomb.c diffutils-3.2/lib/wcrtomb.c
--- diffutils-3.2.orig/lib/wcrtomb.c	2011-01-03 21:04:38 +0000
+++ diffutils-3.2/lib/wcrtomb.c	2012-05-12 22:42:32 +0000
@@ -15,10 +15,16 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#if defined(__DJGPP__) && !defined(EILSEQ)
+# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined(__STRICT_ANSI__)
+#   define EILSEQ   41
+# endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
+#endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #include <errno.h>
 #include <stdlib.h>
diff -aprNU5 diffutils-3.2.orig/src/cmp.c diffutils-3.2/src/cmp.c
--- diffutils-3.2.orig/src/cmp.c	2011-06-13 07:16:58 +0000
+++ diffutils-3.2/src/cmp.c	2012-05-12 22:42:32 +0000
@@ -31,11 +31,11 @@
 #include <inttostr.h>
 #include <progname.h>
 #include <unlocked-io.h>
 #include <version-etc.h>
 #include <xalloc.h>
-#include <xfreopen.h>
+#include <binary-io.h>
 #include <xstrtol.h>
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "cmp"
 
@@ -207,10 +207,11 @@ main (int argc, char **argv)
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (0);
+  STRIP_EXTENSION(argv[0]);
 
   /* Parse command line options.  */
 
   while ((c = getopt_long (argc, argv, "bci:ln:sv", long_options, 0))
 	 != -1)
@@ -265,10 +266,12 @@ main (int argc, char **argv)
   if (optind == argc)
     try_help ("missing operand after `%s'", argv[argc - 1]);
 
   file[0] = argv[optind++];
   file[1] = optind < argc ? argv[optind++] : "-";
+  CANONICALIZE_PATH(file[0]);
+  CANONICALIZE_PATH(file[1]);
 
   for (f = 0; f < 2 && optind < argc; f++)
     {
       char *arg = argv[optind++];
       specify_ignore_initial (f, &arg, 0);
@@ -291,11 +294,11 @@ main (int argc, char **argv)
 
       if (STREQ (file[f1], "-"))
 	{
 	  file_desc[f1] = STDIN_FILENO;
 	  if (O_BINARY && ! isatty (STDIN_FILENO))
-	    xfreopen (NULL, "rb", stdin);
+	    SET_BINARY (STDIN_FILENO);
 	}
       else
 	file_desc[f1] = open (file[f1], O_RDONLY | O_BINARY, 0);
 
       if (file_desc[f1] < 0 || fstat (file_desc[f1], stat_buf + f1) != 0)
diff -aprNU5 diffutils-3.2.orig/src/diff.c diffutils-3.2/src/diff.c
--- diffutils-3.2.orig/src/diff.c	2011-08-15 05:24:38 +0000
+++ diffutils-3.2/src/diff.c	2012-05-12 22:42:32 +0000
@@ -37,11 +37,11 @@
 #include <sh-quote.h>
 #include <stat-time.h>
 #include <timespec.h>
 #include <version-etc.h>
 #include <xalloc.h>
-#include <xfreopen.h>
+#include <binary-io.h>
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "diff"
 
 #define AUTHORS \
@@ -279,10 +279,11 @@ main (int argc, char **argv)
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (0);
+  STRIP_EXTENSION(argv[0]);
   function_regexp_list.buf = &function_regexp;
   ignore_regexp_list.buf = &ignore_regexp;
   re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING);
   excluded = new_exclude ();
 
@@ -523,11 +524,11 @@ main (int argc, char **argv)
 
 	case BINARY_OPTION:
 #if O_BINARY
 	  binary = true;
 	  if (! isatty (STDOUT_FILENO))
-	    xfreopen (NULL, "wb", stdout);
+	    SET_BINARY (STDOUT_FILENO);
 #endif
 	  break;
 
 	case FROM_FILE_OPTION:
 	  specify_value (&from_file, optarg, "--from-file");
@@ -730,21 +731,21 @@ main (int argc, char **argv)
       if (to_file)
 	fatal ("--from-file and --to-file both specified");
       else
 	for (; optind < argc; optind++)
 	  {
-	    int status = compare_files (NULL, from_file, argv[optind]);
+	    int status = compare_files (NULL, from_file, CANONICALIZE_PATH(argv[optind]));
 	    if (exit_status < status)
 	      exit_status = status;
 	  }
     }
   else
     {
       if (to_file)
 	for (; optind < argc; optind++)
 	  {
-	    int status = compare_files (NULL, argv[optind], to_file);
+	    int status = compare_files (NULL, CANONICALIZE_PATH(argv[optind]), to_file);
 	    if (exit_status < status)
 	      exit_status = status;
 	  }
       else
 	{
@@ -754,10 +755,12 @@ main (int argc, char **argv)
 		try_help ("missing operand after `%s'", argv[argc - 1]);
 	      else
 		try_help ("extra operand `%s'", argv[optind + 2]);
 	    }
 
+	  CANONICALIZE_PATH(argv[optind]);
+	  CANONICALIZE_PATH(argv[optind + 1]);
 	  exit_status = compare_files (NULL, argv[optind], argv[optind + 1]);
 	}
     }
 
   /* Print any messages that were saved up for last.  */
@@ -1106,11 +1109,11 @@ compare_files (struct comparison const *
 	    }
 	  else if (STREQ (cmp.file[f].name, "-"))
 	    {
 	      cmp.file[f].desc = STDIN_FILENO;
 	      if (O_BINARY && binary && ! isatty (STDIN_FILENO))
-		xfreopen (NULL, "rb", stdin);
+		SET_BINARY (STDIN_FILENO);
 	      if (fstat (STDIN_FILENO, &cmp.file[f].stat) != 0)
 		cmp.file[f].desc = ERRNO_ENCODE (errno);
 	      else
 		{
 		  if (S_ISREG (cmp.file[f].stat.st_mode))
diff -aprNU5 diffutils-3.2.orig/src/diff3.c diffutils-3.2/src/diff3.c
--- diffutils-3.2.orig/src/diff3.c	2011-07-03 20:42:54 +0000
+++ diffutils-3.2/src/diff3.c	2012-05-12 22:42:32 +0000
@@ -234,10 +234,11 @@ main (int argc, char **argv)
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (0);
+  STRIP_EXTENSION(argv[0]);
 
   while ((c = getopt_long (argc, argv, "aeimvx3AEL:TX", longopts, 0)) != -1)
     {
       switch (c)
 	{
@@ -321,11 +322,11 @@ main (int argc, char **argv)
     }
 
   file = &argv[optind];
 
   for (i = tag_count; i < 3; i++)
-    tag_strings[i] = file[i];
+    tag_strings[i] = CANONICALIZE_PATH(file[i]);
 
   /* Always compare file1 to file2, even if file2 is "-".
      This is needed for -mAeExX3.  Using the file0 as
      the common file would produce wrong results, because if the
      file0-file1 diffs didn't line up with the file0-file2 diffs
diff -aprNU5 diffutils-3.2.orig/src/io.c diffutils-3.2/src/io.c
--- diffutils-3.2.orig/src/io.c	2011-08-15 05:24:38 +0000
+++ diffutils-3.2/src/io.c	2012-05-12 22:45:40 +0000
@@ -20,10 +20,11 @@
 
 #include "diff.h"
 #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)))
 
 /* Given a hash value and a new character, return a new hash value.  */
@@ -108,16 +109,29 @@ sip (struct file_data *current, bool ski
       current->buffer = xmalloc (current->bufsize);
 
       if (! skip_test)
 	{
 	  /* Check first part of file to see if it's a binary file.  */
+          bool binary_file;
+          int prev_mode = SET_BINARY (current->desc);
 
-	  /* FIXME: if O_BINARY, this should revert to text mode
-	     if the file is not binary.  */
-
-	  file_block_read (current, current->bufsize);
-	  return binary_file_p (current->buffer, current->buffered);
+          file_block_read (current, current->bufsize);
+          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;
 	}
     }
 
   current->buffered = 0;
   current->eof = false;
@@ -759,11 +773,12 @@ read_files (struct file_data filevec[],
       filevec[1].bufsize = filevec[0].bufsize;
       filevec[1].buffered = filevec[0].buffered;
     }
   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;
     }
 
   find_identical_ends (filevec);
 
diff -aprNU5 diffutils-3.2.orig/src/sdiff.c diffutils-3.2/src/sdiff.c
--- diffutils-3.2.orig/src/sdiff.c	2011-08-15 05:24:38 +0000
+++ diffutils-3.2/src/sdiff.c	2012-05-12 22:42:32 +0000
@@ -450,10 +450,11 @@ main (int argc, char *argv[])
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   c_stack_action (cleanup);
+  STRIP_EXTENSION(argv[0]);
 
   prog = getenv ("EDITOR");
   if (prog)
     editor_program = prog;
 
@@ -583,12 +584,12 @@ main (int argc, char *argv[])
       FILE *left, *right, *out, *diffout;
       bool interact_ok;
       struct line_filter lfilt;
       struct line_filter rfilt;
       struct line_filter diff_filt;
-      bool leftdir = diraccess (argv[optind]);
-      bool rightdir = diraccess (argv[optind + 1]);
+      bool leftdir = diraccess (CANONICALIZE_PATH(argv[optind]));
+      bool rightdir = diraccess (CANONICALIZE_PATH(argv[optind + 1]));
 
       if (leftdir & rightdir)
 	fatal ("both files to be compared are directories");
 
       lname = expand_name (argv[optind], leftdir, argv[optind + 1]);
diff -aprNU5 diffutils-3.2.orig/src/system.h diffutils-3.2/src/system.h
--- diffutils-3.2.orig/src/system.h	2011-06-13 07:16:58 +0000
+++ diffutils-3.2/src/system.h	2012-05-12 22:42:32 +0000
@@ -203,5 +203,41 @@ verify (sizeof (lin) <= sizeof (long int
     && (s)->st_mtime == (t)->st_mtime \
     && (s)->st_ctime == (t)->st_ctime)
 #endif
 
 #define STREQ(a, b) (strcmp (a, b) == 0)
+
+#ifndef SA_RESTART
+# define SA_RESTART 0
+#endif
+
+#ifdef __DJGPP__
+# include <libc/unconst.h>
+# define HAVE_LFN_SUPPORT(name)      (pathconf ((name), _PC_NAME_MAX) > 12)
+# define STRIP_EXTENSION(file_name)                  \
+  ({                                                 \
+      char *_begin, *_end;                           \
+      _begin = _end = unconst((file_name), char *);  \
+      while (*_end++)                                \
+        ;                                            \
+      while ((_end - _begin) && (*--_end != '.'))    \
+        ;                                            \
+      if (*_end == '.')                              \
+        *_end = '\0';                                \
+      (file_name);                                   \
+  })
+# define CANONICALIZE_PATH(path)                     \
+  ({                                                 \
+      if ((path))                                    \
+      {                                              \
+        char *_p = unconst((path), char *);          \
+        for (; *_p; _p++)                            \
+          if (*_p == '\\')                           \
+            *_p = '/';                               \
+      }                                              \
+      (path);                                        \
+  })
+#else
+# define HAVE_LFN_SUPPORT(name)      (true)
+# define STRIP_EXTENSION(file_name)
+# define CANONICALIZE_PATH(path)     (path)
+#endif
