2013-02-05  Juan M. Guerrero  <juan.guerrero@gmx.de>

	* lib/mbrtowc.c: If ELOOP is not defined, define it to the value given
	by djdev204's errno.h.


2013-02-03  Juan M. Guerrero  <juan.guerrero@gmx.de>

	* lib/copy-acl.c [__DJGPP__]: Include fcntl.h for _USE_LFN definition.
	(copy_acl) [__DJGPP__]:  If only SFN is available fchmod will fail with
	ENOSYS whhen trying to change the file mode.  In this case do not issue
	the error message.

	* lib/mbrtowc.c: If EILSEQ is not defined, define it to the value given
	by djdev204's errno.h.

	* lib/wcrtomb.c: If EILSEQ is not defined, define it to the value given
	by djdev204's errno.h.

	* lib/set-mode-acl.c [__DJGPP__]: Include fcntl.h for _USE_LFN definition.
	(set_acl) [__DJGPP__]:  If only SFN is available fchmod will fail with
	ENOSYS whhen trying to change the file mode.  In this case do not issue
	the error message.

	* lib/getdelim.c (getdelim) [MSDOS]: For DOS-like systems strip the
	trailing CR.

	* sed/sed.c (main) [SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING]: Set
	system_allow_multiple_cmds in the system_flags variable.
	(main): Strip extension from argv[0].

	* sed/utils.h: Include fcntl.h.
	[_O_BINARY]: Define O_BINARY and setmode if not undefined.
	[O_BINARY]: Include io.h.
	(set_read_mode): Declare a prototype.
	[O_BINARY, __DJGPP__]: New macro STRIP_EXTENSION.  No-op for other
	operation systems.
	[O_BINARY, __DJGPP__]: New macro SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING
	to signal on non POSIX systems where for system() multiple, semicolon
	separated, commands must be explicitly enabled.
	[O_BINARY, __DJGPP__]: Declare the system_flags variable to change
	system() behaviour.
	[O_BINARY, __DJGPP__]: New macro IS_TMPDIR to check that the value
	passed really points to an existing directory to be used as tmpdir.
	For no DJGPP system it defaults to the original sed code check.
	[O_BINARY, __DJGPP__]: New macro IS_SLASH to check if character is a
	directory separator for the particular OS.
	[O_BINARY]: New macro LAST_SLASH defined to check for the last slash or
	backslash as directory separator in the given filename.
	[O_BINARY]: New macro LFN_FILE_SYSTEM to check if the used file system
	supports LFN or only SFN.

	* sed/utils.c [O_BINARY]: Include sys/stat.h and make sure S_ISCHR
	is defined.
	(set_read_mode): New function, switches a stream into binary mode.
	This is a no-op unless O_BINARY is defined.
	(ck_mkstemp) [MSDOS]: Check for the TEMP variable too before defaulting
	to P_tmpdir and test that the used tempdir really does exists before
	starting using it.
        (is_a_device): New function, checks if the file pointer is associated
        to stdout.
	(ck_fwrite) [O_BINARY]: If we are writing to a character device,
	replace every ^Z character with an ASCII string "^Z".
	(follow_symlink): Use IS_SLASH and LAST_SLASH to detect directory
	separator character in the file name.

	* sed/execute.c	(dump_append_queue): Call set_read_mode.
	(dump_append_queue) [O_BINARY]: Remove ^M, if before the newline, and
	^Z, if immediately before EOF.
	(get_backup_file_name) [MSDOS, __DJGPP__]: Use LFN_FILE_SYSTEM to check
	if only SFN support is available.  In that case generate a new and 8+3
	conforming backup file name.
	(open_next_file): Call set_read_mode.  Use LAST_SLASH.
	(closedown): Close files to be renamed before issuing the rename() and
	not after.


2013-02-02  Juan M. Guerrero  <juan.guerrero@gmx.de>

	* lib/fwriting.c [__DJGPP__]: Support fwriting function.

	* lib/stdio-impl.c [__DJGPP__]: Include sys/file.h to provide _IOWRT
	for fwriting function support.

	* doc/sed-in.tex: Add DJGPP port specific info about backup names when
	only SFN supports is available.






