2010-01-04  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* lib/pipe.c [__DJGPP__]: Quick and dirty' DJGPP specific
	implementation of create_pipe.  Only usefull for this port.

	* lib/wait-subprocess.c [__DJGPP__]: Include djgpp-spawn.h.
	Quick and dirty' DJGPP specific implementation of wait_subprocess.
	Removes the tmp files used to implement the pipe.  Only usefull for
	this port.

	* lib/djgpp-spawn.h: New file.


2009-12-30  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* lib/execute.c [__DJGPP__]: DJGPP specific implementation of execute.

	* lib/spawni.c [__DJGPP__]: DJGPP specific implementation of __spawni.
	Still not implemented; returns ENOSYS.


2009-12-01  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/builtin.c (m4_syscmd, m4_esyscmd): For MSDOS allow command.com
	as shell as well.


2009-11-23  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/output.c (make_room_for): Added SET_BINARY. On systems
	that distinguish between text and binary files, tmpfiles are
	opened in binary mode. For all others OS it is a no-op macro.
	Now the SET_BINARY macro is defined by gnulib in /lib/binary-io.h
	and expects a file descriptor as argument.

	* src/path.c (include_env_init): If FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
	is defined check the enironment variable PATH_SEPARATOR to determiante
	the path separator character to be used.  For posix systems the default
	is colon, for DOS/DJGPP the default is semi colon.
	Use CANONICALIZE_PATH to replace DOS-style backslash directory separator
	to unix-style slash directory separtor.

	* src/m4.h: Added FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX. This macro
	is used to define a serie of macros to parametrize OS specific issues
	like path separators, directory separators, drive letters, etc.
	New macro DOSISH to define a canonical recognition macro for
	MSDOS and DJGPP.  For DJGPP also define UNIX.

	* src/m4.c: If SA_NODEFER and SA_RESETHAND are not undefined define
	them to 0.
	(usage) [__DJGPP__]: Add DJGPP specific info about M4PATH.

	* src/builtin.c: Add MSDOS and DJGPP to the supported platform macros
	list.

	* lib/tmpdir.c: New macro HAVE_ALTERNATE_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_ALTERNATE_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/tempname.c: New macro HAVE_ALTERNATE_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_ALTERNATE_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/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/open.c (open): Use ISSLASH to check for the OS dependent
	directory separator character.

	* lib/mkstemp-safer.c [__DJGPP__]: Define macro __need_FILE so that
	libc's stdio.h is included and not the gnulib one that does not
	provide the mkstemp prototype.
	[__DJGPP__]: For djdev203 include <stdio.h> for mkstemp declaration.

	* lib/fseeko.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/freadahead.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/freading.c [__DJGPP__]: Include libc/file.h for the definition
	of _IOERR so that SystemV derived implementations, defined in stdio-impl.h,
	are selected for DJGPP.

	* lib/fopen.c (rpl_fopen): Use ISSLASH to check for the OS dependent
	directory separator character.

	* lib/fatal-signal.c: If SA_NODEFER is undefined define it to 0.
	[__DJGPP__]: New macro SIGNAL_INDEX used to adjust the signal numbers
	used by DJGPP to fit into the range of saved_sigactions.
	(uninstall_handlers): Use SIGNAL_INDEX to access saved_sigactions.
	(install_handlers): Use SIGNAL_INDEX to access saved_sigactions.

	* lib/cloexec.c (set_cloexec_flag) [!MSDOS]: On MSDOS/Windows
	systems always return success.

	* doc/m4.texinfo: Add DJGPP specific info about place where the tmp
	files are stored.
	Add (ENOENT) to error message.
	Add DJGPP specific info about supported M4PATH path separator characters.
	Adjust different tests to DJGPP peculiarities.