diff -aprNU5 sed-4.2.2.orig/doc/sed-in.texi sed-4.2.2/doc/sed-in.texi
--- sed-4.2.2.orig/doc/sed-in.texi	2012-07-25 10:33:08 +0000
+++ sed-4.2.2/doc/sed-in.texi	2013-02-05 22:07:40 +0000
@@ -268,10 +268,31 @@ even to place backup copies of the origi
 directory (provided the directory already exists).
 
 If no extension is supplied, the original file is
 overwritten without making a backup.
 
+For the @acronym{DJGPP} port, if only SFN support is available,
+the backup file name will be truncated to the well known @code{8+3}
+length.  This rule is followed: the suffix will remove as many
+characters as necessary from a potentially existing extension to
+fit into the 3 characters long space available for extensions;
+if a prefix is given, it will shift to the right as many as
+characters are necessary to fit into the 8 characters long space
+available for file names.  As example, the following command:
+
+@example
+sed -ibck_*_up s/foobar/raboof/ filename.txt
+@end example
+
+@noindent
+will produce a backup file for @code{filename.txt} with @code{bck_file._up}
+as backup file name.  As can be seen the suffix @code{_up} is 3
+characters long an overwrites the file name's extension @code{ext}
+completely.  The prefix @code{bck_} is 4 characters long and occupies
+the place of the first 4 characters of the file name, so that the last
+4 characters of the original file name are lost.
+
 @item -l @var{N}
 @itemx --line-length=@var{N}
 @opindex -l
 @opindex --line-length
 @cindex Line length, setting
diff -aprNU5 sed-4.2.2.orig/lib/canonicalize-lgpl.c sed-4.2.2/lib/canonicalize-lgpl.c
--- sed-4.2.2.orig/lib/canonicalize-lgpl.c	2012-12-22 07:22:58 +0000
+++ sed-4.2.2/lib/canonicalize-lgpl.c	2013-02-05 22:08:20 +0000
@@ -18,10 +18,14 @@
 #ifndef _LIBC
 # define _GL_USE_STDLIB_ALLOC 1
 # include <config.h>
 #endif
 
+# ifndef ELOOP
+#  define ELOOP  39  /*  To match the value used in djdev204  */
+# endif
+
 #if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC
 
 /* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
    optimizes away the name == NULL test below.  */
 #define _GL_ARG_NONNULL(params)
diff -aprNU5 sed-4.2.2.orig/lib/copy-acl.c sed-4.2.2/lib/copy-acl.c
--- sed-4.2.2.orig/lib/copy-acl.c	2012-09-13 06:58:18 +0000
+++ sed-4.2.2/lib/copy-acl.c	2013-02-05 22:07:40 +0000
@@ -17,10 +17,14 @@
 
    Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */
 
 #include <config.h>
 
+#if __DJGPP__
+# include <fcntl.h>
+#endif
+
 #include "acl.h"
 
 #include "acl-internal.h"
 
 #include "gettext.h"
@@ -606,10 +610,17 @@ copy_acl (const char *src_name, int sour
     case -2:
       error (0, errno, "%s", quote (src_name));
       break;
 
     case -1:
+#if __DJGPP__
+      /* If only SFN support available, DJGPP's fchmod will fail
+         with ENOSYS.  For DOS/WINDOWS this will not heard, so do
+         not confuse the user by issuing the error message. */
+      if (!_USE_LFN)
+        return 0;
+#endif
       error (0, errno, _("preserving permissions for %s"), quote (dst_name));
       break;
 
     default:
       break;
diff -aprNU5 sed-4.2.2.orig/lib/fwriting.c sed-4.2.2/lib/fwriting.c
--- sed-4.2.2.orig/lib/fwriting.c	2012-09-13 06:58:18 +0000
+++ sed-4.2.2/lib/fwriting.c	2013-02-05 22:07:42 +0000
@@ -31,10 +31,12 @@ fwriting (FILE *fp)
   return (fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) != 0;
 #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */
   return (fp_->_flags & __SWR) != 0;
 #elif defined __EMX__               /* emx+gcc */
   return (fp->_flags & _IOWRT) != 0;
+#elif defined __DJGPP__             /* djgpp */
+  return (fp->_flag & _IOWRT) != 0;
 #elif defined __minix               /* Minix */
   return (fp->_flags & _IOWRITING) != 0;
 #elif defined _IOERR                /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
   return (fp->_flag & _IOWRT) != 0;
 #elif defined __UCLIBC__            /* uClibc */
diff -aprNU5 sed-4.2.2.orig/lib/getdelim.c sed-4.2.2/lib/getdelim.c
--- sed-4.2.2.orig/lib/getdelim.c	2012-03-16 08:30:06 +0000
+++ sed-4.2.2/lib/getdelim.c	2013-02-05 22:07:42 +0000
@@ -123,11 +123,18 @@ getdelim (char **lineptr, size_t *n, int
 
       (*lineptr)[cur_len] = i;
       cur_len++;
 
       if (i == delimiter)
-        break;
+        {
+#ifdef MSDOS
+	  /*  For DOS-like systems strip the trailing CR.  */
+	  if ((i = cur_len - 2) >= 0 && (*lineptr)[i] == '\r')
+	    (*lineptr)[i] = (*lineptr)[--cur_len];
+#endif
+	  break;
+        }
     }
   (*lineptr)[cur_len] = '\0';
   result = cur_len ? cur_len : result;
 
  unlock_return:
diff -aprNU5 sed-4.2.2.orig/lib/mbrtowc.c sed-4.2.2/lib/mbrtowc.c
--- sed-4.2.2.orig/lib/mbrtowc.c	2012-09-13 06:58:18 +0000
+++ sed-4.2.2/lib/mbrtowc.c	2013-02-05 22:07:42 +0000
@@ -15,10 +15,14 @@
    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>
 
+# ifndef EILSEQ
+#  define EILSEQ  41  /*  To match the value used in djdev204  */
+# endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #if GNULIB_defined_mbstate_t
 /* Implement mbrtowc() on top of mbtowc().  */
diff -aprNU5 sed-4.2.2.orig/lib/set-mode-acl.c sed-4.2.2/lib/set-mode-acl.c
--- sed-4.2.2.orig/lib/set-mode-acl.c	2012-12-22 07:22:58 +0000
+++ sed-4.2.2/lib/set-mode-acl.c	2013-02-05 22:07:42 +0000
@@ -17,10 +17,14 @@
 
    Written by Paul Eggert and Andreas Gruenbacher, and Bruno Haible.  */
 
 #include <config.h>
 
+#if __DJGPP__
+# include <fcntl.h>
+#endif
+
 #define ACL_INTERNAL_INLINE _GL_EXTERN_INLINE
 
 #include "acl.h"
 
 #include "acl-internal.h"
@@ -692,8 +696,17 @@ qset_acl (char const *name, int desc, mo
 int
 set_acl (char const *name, int desc, mode_t mode)
 {
   int ret = qset_acl (name, desc, mode);
   if (ret != 0)
-    error (0, errno, _("setting permissions for %s"), quote (name));
+    {
+#if __DJGPP__
+      /* If only SFN support available, DJGPP's fchmod will fail
+         with ENOSYS.  For DOS/WINDOWS this will not heard, so do
+         not confuse the user by issuing the error message. */
+      if (!_USE_LFN)
+        return 0;
+#endif
+      error (0, errno, _("setting permissions for %s"), quote (name));
+    }
   return ret;
 }
diff -aprNU5 sed-4.2.2.orig/lib/stdio-impl.h sed-4.2.2/lib/stdio-impl.h
--- sed-4.2.2.orig/lib/stdio-impl.h	2012-09-13 06:58:18 +0000
+++ sed-4.2.2/lib/stdio-impl.h	2013-02-05 22:07:42 +0000
@@ -22,10 +22,12 @@
 /* BSD stdio derived implementations.  */
 
 #if defined __NetBSD__                         /* NetBSD */
 /* Get __NetBSD_Version__.  */
 # include <sys/param.h>
+#elif defined __DJGPP__
+# include <libc/file.h>
 #endif
 
 #include <errno.h>                             /* For detecting Plan9.  */
 
 #if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */
diff -aprNU5 sed-4.2.2.orig/lib/wcrtomb.c sed-4.2.2/lib/wcrtomb.c
--- sed-4.2.2.orig/lib/wcrtomb.c	2012-03-16 07:52:02 +0000
+++ sed-4.2.2/lib/wcrtomb.c	2013-02-05 22:07:42 +0000
@@ -15,10 +15,14 @@
    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>
 
+#ifndef EILSEQ
+# define EILSEQ  41  /*  To match the value given in djdev204  */
+#endif
+
 /* Specification.  */
 #include <wchar.h>
 
 #include <errno.h>
 #include <stdlib.h>
diff -aprNU5 sed-4.2.2.orig/sed/execute.c sed-4.2.2/sed/execute.c
--- sed-4.2.2.orig/sed/execute.c	2012-03-16 09:13:30 +0000
+++ sed-4.2.2/sed/execute.c	2013-02-05 22:07:42 +0000
@@ -524,12 +524,56 @@ dump_append_queue()
 	     condition."  IEEE Std 1003.2-1992
 	     So, don't fail. */
 	  fp = ck_fopen(p->fname, read_mode, false);
 	  if (fp)
 	    {
+	      set_read_mode(fp);
 	      while ((cnt = ck_fread(buf, 1, sizeof buf, fp)) > 0)
-		ck_fwrite(buf, 1, cnt, output_file.fp);
+		{
+#ifdef O_BINARY
+		  /* Remove CRs from CR-LF pairs, and the trailing ^Z.  */
+		  register char *src = buf, *dest = buf;
+		  register size_t len = cnt;
+
+		  while (len--)
+		    {
+		      if (*src == '\r' || *src == 0x1a)
+			{
+			  if (!len)
+			    {
+			      if (getc(fp) != EOF)
+				{
+				  if (*src == '\r')
+				    {
+				      fseek(fp, -2L, SEEK_CUR);
+				      cnt--;
+				    }
+				  else
+				    {
+				      fseek(fp, -1L, SEEK_CUR);
+				      *dest++ = *src++;
+				    }
+				  break;
+				}
+			      else if (*src == 0x1a)
+				{
+				  cnt--;
+				  break;
+				}
+			    }
+			  else if (src[1] == '\n')
+			    {
+			      src++;
+			      len--;
+			      cnt--;
+			    }
+			}
+		      *dest++ = *src++;
+		    }
+#endif
+		  ck_fwrite(buf, 1, cnt, output_file.fp);
+		}
 	      ck_fclose(fp);
 	    }
 	}
     }
 