diff -aprNU5 m4-1.4.13.orig/doc/m4.texinfo m4-1.4.13/doc/m4.texinfo
--- m4-1.4.13.orig/doc/m4.texinfo	2009-03-05 12:46:00 +0000
+++ m4-1.4.13/doc/m4.texinfo	2010-01-08 20:35:44 +0000
@@ -4948,14 +4948,14 @@ parameters.
 @end deffn
 
 @comment status: 1
 @example
 include(`none')
-@error{}m4:stdin:1: cannot open `none': No such file or directory
+@error{}m4:stdin:1: cannot open `none': No such file or directory (ENOENT)
 @result{}
 include()
-@error{}m4:stdin:2: cannot open `': No such file or directory
+@error{}m4:stdin:2: cannot open `': No such file or directory (ENOENT)
 @result{}
 sinclude(`none')
 @result{}
 sinclude()
 @result{}
@@ -5074,10 +5074,19 @@ directory.  Next comes the directories s
 @option{--include} or @option{-I} option, in the order found on the
 command line.  Finally, if the @env{M4PATH} environment variable is set,
 it is expected to contain a colon-separated list of directories, which
 will be searched in order.
 
+For the @acronym{DJGPP} port of @code{m4} the @env{M4PATH} environment variable
+points to either a semicolon-separted (default) or colon-separated list of
+directories.  The character to be used as path separator will be determinated
+by the value of the @env{PATH_SEPARATOR} environment variable.  If the variable
+is not set or set to @samp{;}, then the directory list must be a semicolon-separted
+list; if @env{PATH_SEPARATOR} is set to @samp{:}, then the directory list must be a
+colon-separted list.  In both cases the @acronym{DJGPP} specific syntax for drive
+letter prefix, e.g.: @samp{c:} is equivalent to @samp{/dev/c}, is supported.
+
 If the automatic search for include-files causes trouble, the @samp{p}
 debug flag (@pxref{Debug Levels}) can help isolate the problem.
 
 @node Diversions
 @chapter Diverting and undiverting output
@@ -5097,10 +5106,15 @@ limit to the overall memory usable by al
 (512K, currently).  When this maximum is about to be exceeded,
 a temporary file is opened to receive the contents of the biggest
 diversion still in memory, freeing this memory for other diversions.
 When creating the temporary file, @code{m4} honors the value of the
 environment variable @env{TMPDIR}, and falls back to @file{/tmp}.
+The @acronym{DJGPP} port of @acronym{GNU} @code{m4} also honors the
+value of the environment variables @env{TMP} and @env{TEMP}, in that
+order, if @env{TMPDIR} is not defined or points to a not existing
+directory, and falls back to the value of @code{P_tmpdir}.  If this also
+fails then it falls back to @file{./}.
 So, it is theoretically possible that the number and aggregate size of
 diversions is limited only by available disk space.
 
 @ignore
 @comment We need to test spilled diversions, but don't need to expose
@@ -6395,10 +6409,14 @@ Sometimes it is desirable for an input f
 @code{m4} is running on.  @acronym{GNU} @code{m4} provides several
 macros that are predefined to expand to the empty string; checking for
 their existence will confirm platform details.
 
 @deffn {Optional builtin} __gnu__
+@deffnx {Optional builtin} __djgpp__
+@deffnx {Optional builtin} djgpp
+@deffnx {Optional builtin} __msdos__
+@deffnx {Optional builtin} msdos
 @deffnx {Optional builtin} __os2__
 @deffnx {Optional builtin} os2
 @deffnx {Optional builtin} __unix__
 @deffnx {Optional builtin} unix
 @deffnx {Optional builtin} __windows__
@@ -6443,10 +6461,14 @@ On native Windows systems, @acronym{GNU}
 @option{-G} option is specified.
 
 On OS/2 systems, @acronym{GNU} @code{m4} will define @code{@w{__os2__}}
 by default, or @code{os2} when the @option{-G} option is specified.
 
+On MSDOS/DJGPP systems, @acronym{GNU} @code{m4} will define @code{@w{__djgpp__}},
+@code{@w{__msdos__}} and @code{@w{__unix__}} by default, or @code{djgpp}, @code{msdos}
+and @code{unix} when the @option{-G} option is specified.
+
 If @acronym{GNU} @code{m4} does not provide a platform macro for your system,
 please report that as a bug.
 
 @example
 define(`provided', `0')
@@ -6455,12 +6477,16 @@ ifdef(`__unix__', `define(`provided', in
 @result{}
 ifdef(`__windows__', `define(`provided', incr(provided))')
 @result{}
 ifdef(`__os2__', `define(`provided', incr(provided))')
 @result{}
+ifdef(`__djgpp__', `define(`provided', incr(provided))')
+@result{}
+ifdef(`__msdos__', `define(`provided', incr(provided))')
+@result{}
 provided
-@result{}1
+@result{}3
 @end example
 
 @node Syscmd
 @section Executing simple commands
 
@@ -6775,12 +6801,12 @@ sysval
 @example
 syscmd(`rm -rf foodir')sysval
 @result{}0
 syscmd(`mkdir foodir')sysval
 @result{}0
-len(mkstemp(`foodir/fooXXXXX'))
-@result{}16
+len(mkstemp(`foodir/foXXXXX'))
+@result{}15
 syscmd(`rm -r foodir')sysval
 @result{}0
 @end example
 
 @c Likewise, and ensure that traditional mode leaves the result unquoted
@@ -7149,11 +7175,11 @@ syscmd([echo 'changequote([,])pushdef([d
 @comment xerr: ignore
 @comment status: 1
 @example
 $ @kbd{m4 -F /none/such}
 ^D
-@error{}m4: cannot open `/none/such': No such file or directory
+@error{}m4: cannot open `/none/such': No such file or directory (ENOENT)
 @end example
 @end ignore
 
 When an @code{m4} run is to be frozen, the automatic undiversion
 which takes place at end of execution is inhibited.  Instead, all
diff -aprNU5 m4-1.4.13.orig/lib/cloexec.c m4-1.4.13/lib/cloexec.c
--- m4-1.4.13.orig/lib/cloexec.c	2008-02-23 17:29:36 +0000
+++ m4-1.4.13/lib/cloexec.c	2010-01-08 20:30:48 +0000
@@ -33,11 +33,19 @@
    Return 0 on success, or -1 on error with `errno' set. */
 
 int
 set_cloexec_flag (int desc, bool value)
 {
-#if defined F_GETFD && defined F_SETFD
+#if defined F_GETFD && defined F_SETFD && !defined MSDOS
+/*
+ *  On MSDOS/Windows DJGPP 2.03 always returns 0 for the handles
+ *  below 18 and FD_CLOEXEC for 19 and 20.
+ *  To avoid error messages like:
+ *    Warning: cannot protect input file across forks: Function not implemented (ENOSYS)
+ *  this function call returns always success.  This will not hurd because MSDOS/Windows
+ *  has no fork functionality at all.
+ */
 
   int flags = fcntl (desc, F_GETFD, 0);
 
   if (0 <= flags)
     {
diff -aprNU5 m4-1.4.13.orig/lib/djgpp-spawn.h m4-1.4.13/lib/djgpp-spawn.h
--- m4-1.4.13.orig/lib/djgpp-spawn.h	1970-01-01 00:00:00 +0000
+++ m4-1.4.13/lib/djgpp-spawn.h	2010-01-08 20:30:48 +0000
@@ -0,0 +1,80 @@
+#include "xalloc.h"
+
+#define prepare_spawn(argv)                                       \
+({                                                                \
+   size_t _argc;                                                  \
+   char **_new_argv;                                              \
+                                                                  \
+   for (_argc = 0; (argv)[_argc]; _argc++)                        \
+     ;                                                            \
+                                                                  \
+   _new_argv = xmalloc ((1 + _argc + 1) * sizeof(_new_argv[0]));  \
+   *_new_argv++ = "/dev/env/DJDIR/bin/sh";                        \
+                                                                  \
+   for (_argc = 0; _new_argv[_argc] = argv[_argc]; _argc++)       \
+     ;                                                            \
+                                                                  \
+   _new_argv;                                                     \
+})
+
+
+#define PIPE_STDIN   0
+#define PIPE_STDOUT  1
+
+
+char tmp_file_name[2][L_tmpnam];  /*  0: pipe stdin, 1: pipe stdout.  */
+
+
+#define remove_tmp_file(name)                                               \
+ do {                                                                       \
+   if ((name))                                                              \
+   {                                                                        \
+     if (unlink ((name)))                                                   \
+       error (exit_on_error ? EXIT_FAILURE : 0, errno,                      \
+              _("removing of `%s' failed"), (name));                        \
+   }                                                                        \
+   else                                                                     \
+   {                                                                        \
+     if (tmp_file_name[PIPE_STDIN][0])                                      \
+     {                                                                      \
+       if (unlink (tmp_file_name[PIPE_STDIN]))                              \
+         error (exit_on_error ? EXIT_FAILURE : 0, errno,                    \
+                _("removing of `%s' failed"), tmp_file_name[PIPE_STDIN]);   \
+     }                                                                      \
+     if (tmp_file_name[PIPE_STDOUT][0])                                     \
+     {                                                                      \
+       if (unlink (tmp_file_name[PIPE_STDOUT]))                             \
+         error (exit_on_error ? EXIT_FAILURE : 0, errno,                    \
+                _("removing of `%s' failed"), tmp_file_name[PIPE_STDOUT]);  \
+     }                                                                      \
+   }                                                                        \
+ } while (0)
+
+
+#ifdef _PIPE_H
+static int
+_pipe(int pipe_fd[2], int pipe_end)
+{
+  int fd;
+
+  strcpy (tmp_file_name[pipe_end], "/dev/env/TMPDIR/m4XXXXXX");
+  fd = mkstemp (tmp_file_name[pipe_end]);
+  if (fd < 0)
+    return -1;
+
+  if (pipe_end == PIPE_STDIN)
+  {
+    pipe_fd[PIPE_STDIN] = fd;
+    pipe_fd[PIPE_STDOUT] = -1;
+    tmp_file_name[PIPE_STDOUT][0] = '\0';
+  }
+  else if (pipe_end == PIPE_STDOUT)
+  {
+    pipe_fd[PIPE_STDOUT] = fd;
+    pipe_fd[PIPE_STDIN] = -1;
+    tmp_file_name[PIPE_STDIN][0] = '\0';
+  }
+
+  return 0;
+}
+#endif
diff -aprNU5 m4-1.4.13.orig/lib/execute.c m4-1.4.13/lib/execute.c
--- m4-1.4.13.orig/lib/execute.c	2009-03-09 02:14:32 +0000
+++ m4-1.4.13/lib/execute.c	2010-01-08 20:30:48 +0000
@@ -39,10 +39,16 @@
 
 /* Native Woe32 API.  */
 # include <process.h>
 # include "w32spawn.h"
 
+#elif defined __DJGPP__
+
+/* DJGPP API.  */
+# include <process.h>
+# include "djgpp-spawn.h"
+
 #else
 
 /* Unix API.  */
 # include <spawn.h>
 
@@ -190,10 +196,100 @@ execute (const char *progname,
       return 127;
     }
 
   return exitcode;
 
+#elif defined __DJGPP__
+
+  int orig_stdin;
+  int orig_stdout;
+  int orig_stderr;
+  int exitcode;
+  int nullinfd;
+  int nulloutfd;
+
+  /* Add an element upfront that can be used when argv[0] turns out to be a
+     script, not a program.  */
+  char **new_prog_argv = prepare_spawn (prog_argv);
+
+  /* Save standard file handles of parent process.  */
+  if (null_stdin)
+    if ((orig_stdin = dup (STDIN_FILENO)) < 0)
+      error (EXIT_FAILURE, errno, _("dup for STDIN failed"));
+  if (null_stdout)
+    if ((orig_stdout = dup (STDOUT_FILENO)) < 0)
+      error (EXIT_FAILURE, errno, _("dup for STDOUT failed"));
+  if (null_stderr)
+    if ((orig_stderr = dup (STDERR_FILENO)) < 0)
+      error (EXIT_FAILURE, errno, _("dup for STDERR failed"));
+  exitcode = -1;
+
+  /* Create standard file handles of child process.  */
+  nullinfd = -1;
+  nulloutfd = -1;
+  if ((!null_stdin
+       || ((nullinfd = open ("/dev/null", O_RDONLY|O_BINARY, 0)) >= 0
+           && (nullinfd == STDIN_FILENO
+               || (dup2 (nullinfd, STDIN_FILENO) >= 0
+                   && close (nullinfd) >= 0))))
+      && (!(null_stdout || null_stderr)
+          || ((nulloutfd = open ("/dev/null", O_RDWR|O_BINARY, 0)) >= 0
+              && (!null_stdout
+                  || nulloutfd == STDOUT_FILENO
+                  || dup2 (nulloutfd, STDOUT_FILENO) >= 0)
+              && (!null_stderr
+                  || nulloutfd == STDERR_FILENO
+                  || dup2 (nulloutfd, STDERR_FILENO) >= 0)
+              && ((null_stdout && nulloutfd == STDOUT_FILENO)
+                  || (null_stderr && nulloutfd == STDERR_FILENO)
+                  || close (nulloutfd) >= 0))))
+    /* Use spawnvpe and pass the environment explicitly.  This is needed if
+       the program has modified the environment using putenv() or [un]setenv().
+       On Windows, programs have two environments, one in the "environment
+       block" of the process and managed through SetEnvironmentVariable(), and
+       one inside the process, in the location retrieved by the 'environ'
+       macro.  When using spawnvp() without 'e', the child process inherits a
+       copy of the environment block - ignoring the effects of putenv() and
+       [un]setenv().  */
+    {
+      exitcode = spawnvpe (P_WAIT, prog_path, new_prog_argv, environ);
+      if (--new_prog_argv, exitcode < 0 && errno == ENOEXEC)
+        {
+          /* prog is not an native executable.  Try to execute it as a
+             shell script.  Note that prepare_spawn() has already prepended
+             a hidden element "/dev/env/DJDIR/bin/sh" to new_prog_argv.  */
+          exitcode = spawnvpe (P_WAIT, new_prog_argv[0], new_prog_argv, environ);
+        }
+      free (new_prog_argv);
+    }
+  if (nulloutfd >= 0)
+    close (nulloutfd);
+  if (nullinfd >= 0)
+    close (nullinfd);
+
+  /* Restore standard file handles of parent process.  */
+  if (null_stderr)
+    dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
+  if (null_stdout)
+    dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
+  if (null_stdin)
+    dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
+
+  if (termsigp != NULL)
+    *termsigp = 0;
+
+  if (exitcode == -1)
+    {
+      if (exit_on_error || !null_stderr)
+        error (exit_on_error ? EXIT_FAILURE : 0, errno,
+               _("%s subprocess failed"), progname);
+      return 127;
+    }
+
+  return exitcode;
+
+
 #else
 
   /* Unix API.  */
   /* Note about 127: Some errors during posix_spawnp() cause the function
      posix_spawnp() to return an error code; some other errors cause the
diff -aprNU5 m4-1.4.13.orig/lib/fatal-signal.c m4-1.4.13/lib/fatal-signal.c
--- m4-1.4.13.orig/lib/fatal-signal.c	2008-08-31 19:47:54 +0000
+++ m4-1.4.13/lib/fatal-signal.c	2010-01-08 20:30:48 +0000
@@ -24,10 +24,14 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
 
+#ifndef SA_NODEFER
+# define SA_NODEFER  0
+#endif
+
 #include "sig-handler.h"
 #include "xalloc.h"
 
 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
 
@@ -123,10 +127,18 @@ static actions_entry_t static_actions[32
 static actions_entry_t * volatile actions = static_actions;
 static sig_atomic_t volatile actions_count = 0;
 static size_t actions_allocated = SIZEOF (static_actions);
 
 
+#if __DJGPP__
+/* The saved signal handlers.
+   Size 32 would not be sufficient: On DJGPP, signals start at SIGABRT = 288 and go until SIGUSR2 = 300.
+   Make it fit into the given size of 64  */
+# define SIGNAL_INDEX(signal)  ((signal) % 288)
+#else
+# define SIGNAL_INDEX(signal)  (signal)
+#endif
 /* The saved signal handlers.
    Size 32 would not be sufficient: On HP-UX, SIGXCPU = 33, SIGXFSZ = 34.  */
 static struct sigaction saved_sigactions[64];
 
 
@@ -138,13 +150,13 @@ uninstall_handlers ()
 
   for (i = 0; i < num_fatal_signals; i++)
     if (fatal_signals[i] >= 0)
       {
 	int sig = fatal_signals[i];
-	if (saved_sigactions[sig].sa_handler == SIG_IGN)
-	  saved_sigactions[sig].sa_handler = SIG_DFL;
-	sigaction (sig, &saved_sigactions[sig], NULL);
+	if (saved_sigactions[SIGNAL_INDEX(sig)].sa_handler == SIG_IGN)
+	  saved_sigactions[SIGNAL_INDEX(sig)].sa_handler = SIG_DFL;
+	sigaction (sig, &saved_sigactions[SIGNAL_INDEX(sig)], NULL);
       }
 }
 
 
 /* The signal handler.  It gets called asynchronously.  */
@@ -191,13 +203,13 @@ install_handlers ()
   for (i = 0; i < num_fatal_signals; i++)
     if (fatal_signals[i] >= 0)
       {
 	int sig = fatal_signals[i];
 
-	if (!(sig < sizeof (saved_sigactions) / sizeof (saved_sigactions[0])))
+	if (!(SIGNAL_INDEX(sig) < sizeof (saved_sigactions) / sizeof (saved_sigactions[0])))
 	  abort ();
-	sigaction (sig, &action, &saved_sigactions[sig]);
+	sigaction (sig, &action, &saved_sigactions[SIGNAL_INDEX(sig)]);
       }
 }
 
 
 /* Register a cleanup function to be executed when a catchable fatal signal
diff -aprNU5 m4-1.4.13.orig/lib/fopen.c m4-1.4.13/lib/fopen.c
--- m4-1.4.13.orig/lib/fopen.c	2009-01-24 19:01:56 +0000
+++ m4-1.4.13/lib/fopen.c	2010-01-08 20:30:48 +0000
@@ -64,11 +64,11 @@ rpl_fopen (const char *filename, const c
      fails with errno = EISDIR in this case.
      If the named file does not exist or does not name a directory, then
      fopen() must fail since the file does not contain a '.' directory.  */
   {
     size_t len = strlen (filename);
-    if (len > 0 && filename[len - 1] == '/')
+    if (len > 0 && ISSLASH (filename[len - 1]))
       {
 	int fd;
 	struct stat statbuf;
 	FILE *fp;
 
diff -aprNU5 m4-1.4.13.orig/lib/freadahead.c m4-1.4.13/lib/freadahead.c
--- m4-1.4.13.orig/lib/freadahead.c	2009-03-01 15:29:10 +0000
+++ m4-1.4.13/lib/freadahead.c	2010-01-08 20:30:48 +0000
@@ -17,10 +17,19 @@
 #include <config.h>
 
 /* Specification.  */
 #include "freadahead.h"
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOERR definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include <stdlib.h>
 #include "stdio-impl.h"
 
 size_t
 freadahead (FILE *fp)
diff -aprNU5 m4-1.4.13.orig/lib/freading.c m4-1.4.13/lib/freading.c
--- m4-1.4.13.orig/lib/freading.c	2009-03-01 15:29:10 +0000
+++ m4-1.4.13/lib/freading.c	2010-01-08 20:30:48 +0000
@@ -17,10 +17,19 @@
 #include <config.h>
 
 /* Specification.  */
 #include "freading.h"
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOREAD definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include "stdio-impl.h"
 
 /* Don't use glibc's __freading function in glibc < 2.7, see
    <http://sourceware.org/bugzilla/show_bug.cgi?id=4359>  */
 #if !(HAVE___FREADING && (!defined __GLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)))
diff -aprNU5 m4-1.4.13.orig/lib/fseeko.c m4-1.4.13/lib/fseeko.c
--- m4-1.4.13.orig/lib/fseeko.c	2009-03-01 15:29:12 +0000
+++ m4-1.4.13/lib/fseeko.c	2010-01-08 20:30:48 +0000
@@ -21,10 +21,19 @@
 #include <stdio.h>
 
 /* Get off_t and lseek.  */
 #include <unistd.h>
 
+#if __DJGPP__
+ /*
+  *  Include libc/file.h for _IOERR definition
+  *  so that SystemV derived implementations are
+  *  selected for DJGPP.
+  */
+# include <libc/file.h>
+#endif
+
 #include "stdio-impl.h"
 
 #undef fseeko
 #if !HAVE_FSEEKO
 # undef fseek
diff -aprNU5 m4-1.4.13.orig/lib/mkstemp-safer.c m4-1.4.13/lib/mkstemp-safer.c
--- m4-1.4.13.orig/lib/mkstemp-safer.c	2008-02-23 17:29:50 +0000
+++ m4-1.4.13/lib/mkstemp-safer.c	2010-01-08 20:30:48 +0000
@@ -22,10 +22,20 @@
 #include "stdlib-safer.h"
 
 #include <stdlib.h>
 #include "unistd-safer.h"
 
+/* #if (__DJGPP__ == 2) && (__DJGPP_MINOR__ == 3) */
+#if __DJGPP__
+/*
+ *  DJGPP 2.03 declares mkstemp() in stdio.h instead of stdlib.h.
+ */
+# define __need_FILE
+# include <stdio.h>
+# undef __need_FILE
+#endif
+
 /* Like mkstemp, but do not return STDIN_FILENO, STDOUT_FILENO, or
    STDERR_FILENO.  */
 
 int
 mkstemp_safer (char *templ)
diff -aprNU5 m4-1.4.13.orig/lib/open.c m4-1.4.13/lib/open.c
--- m4-1.4.13.orig/lib/open.c	2008-10-10 03:04:30 +0000
+++ m4-1.4.13/lib/open.c	2010-01-08 20:30:48 +0000
@@ -89,11 +89,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;
 	}
     }
@@ -115,11 +115,11 @@ open (const char *filename, int flags, .
      If the named file without the slash is not a directory, open() must fail
      with ENOTDIR.  */
   if (fd >= 0)
     {
       size_t len = strlen (filename);
-      if (len > 0 && filename[len - 1] == '/')
+      if (len > 0 && ISSLASH (filename[len - 1]))
 	{
 	  struct stat statbuf;
 
 	  if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
 	    {
diff -aprNU5 m4-1.4.13.orig/lib/pipe.c m4-1.4.13/lib/pipe.c
--- m4-1.4.13.orig/lib/pipe.c	2009-03-09 02:14:46 +0000
+++ m4-1.4.13/lib/pipe.c	2010-01-08 20:30:48 +0000
@@ -39,10 +39,16 @@
 
 /* Native Woe32 API.  */
 # include <process.h>
 # include "w32spawn.h"
 
+#elif defined __DJGPP__
+
+/* DJGPP API.  */
+# include <process.h>
+# include "djgpp-spawn.h"
+
 #else
 
 /* Unix API.  */
 # include <spawn.h>
 
@@ -204,10 +210,11 @@ create_pipe (const char *progname,
 	     a hidden element "sh.exe" to prog_argv.  */
 	  --prog_argv;
 	  child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
 			    (const char **) environ);
 	}
+      free (new_prog_argv);
     }
   if (stdinfd >= 0)
     close (stdinfd);
   if (stdoutfd >= 0)
     close (stdoutfd);
@@ -242,10 +249,133 @@ create_pipe (const char *progname,
     fd[0] = ifd[0];
   if (pipe_stdin)
     fd[1] = ofd[1];
   return child;
 
+#elif defined  __DJGPP__
+
+  /* DJGPP API.  */
+  int ifd[2];
+  int ofd[2];
+  int orig_stdin;
+  int orig_stdout;
+  int orig_stderr;
+  int exitcode;
+  int nulloutfd;
+  int stdinfd;
+  int stdoutfd;
+
+  /* Add an element upfront that can be used when argv[0] turns out to be a
+     script, not a program.  */
+  char **new_prog_argv = prepare_spawn (prog_argv);
+
+  if (pipe_stdout)
+//    if (_pipe (ifd, PIPE_STDOUT) < 0 || (ifd[0] = fd_safer (ifd[0])) < 0)
+    if (_pipe (ifd, PIPE_STDOUT) < 0)
+      error (EXIT_FAILURE, errno, _("cannot create pipe"));
+  if (pipe_stdin)
+//    if (_pipe (ofd, PIPE_STDIN) < 0 || (ofd[1] = fd_safer (ofd[1])) < 0)
+    if (_pipe (ofd, PIPE_STDIN) < 0)
+      error (EXIT_FAILURE, errno, _("cannot create pipe"));
+/* Data flow diagram:
+ *
+ *           write        system         read
+ *    parent  ->   ofd[1]   ->   ofd[0]   ->   child       if pipe_stdin
+ *    parent  <-   ifd[0]   <-   ifd[1]   <-   child       if pipe_stdout
+ *           read         system         write
+ *
+ */
+
+  /* Save standard file handles of parent process.  */
+  if (pipe_stdin || prog_stdin != NULL)
+    orig_stdin = dup (STDIN_FILENO);
+  if (pipe_stdout || prog_stdout != NULL)
+    orig_stdout = dup (STDOUT_FILENO);
+  if (null_stderr)
+    orig_stderr = dup (STDERR_FILENO);
+  exitcode = -1;
+
+  /* Create standard file handles of child process.  */
+  nulloutfd = -1;
+  stdinfd = -1;
+  stdoutfd = -1;
+  if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
+      && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
+      && (!null_stderr
+	  || ((nulloutfd = open ("/dev/null", O_RDWR, 0)) >= 0
+	      && (nulloutfd == STDERR_FILENO
+		  || (dup2 (nulloutfd, STDERR_FILENO) >= 0
+		      && close (nulloutfd) >= 0))))
+      && (pipe_stdin
+	  || prog_stdin == NULL
+	  || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
+	      && (stdinfd == STDIN_FILENO
+		  || (dup2 (stdinfd, STDIN_FILENO) >= 0
+		      && close (stdinfd) >= 0))))
+      && (pipe_stdout
+	  || prog_stdout == NULL
+	  || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
+	      && (stdoutfd == STDOUT_FILENO
+		  || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
+		      && close (stdoutfd) >= 0)))))
+    /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
+       but it inherits all open()ed or dup2()ed file handles (which is what
+       we want in the case of STD*_FILENO) and also orig_stdin,
+       orig_stdout, orig_stderr (which is not explicitly wanted but
+       harmless).  */
+    /* Use spawnvpe and pass the environment explicitly.  This is needed if
+       the program has modified the environment using putenv() or [un]setenv().
+       On Windows, programs have two environments, one in the "environment
+       block" of the process and managed through SetEnvironmentVariable(), and
+       one inside the process, in the location retrieved by the 'environ'
+       macro.  When using spawnvp() without 'e', the child process inherits a
+       copy of the environment block - ignoring the effects of putenv() and
+       [un]setenv().  */
+    {
+      exitcode = spawnvpe (P_WAIT, prog_path, prog_argv, environ);
+      if (exitcode < 0 && errno == ENOEXEC)
+	{
+	  /* prog is not an native executable.  Try to execute it as a
+	     shell script.  Note that prepare_spawn() has already prepended
+	     a hidden element "sh.exe" to prog_argv.  */
+	  --prog_argv;
+	  exitcode = spawnvpe (P_WAIT, prog_argv[0], prog_argv, environ);
+	}
+    }
+  if (stdinfd >= 0)
+    close (stdinfd);
+  if (stdoutfd >= 0)
+    close (stdoutfd);
+  if (nulloutfd >= 0)
+    close (nulloutfd);
+
+  /* Restore standard file handles of parent process.  */
+  if (null_stderr)
+    dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
+  if (pipe_stdout || prog_stdout != NULL)
+    dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
+  if (pipe_stdin || prog_stdin != NULL)
+    dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
+
+  if (pipe_stdin)
+    close (ofd[0]);
+  if (pipe_stdout)
+    close (ifd[1]);
+  if (exitcode == -1)
+    {
+      if (exit_on_error || !null_stderr)
+	error (exit_on_error ? EXIT_FAILURE : 0, errno,
+	       _("%s subprocess failed"), progname);
+      return -1;
+    }
+
+  if (pipe_stdout)
+    fd[0] = open (tmp_file_name[PIPE_STDOUT], O_RDONLY, S_IRUSR);
+  if (pipe_stdin)
+    fd[1] = open (tmp_file_name[PIPE_STDIN], O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR);
+  return exitcode;
+
 #else
 
   /* Unix API.  */
   int ifd[2];
   int ofd[2];
diff -aprNU5 m4-1.4.13.orig/lib/progname.c m4-1.4.13/lib/progname.c
--- m4-1.4.13.orig/lib/progname.c	2009-01-16 13:26:12 +0000
+++ m4-1.4.13/lib/progname.c	2010-01-08 20:30:48 +0000
@@ -22,10 +22,30 @@
 #undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.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
+# define GET_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
+# 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;
 
@@ -39,13 +59,21 @@ set_program_name (const char *argv0)
      visible to the end user and to the test suite.
      Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
   const char *slash;
   const char *base;
 
-  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 m4-1.4.13.orig/lib/spawni.c m4-1.4.13/lib/spawni.c
--- m4-1.4.13.orig/lib/spawni.c	2009-03-09 02:14:52 +0000
+++ m4-1.4.13/lib/spawni.c	2010-01-08 20:30:48 +0000
@@ -100,10 +100,24 @@ __spawni (pid_t *pid, const char *file,
 {
   /* Not yet implemented.  */
   return ENOSYS;
 }
 
+#elif defined __DJGPP__
+
+
+/* MSDOS/DJGPP API.  */
+int
+__spawni (pid_t *pid, const char *file,
+	  const posix_spawn_file_actions_t *file_actions,
+	  const posix_spawnattr_t *attrp, char *const argv[],
+	  char *const envp[], int use_path)
+{
+  /* Not yet implemented.  */
+  return ENOSYS;
+}
+
 #else
 
 
 /* The file is accessible but it is not an executable file.  Invoke
    the shell to interpret it as a script.  */
diff -aprNU5 m4-1.4.13.orig/lib/tempname.c m4-1.4.13/lib/tempname.c
--- m4-1.4.13.orig/lib/tempname.c	2008-02-23 17:29:58 +0000
+++ m4-1.4.13/lib/tempname.c	2010-01-08 20:30:48 +0000
@@ -103,10 +103,16 @@
    which is better than not having mkstemp at all.  */
 #if !defined UINT64_MAX && !defined uint64_t
 # define uint64_t uintmax_t
 #endif
 
+#ifdef MSDOS
+# define HAVE_ALTERNATE_TMPDIR  1
+#else
+# define HAVE_ALTERNATE_TMPDIR  0
+#endif
+
 #if _LIBC
 /* Return nonzero if DIR is an existent directory.  */
 static int
 direxists (const char *dir)
 {
@@ -142,30 +148,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_ALTERNATE_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_ALTERNATE_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 m4-1.4.13.orig/lib/tmpdir.c m4-1.4.13/lib/tmpdir.c
--- m4-1.4.13.orig/lib/tmpdir.c	2008-02-23 17:29:58 +0000
+++ m4-1.4.13/lib/tmpdir.c	2010-01-08 20:30:48 +0000
@@ -51,13 +51,15 @@
 /* Pathname support.
    ISSLASH(C)           tests whether C is a directory separator character.
  */
 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
   /* Win32, Cygwin, OS/2, DOS */
+# define HAVE_ALTERNATE_TMPDIR  1
 # define ISSLASH(C) ((C) == '/' || (C) == '\\')
 #else
   /* Unix */
+# define HAVE_ALTERNATE_TMPDIR  0
 # define ISSLASH(C) ((C) == '/')
 #endif
 
 
 /* Return nonzero if DIR is an existent directory.  */
@@ -96,21 +98,32 @@ path_search (char *tmpl, size_t tmpl_len
   if (try_tmpdir)
     {
       d = __secure_getenv ("TMPDIR");
       if (d != NULL && direxists (d))
 	dir = d;
+#if HAVE_ALTERNATE_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_ALTERNATE_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;
 	}
diff -aprNU5 m4-1.4.13.orig/lib/wait-process.c m4-1.4.13/lib/wait-process.c
--- m4-1.4.13.orig/lib/wait-process.c	2009-03-01 23:12:02 +0000
+++ m4-1.4.13/lib/wait-process.c	2010-01-08 20:30:48 +0000
@@ -46,10 +46,12 @@
 
 /* The return value of spawnvp() is really a process handle as returned
    by CreateProcess().  Therefore we can kill it using TerminateProcess.  */
 #define kill(pid,sig) TerminateProcess ((HANDLE) (pid), sig)
 
+#elif defined __DJGPP__
+#include "djgpp-spawn.h"
 #endif
 
 
 /* Type of an entry in the slaves array.
    The 'used' bit determines whether this entry is currently in use.
@@ -291,29 +293,46 @@ wait_subprocess (pid_t child, const char
   int status;
 
   if (termsigp != NULL)
     *termsigp = 0;
   status = 0;
+
+# ifdef __DJGPP__
+  /* Child process already finished.  */
+
+  remove_tmp_file(NULL);
+  if (child == -1)
+    {
+      if (exit_on_error || !null_stderr)
+        error (exit_on_error ? EXIT_FAILURE : 0, errno,
+               _("%s subprocess failed"), progname);
+      return 127;
+    }
+
+  return WEXITSTATUS (child);
+
+# else
+
   for (;;)
     {
       int result = waitpid (child, &status, 0);
 
       if (result != child)
 	{
-# ifdef EINTR
+#  ifdef EINTR
 	  if (errno == EINTR)
 	    continue;
-# endif
-# if 0 /* defined ECHILD */
+#  endif
+#  if 0 /* defined ECHILD */
 	  if (errno == ECHILD)
 	    {
 	      /* Child process nonexistent?! Assume it terminated
 		 successfully.  */
 	      status = 0;
 	      break;
 	    }
-# endif
+#  endif
 	  if (exit_on_error || !null_stderr)
 	    error (exit_on_error ? EXIT_FAILURE : 0, errno,
 		   _("%s subprocess"), progname);
 	  return 127;
 	}
@@ -335,14 +354,14 @@ wait_subprocess (pid_t child, const char
 
   if (WIFSIGNALED (status))
     {
       if (termsigp != NULL)
 	*termsigp = WTERMSIG (status);
-# ifdef SIGPIPE
+#  ifdef SIGPIPE
       if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe)
 	return 0;
-# endif
+#  endif
       if (exit_on_error || (!null_stderr && termsigp == NULL))
 	error (exit_on_error ? EXIT_FAILURE : 0, 0,
 	       _("%s subprocess got fatal signal %d"),
 	       progname, (int) WTERMSIG (status));
       return 127;
@@ -355,7 +374,8 @@ wait_subprocess (pid_t child, const char
 	error (exit_on_error ? EXIT_FAILURE : 0, 0,
 	       _("%s subprocess failed"), progname);
       return 127;
     }
   return WEXITSTATUS (status);
+# endif
 #endif
 }
diff -aprNU5 m4-1.4.13.orig/src/builtin.c m4-1.4.13/src/builtin.c
--- m4-1.4.13.orig/src/builtin.c	2009-03-05 12:46:00 +0000
+++ m4-1.4.13/src/builtin.c	2010-01-08 20:30:48 +0000
@@ -159,11 +159,17 @@ static predefined const predefined_tab[]
   { "windows",	"__windows__",	"" },
 #endif
 #if OS2
   { "os2",	"__os2__",	"" },
 #endif
-#if !UNIX && !W32_NATIVE && !OS2
+#if DOSISH
+  { "msdos",	"__msdos__",	"" },
+#if __DJGPP__
+  { "djgpp",	"__djgpp__",	"" },
+#endif
+#endif
+#if !UNIX && !W32_NATIVE && !OS2 && !DOSISH
 # warning Platform macro not provided
 #endif
   { NULL,	"__gnu__",	"" },
 
   { NULL,	NULL,		NULL },
@@ -960,10 +966,17 @@ m4_syscmd (struct obstack *obs, int argc
     {
       prog_args[0] = "cmd";
       prog_args[1] = "/c";
     }
 #endif
+#if __MSDOS__
+  if (strstr (SYSCMD_SHELL, "command"))
+    {
+      prog_args[0] = "command";
+      prog_args[1] = "/c";
+    }
+#endif
   prog_args[2] = cmd;
   errno = 0;
   status = execute (ARG (0), SYSCMD_SHELL, (char **) prog_args, false,
 		    false, false, false, true, false, &sig_status);
   if (sig_status)
@@ -1003,10 +1016,17 @@ m4_esyscmd (struct obstack *obs, int arg
     {
       prog_args[0] = "cmd";
       prog_args[1] = "/c";
     }
 #endif
+#if __MSDOS__
+  if (strstr (SYSCMD_SHELL, "command"))
+    {
+      prog_args[0] = "command";
+      prog_args[1] = "/c";
+    }
+#endif
   prog_args[2] = cmd;
   errno = 0;
   child = create_pipe_in (ARG (0), SYSCMD_SHELL, (char **) prog_args,
 			  NULL, false, true, false, &fd);
   if (child == -1)
diff -aprNU5 m4-1.4.13.orig/src/m4.c m4-1.4.13/src/m4.c
--- m4-1.4.13.orig/src/m4.c	2009-01-24 19:52:42 +0000
+++ m4-1.4.13/src/m4.c	2010-01-08 20:30:48 +0000
@@ -33,10 +33,18 @@
 # include "assert.h"
 #endif
 
 #define AUTHORS "Rene' Seindal"
 
+#ifndef SA_NODEFER
+# define SA_NODEFER  0
+#endif
+
+#ifndef SA_RESETHAND
+# define SA_RESETHAND  0
+#endif
+
 static void usage (int);
 
 /* Enable sync output for /lib/cpp (-s).  */
 int sync_output = 0;
 
@@ -248,15 +256,25 @@ FLAGS is any of:\n\
   q   quote values as necessary, with a or e flag\n\
   t   trace for all macro calls, not only traceon'ed\n\
   x   add a unique macro call id, useful with c flag\n\
   V   shorthand for all of the above flags\n\
 ", stdout);
+#if __DJGPP__
+      fputs ("\
+\n\
+If defined, the environment variable `M4PATH' is either a colon-separated\n\
+or semicolon-separated (default) list of directories included after any\n\
+specified by `-I'.  The value of the environment variable `PATH_SEPARATOR'\n\
+determinates which one of the characters will be used.\n\
+", stdout);
+#else
       fputs ("\
 \n\
 If defined, the environment variable `M4PATH' is a colon-separated list\n\
 of directories included after any specified by `-I'.\n\
 ", stdout);
+#endif
       fputs ("\
 \n\
 Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
 mismatch, or whatever value was passed to the m4exit macro.\n\
 ", stdout);
diff -aprNU5 m4-1.4.13.orig/src/m4.h m4-1.4.13/src/m4.h
--- m4-1.4.13.orig/src/m4.h	2008-12-12 13:11:38 +0000
+++ m4-1.4.13/src/m4.h	2010-01-08 20:30:48 +0000
@@ -69,10 +69,63 @@
 #ifdef __EMX__
 # define OS2 1
 # undef UNIX
 #endif
 
+/* Canonicalize MSDOS/DJGPP recognition macro.  */
+#ifdef MSDOS
+# define DOSISH 1
+# ifdef __DJGPP__
+#  undef UNIX
+#  define UNIX 1
+# endif
+#endif
+
+/* MS-DOS and similar non-Posix systems have some peculiarities:
+    - directories in environment variables (like PATH) are separated
+        by `;' rather than `:';
+   This is parameterized here.  */
+
+#if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+# define IS_DRIVE_SPEC(path)        ((path)[0] >= 'A' && \
+                                     (path)[0] <= 'z' && \
+                                     (path)[1] == ':')
+# define GET_PATH_SEPARATOR(path)                                 \
+  ({                                                              \
+     char *_path_separator;                                       \
+     char *_colon, *_semi_colon;                                  \
+     _colon = strchr((path), ':');                                \
+     _semi_colon = strchr((path), ';');                           \
+     if (_semi_colon == (path) || _colon == (path))               \
+       _path_separator = path;                                    \
+     else if (_semi_colon == _colon + 1 && !IS_DRIVE_SPEC(path))  \
+       _path_separator = _colon;                                  \
+     else if (_colon == _semi_colon + 1 || IS_DRIVE_SPEC(path))   \
+       _path_separator = _semi_colon;                             \
+     else                                                         \
+     {                                                            \
+       if (_colon < _semi_colon)                                  \
+         _path_separator = _colon;                                \
+       else                                                       \
+         _path_separator = _semi_colon;                           \
+     }                                                            \
+     _path_separator;                                             \
+  })
+# define CANONICALIZE_PATH(path)  \
+do {                              \
+  if ((path))                     \
+  {                               \
+    char *_p;                     \
+    for (_p = (path); *_p; _p++)  \
+      if (*_p == '\\')            \
+        *_p = '/';                \
+  }                               \
+} while(0)
+#else  /* not DOS/Windows like, i.e., Unix */
+# define CANONICALIZE_PATH(path)  /* NO OP */
+#endif /* not FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX */
+
 /* Used if any programmer error is detected (not possible, right?)  */
 #define EXIT_INTERNAL_ERROR 2
 
 /* Used for version mismatch, when -R detects a frozen file it can't parse.  */
 #define EXIT_MISMATCH 63
diff -aprNU5 m4-1.4.13.orig/src/output.c m4-1.4.13/src/output.c
--- m4-1.4.13.orig/src/output.c	2009-02-19 01:19:04 +0000
+++ m4-1.4.13/src/output.c	2010-01-08 20:30:48 +0000
@@ -473,10 +473,11 @@ make_room_for (int length)
       selected_buffer = selected_diversion->u.buffer;
       total_buffer_size -= selected_diversion->size;
       selected_diversion->size = 0;
       selected_diversion->u.file = NULL;
       selected_diversion->u.file = m4_tmpfile (selected_diversion->divnum);
+      SET_BINARY (fileno (selected_diversion->u.file));
 
       if (selected_diversion->used > 0)
 	{
 	  count = fwrite (selected_buffer, (size_t) selected_diversion->used,
 			  1, selected_diversion->u.file);
diff -aprNU5 m4-1.4.13.orig/src/path.c m4-1.4.13/src/path.c
--- m4-1.4.13.orig/src/path.c	2008-12-12 13:06:32 +0000
+++ m4-1.4.13/src/path.c	2010-01-08 20:30:48 +0000
@@ -50,10 +50,16 @@ void
 include_env_init (void)
 {
   char *path;
   char *path_end;
   char *env_path;
+  char path_sep = ':';
+#if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+  char *sep_char = getenv ("PATH_SEPARATOR");
+
+  path_sep = sep_char ? *sep_char :  ';';
+#endif
 
   if (no_gnu_extensions)
     return;
 
   env_path = getenv ("M4PATH");
@@ -63,13 +69,14 @@ include_env_init (void)
   env_path = xstrdup (env_path);
   path = env_path;
 
   do
     {
-      path_end = strchr (path, ':');
+      path_end = strchr (path, path_sep);
       if (path_end)
 	*path_end = '\0';
+      CANONICALIZE_PATH (path);
       add_include_directory (path);
       path = path_end + 1;
     }
   while (path_end);
   free (env_path);