@@ -566,10 +610,85 @@ get_backup_file_name(name)
       p += name_length;
     }
 
   /* Tack on what's after the last asterisk */
   strcpy (p, old_asterisk);
+
+#if defined(MSDOS) && defined(__DJGPP__)
+  /* For file systems with limited file name length, like DOS,
+     the backup file name must be truncated to fullfill
+     with these limitations.  Only designed to work with a
+     DOS file system (8+3) */
+  if (!LFN_FILE_SYSTEM(backup) && !LFN_FILE_SYSTEM(name))
+    {
+      char *dot, *sfn_backup, *new_name, *extension, *prefix, *suffix;
+      int length, suffix_length;
+
+      /* Get the extension of the input file name */
+      new_name = xmalloc(name_length + 1);
+      strcpy(new_name, name);
+      if (extension = strrchr(new_name, '.'))
+        {
+          *extension = '\0';
+          extension++;
+        }
+
+      /* Get the prefix and the suffix for the backup file */
+      length = strlen(in_place_extension);
+      prefix = xmalloc(length + 1);
+      strcpy(prefix, in_place_extension);
+      asterisk = strchr(prefix, '*');
+      if (asterisk)
+        {
+          *asterisk = '\0';
+          asterisk++;
+          suffix = strrchr(asterisk, '*');
+          if (!suffix)
+            suffix = asterisk;
+        }
+      else
+        {
+          suffix = prefix;
+          prefix = NULL;
+        }
+      suffix_length = strlen(suffix);
+
+      /* Compute a SFN for the backup file name */
+      sfn_backup = xmalloc(8 + 1 + 3 + 1);
+      if (length = 0, prefix)
+        for (; (sfn_backup[length] = prefix[length]) && (length < 8); length++)
+          ;  /* Copy the prefix into the sfn backup file name */
+      for (backup_length = length, length = 0; (backup_length < 8) && (sfn_backup[backup_length] = new_name[length]); backup_length++, length++)
+        ;  /* Append the input file name to the sfn backup file name */
+      sfn_backup[backup_length++] = '.';
+      if (extension && (suffix_length < 3))
+        {
+          for (length = 0; (sfn_backup[backup_length] = extension[length]) && (length < 3); backup_length++, length++)
+            ;  /* Append the extension of the input file name to the sfn backup file name */
+          if ((suffix_length + length) > 3)
+            {
+              switch (length)
+                {
+                case 2:
+                  backup_length--;
+                  break;
+                case 3:
+                  backup_length -= suffix_length;
+                  break;
+                }
+            }
+        }
+      for (length = 0; (sfn_backup[backup_length] = suffix[length]) && (length < 3); backup_length++, length++)
+        ;  /* Append the suffix to the sfn backup file name */
+      sfn_backup[backup_length] = '\0';
+      xfree(backup);
+      xfree(new_name);
+      xfree(prefix);
+      backup = sfn_backup;
+    }
+#endif  /* MSDOS && __DJGPP__  */
+
   return backup;
 }
 
 /* Initialize a struct input for the named file. */
 static void open_next_file (const char *name, struct input *);
@@ -596,10 +715,12 @@ open_next_file(name, input)
       input->read_fn = read_always_fail; /* a redundancy */
       ++input->bad_count;
       return;
     }
 
+  set_read_mode(input->fp); /* for systems with text/binary schizophrenia */
+
   input->read_fn = read_file_line;
 
   if (follow_symlinks)
     input->in_file_name = follow_symlink (name);
   else
@@ -613,11 +734,11 @@ open_next_file(name, input)
       int reset_fscreatecon = 0;
       memset (&old_fscreatecon, 0, sizeof (old_fscreatecon));
 
       /* get the base name */
       tmpdir = ck_strdup(input->in_file_name);
-      if ((p = strrchr(tmpdir, '/')))
+      if ((p = LAST_SLASH(tmpdir)))
 	*p = 0;
       else
 	strcpy(tmpdir, ".");
 
       if (isatty (fileno (input->fp)))
@@ -685,10 +806,18 @@ closedown(input)
   if (in_place_extension && output_file.fp != NULL)
     {
       const char *target_name;
       int input_fd, output_fd;
 
+      /*
+       *  For DOS/WINDOWS and all other OS with non-POSIX like file systems,
+       *  the file that shall be replaced/renamed by rename() must be closed
+       *  before the rename() call can be issued or the call will fail.
+       */
+      if (input->fp != stdin) /* stdin can be reused on tty and tape devices */
+        ck_fclose(input->fp);
+
       target_name = input->in_file_name;
       input_fd = fileno (input->fp);
       output_fd = fileno (output_file.fp);
 #ifdef HAVE_FCHOWN
       if (fchown (output_fd, input->st.st_uid, input->st.st_gid) == -1)
diff -aprNU5 sed-4.2.2.orig/sed/sed.c sed-4.2.2/sed/sed.c
--- sed-4.2.2.orig/sed/sed.c	2012-03-16 09:13:30 +0000
+++ sed-4.2.2/sed/sed.c	2013-02-05 22:07:42 +0000
@@ -190,11 +190,20 @@ main(argc, argv)
 
   int opt;
   int return_code;
   const char *cols = getenv("COLS");
 
-  program_name = argv[0];
+#if SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING
+  /*
+   *  For some non posix systems where multiple cmds
+   *  separated by semicolon must be explicitly
+   *  enabled before calling system().
+   */
+  system_flags |= system_allow_multiple_cmds;
+#endif
+
+  program_name = STRIP_EXTENSION(argv[0]);
   initialize_main (&argc, &argv);
 #if HAVE_SETLOCALE
   /* Set locale according to user's wishes.  */
   setlocale (LC_ALL, "");
 #endif
diff -aprNU5 sed-4.2.2.orig/sed/utils.c sed-4.2.2/sed/utils.c
--- sed-4.2.2.orig/sed/utils.c	2012-03-16 09:13:30 +0000
+++ sed-4.2.2/sed/utils.c	2013-02-05 22:07:42 +0000
@@ -126,10 +126,25 @@ register_open_file (fp, name, temp)
   p->name = ck_strdup(name);
   p->fp = fp;
   p->temp = false;
 }
 
+void
+set_read_mode (fp)
+  FILE *fp;
+{
+#ifdef O_BINARY
+  /* For systems that distinguish between text and binary files,
+     switch all input streams to binary mode.  This is so we get all
+     the characters from the file, instead of relying on the
+     misfeatures of the C library conversions (e.g., most of them drop
+     lone ^M characters, stop at the first ^Z character, etc.)  */
+  if (!isatty(fileno(fp)))
+    setmode(fileno(fp), O_BINARY);
+#endif
+}
+
 /* Panic on failing fopen */
 FILE *
 ck_fopen(name, mode, fail)
   const char *name;
   const char *mode;
@@ -182,21 +197,31 @@ ck_mkstemp (p_filename, tmpdir, base, mo
   char *template;
   FILE *fp;
   int fd;
   int save_umask;
 
-  if (tmpdir == NULL)
+  if (!IS_TMPDIR(tmpdir))
     tmpdir = getenv("TMPDIR");
-  if (tmpdir == NULL)
+  if (!IS_TMPDIR(tmpdir))
     {
       tmpdir = getenv("TMP");
-      if (tmpdir == NULL)
+      if (!IS_TMPDIR(tmpdir))
+	{
+#ifdef MSDOS
+	  tmpdir = getenv("TEMP");
+	  if (!IS_TMPDIR(tmpdir))
+#endif
 #ifdef P_tmpdir
-	tmpdir = P_tmpdir;
+	    tmpdir = P_tmpdir;
 #else
-	tmpdir = "/tmp";
+# ifdef MSDOS
+	    tmpdir = ".";
+# else
+	    tmpdir = "/tmp";
+# endif
 #endif
+	}
     }
 
   template = xmalloc (strlen (tmpdir) + strlen (base) + 8);
   sprintf (template, "%s/%sXXXXXX", tmpdir, base);
 
@@ -214,23 +239,73 @@ ck_mkstemp (p_filename, tmpdir, base, mo
   fp = fdopen (fd, mode);
   register_open_file (fp, template, true);
   return fp;
 }
 
+#ifdef O_BINARY
+static int stdout_is_a_device;
+
+static int __inline__ is_a_device(FILE *fp);
+static int __inline__
+is_a_device(fp)
+  FILE *fp;
+{
+  struct stat st;
+
+  if (fp == stdout)
+    {
+      /* Warning!  This assumes stdout is never switched during the
+	 program's run!  */
+      if (stdout_is_a_device == -1
+	  && fstat(fileno(stdout), &st) == 0)
+	stdout_is_a_device = S_ISCHR(st.st_mode) != 0;
+      return stdout_is_a_device == 1;
+    }
+  else
+    return fstat(fileno(fp), &st) == 0 && S_ISCHR(st.st_mode);
+}
+#endif
+
 /* Panic on failing fwrite */
 void
 ck_fwrite(ptr, size, nmemb, stream)
   const void *ptr;
   size_t size;
   size_t nmemb;
   FILE *stream;
 {
   clearerr(stream);
-  if (size && fwrite(ptr, size, nmemb, stream) != nmemb)
-    panic(ngettext("couldn't write %d item to %s: %s",
-		   "couldn't write %d items to %s: %s", nmemb), 
-		nmemb, utils_fp_name(stream), strerror(errno));
+#ifdef O_BINARY
+  if (!size)
+    return;
+  if (is_a_device(stream))
+    {
+      char *p;
+      size_t left = nmemb * size;
+
+      /* Text-mode writes to character devices stop at the first ^Z
+	 character.  Repair this lossage.  */
+      while ((p = memchr(ptr, 0x1a, left)) != NULL)
+	{
+	  size_t this_write = p - (char *)ptr;
+
+	  if (fwrite(ptr, 1, this_write, stream) != this_write)
+	    break;
+	  fwrite("^Z", 1, 2, stream);
+	  left -= this_write + 1;
+	  ptr = (char *)ptr + this_write + 1;
+	}
+      if (p == NULL && fwrite(ptr, 1, left, stream) == left)
+	return;
+    }
+  else
+#endif
+  if (!size || fwrite(ptr, size, nmemb, stream) == nmemb)
+    return;
+  panic(ngettext("couldn't write %d item to %s: %s",
+		 "couldn't write %d items to %s: %s", nmemb), 
+	nmemb, utils_fp_name(stream), strerror(errno));
 }
 
 /* Panic on failing fread */
 size_t
 ck_fread(ptr, size, nmemb, stream)
@@ -371,11 +446,11 @@ follow_symlink(const char *fname)
       if (rc < 0)
 	panic (_("couldn't follow symlink %s: %s"), buf, strerror(errno));
       else
 	buf2 [rc] = '\0';
 
-      if (buf2[0] != '/' && (c = strrchr (buf, '/')) != NULL)
+      if (!IS_SLASH (buf2[0]) && LAST_SLASH (buf))
 	{
 	  /* Need to handle relative paths with care.  Reallocate buf1 and
 	     buf2 to be big enough.  */
 	  int len = c - buf + 1;
 	  if (len + rc + 1 > buf_size)
diff -aprNU5 sed-4.2.2.orig/sed/utils.h sed-4.2.2/sed/utils.h
--- sed-4.2.2.orig/sed/utils.h	2012-03-16 09:13:30 +0000
+++ sed-4.2.2/sed/utils.h	2013-02-05 22:07:42 +0000
@@ -18,12 +18,89 @@
 
 #include <stdio.h>
 
 #include "basicdefs.h"
 
+#include <fcntl.h>
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY _O_BINARY
+#  define setmode  _setmode
+# endif
+#endif
+
+#ifdef O_BINARY
+# include <io.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# ifndef S_ISCHR
+#  define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)
+# endif
+# if __DJGPP__
+#  include <crt0.h>
+extern int _crt0_startup_flags;
+#  undef  IS_DIR_SEPARATOR
+#  define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+#  include <libc/unconst.h>
+#  define STRIP_EXTENSION(file_name)                   \
+   (__extension__                                      \
+     ({                                                \
+        char *_begin, *_end;                           \
+        _begin = _end = unconst((file_name), char *);  \
+        while (*_end++)                                \
+          ;                                            \
+        while ((_end - _begin) && (*--_end != '.'))    \
+          ;                                            \
+        if (*_end == '.')                              \
+          *_end = '\0';                                \
+        (file_name);                                   \
+     })                                                \
+   )
+
+   /*
+    *  For some non posix systems where multiple cmds
+    *  separated by semicolon must be explicitly
+    *  enabled before calling system().
+    */
+#  define system_flags   __system_flags
+#  define system_allow_multiple_cmds  __system_allow_multiple_cmds
+#  define SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING  1
+#  define IS_TMPDIR(dirname)                       (!((dirname) == NULL || access((dirname), D_OK)))
+extern int __system_flags;
+
+void xfree (void *ptr);
+# else /*  !__DJGPP__  */
+#  define STRIP_EXTENSION(file_name)               (file_name)
+#  define SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING  0
+#  define IS_TMPDIR(dirname)                       ((dirname) != NULL)
+# endif /*  !__DJGPP__  */
+# define IS_SLASH(C)                               ((C) == '/' || (C) == '\\')
+# define LAST_SLASH(filename)           \
+  ({                                    \
+     char *_pb, *_ps;                   \
+     _pb = strrchr((filename), '\\');   \
+     _ps = strrchr((filename), '/');    \
+     if (!_pb && !_ps)                  \
+       _ps = strrchr((filename), ':');  \
+     else if (_pb > _ps) _ps = _pb;     \
+     _ps;                               \
+  })
+#else /*  !O_BINARY  */
+  /*  posix  */
+# define STRIP_EXTENSION(file_name)                (file_name)
+# define SYSTEM_CALL_NEED_MULTIPLE_CMDS_ENABLING   0
+# define IS_TMPDIR(dirname)                        ((dirname) != NULL)
+# define IS_SLASH(C)                               ((C) == '/')
+# define LAST_SLASH(filename)                      (strrchr((filename), '/'))
+#endif
+
+#define LFN_FILE_SYSTEM(filename)  (pathconf((filename), _PC_NAME_MAX) > 12)
+
+
 void panic (const char *str, ...);
 
+void set_read_mode (FILE *stream);
 FILE *ck_fopen (const char *name, const char *mode, int fail);
 FILE *ck_fdopen (int fd, const char *name, const char *mode, int fail);
 void ck_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream);
 size_t ck_fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
 void ck_fflush (FILE *stream);
