2014-07-06  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/output.c (m4_tmpname): Use HAVE_LFN_SUPPORT to determinate a
	valid file name pattern.

	* src/m4.h [FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX]: New macro
	HAVE_LFN_SUPPORT defined.  For all other systems this macro is a no-op.

	* lib/tmpdir.c [__DJGPP__]: New macro HAVE_LFN_SUPPORT.  Value depends
	on if the OS is posix or not.  Include libc/unconst.h.
	(path_search): Use HAVE_LFN_SUPPORT to limit the length of the prefix
	string used to create the temporary file name.

	* lib/tempname.c [__DJGPP__]: New macro HAVE_LFN_SUPPORT.  Value depends
	on if the OS is posix or not.  Include libc/unconst.h.
	(__path_search): Use HAVE_LFN_SUPPORT to limit the length of the prefix
	string used to create the temporary file name.

	* lib/secure_getenv.c [HAVE_ISSETUGID, __DJGPP__]: DOS does not provide
	issetugid.  Call getenv always.


2014-07-02  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* lib/fflush.c (rpl_fflush) [__DJGPP__]: Call fflush directly and do
	not try to do any POSIX specific stuff especially do not seek STDIN
	if connected to a file.  This would make lose synchronization between
        buffer pointer of FILE structure and and DOS file pointer.


2014-01-18  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* lib/fopen.c: If ISSLASH is not defined include dosname.h

	* lib/open.c: If ISSLASH is not defined include dosname.h


2013-11-03  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

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

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

	* lib/wait-process.c [__DJGPP__]: Include djgpp-spawn.h.
	DJGPP specific implementation of wait_subprocess.  Removes the tmp
	files used to implement the pipe.


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

	* 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/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/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.
	New macro STRIP_FULL_PATH_AND_EXTENSION defined.  For all other systems
	this macro is a no-op.

	* src/m4.c (usage) [__DJGPP__]: Add DJGPP specific info about M4PATH.
	(main): Use STRIP_FULL_PATH_AND_EXTENSION to strip path and extension
	from argv[0].

	* src/builtin.c: Add MSDOS and DJGPP to the supported platform macros
	list.
	(m4_syscmd, m4_esyscmd): For MSDOS allow command.com as shell as well.

	* lib/tmpdir.c [__DJGPP__]: New macro HAVE_DIFFERENT_TMPDIR.  Value
	depends on if the OS is posix or not.
	(path_search): 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/tempname.c [__DJGPP__]: New macro HAVE_DIFFERENT_TMPDIR.  Value
	depends on if the OS is posix or not.
	(__path_search): 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/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/stdio-impl.h [__DJGPP__]: Include sys/file.h to provide _IOERR
	for fseterr function support.

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

	* lib/fatal-signal.c [__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/execute.c [__DJGPP__]: DJGPP specific implementation of execute.

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

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


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

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











diff -aprNU5 m4-1.4.17.orig/doc/m4.texi m4-1.4.17/doc/m4.texi
--- m4-1.4.17.orig/doc/m4.texi	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/doc/m4.texi	2015-07-25 23:29:28 -0502
@@ -5026,14 +5026,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{}
@@ -5152,10 +5152,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
@@ -5174,10 +5183,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{./}.
 Thus, the amount of available disk space provides the only real limit on
 the number and aggregate size of diversions.
 
 @ignore
 @comment We need to test spilled diversions, but don't need to expose
@@ -6503,10 +6517,14 @@ Sometimes it is desirable for an input f
 @code{m4} is running on.  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__
@@ -6551,10 +6569,14 @@ On native Windows systems, GNU @code{m4}
 @option{-G} option is specified.
 
 On OS/2 systems, 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 GNU @code{m4} does not provide a platform macro for your system,
 please report that as a bug.
 
 @example
 define(`provided', `0')
@@ -6563,12 +6585,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
 
@@ -6883,12 +6909,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
@@ -7257,11 +7283,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.17.orig/lib/cloexec.c m4-1.4.17/lib/cloexec.c
--- m4-1.4.17.orig/lib/cloexec.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/cloexec.c	2015-07-25 23:29:28 -0502
@@ -36,11 +36,19 @@
    non-inheritable in the first place.  */
 
 int
 set_cloexec_flag (int desc, bool value)
 {
-#ifdef F_SETFD
+#if 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.17.orig/lib/djgpp-spawn.h m4-1.4.17/lib/djgpp-spawn.h
--- m4-1.4.17.orig/lib/djgpp-spawn.h	1969-12-31 18:57:11 -0502
+++ m4-1.4.17/lib/djgpp-spawn.h	2015-07-25 23:29:28 -0502
@@ -0,0 +1,156 @@
+#include <config.h>
+#include <stdio.h>
+#include "cloexec.h"
+#include "xalloc.h"
+
+
+#define PROGRAM_NAME_TEMPLATE  "m4XXXXXX"
+
+#define prepare_spawn(argv)                                        \
+(__gnuc_extension__                                                \
+  ({                                                               \
+     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)                                                \
+(__gnuc_extension__                                                          \
+  ({                                                                         \
+     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]);  \
+       }                                                                     \
+     }                                                                       \
+  })                                                                         \
+)
+
+
+/* Duplicates a file handle, making the copy uninheritable.
+   Returns -1 for a file handle that is equivalent to closed.  */
+static int
+dup_noinherit(int fd)
+{
+  fd = dup_cloexec(fd);
+  if (fd < 0 && errno == EMFILE)
+    error(EXIT_FAILURE, errno, _("fcntl failed"));
+
+  return fd;
+}
+
+/* Returns a file descriptor equivalent to FD, except that the resulting file
+   descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.
+   FD must be open and non-inheritable.  The result will be non-inheritable as
+   well.
+   If FD < 0, FD itself is returned.  */
+static int
+fd_safer_noinherit(int fd)
+{
+  if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
+  {
+    /* The recursion depth is at most 3.  */
+    int nfd = fd_safer_noinherit(dup_noinherit(fd));
+    int saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return nfd;
+  }
+  return fd;
+}
+
+/* Duplicates a file handle, making the copy uninheritable and ensuring the
+   result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.
+   Returns -1 for a file handle that is equivalent to closed.  */
+static int
+dup_safer_noinherit(int fd)
+{
+  return fd_safer_noinherit(dup_noinherit(fd));
+}
+
+/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD);  */
+static void
+undup_safer_noinherit(int tempfd, int origfd)
+{
+  if (tempfd >= 0)
+  {
+    if (dup2(tempfd, origfd) < 0)
+      error(EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"), origfd);
+    close(tempfd);
+  }
+  else
+  {
+    /* origfd was closed or open to no handle at all.  Set it to a closed
+       state.  This is (nearly) equivalent to the original state.  */
+    close(origfd);
+  }
+}
+
+#ifdef _SPAWN_PIPE_H
+static int
+djgpp_pipe(int pipe_fd[2], int pipe_end)
+{
+  int fd;
+
+  strcpy(tmp_file_name[pipe_end], "/dev/env/TMPDIR/"PROGRAM_NAME_TEMPLATE);
+  if ((fd = mkstemp(tmp_file_name[pipe_end])) < 0)
+  {
+    strcpy(tmp_file_name[pipe_end], "/dev/env/TMP/"PROGRAM_NAME_TEMPLATE);
+    if ((fd = mkstemp(tmp_file_name[pipe_end])) < 0)
+    {
+      strcpy(tmp_file_name[pipe_end], "/dev/env/TEMP/"PROGRAM_NAME_TEMPLATE);
+      if ((fd = mkstemp(tmp_file_name[pipe_end])) < 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.17.orig/lib/execute.c m4-1.4.17/lib/execute.c
--- m4-1.4.17.orig/lib/execute.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/execute.c	2015-07-25 23:29:28 -0502
@@ -39,10 +39,16 @@
 
 /* Native Windows 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>
 
@@ -168,10 +174,96 @@ execute (const char *progname,
     }
   if (nulloutfd >= 0)
     close (nulloutfd);
   if (nullinfd >= 0)
     close (nullinfd);
+
+  /* Restore standard file handles of parent process.  */
+  if (null_stderr)
+    undup_safer_noinherit (orig_stderr, STDERR_FILENO);
+  if (null_stdout)
+    undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
+  if (null_stdin)
+    undup_safer_noinherit (orig_stdin, STDIN_FILENO);
+
+  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;
+
+#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)
+    orig_stdin = dup_safer_noinherit (STDIN_FILENO);
+  if (null_stdout)
+    orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
+  if (null_stderr)
+    orig_stderr = dup_safer_noinherit (STDERR_FILENO);
+  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)
     undup_safer_noinherit (orig_stderr, STDERR_FILENO);
   if (null_stdout)
diff -aprNU5 m4-1.4.17.orig/lib/fatal-signal.c m4-1.4.17/lib/fatal-signal.c
--- m4-1.4.17.orig/lib/fatal-signal.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/fatal-signal.c	2015-07-25 23:29:28 -0502
@@ -123,10 +123,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 +146,13 @@ uninstall_handlers (void)
 
   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 +199,13 @@ install_handlers (void)
   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.17.orig/lib/fflush.c m4-1.4.17/lib/fflush.c
--- m4-1.4.17.orig/lib/fflush.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/fflush.c	2015-07-25 23:29:28 -0502
@@ -121,10 +121,14 @@ update_fpos_cache (FILE *fp _GL_UNUSED_P
 /* Flush all pending data on STREAM according to POSIX rules.  Both
    output and seekable input streams are supported.  */
 int
 rpl_fflush (FILE *stream)
 {
+#ifdef __DJGPP__
+  return fflush (stream);
+#endif
+
   /* When stream is NULL, POSIX and C99 only require flushing of "output
      streams and update streams in which the most recent operation was not
      input", and all implementations do this.
 
      When stream is "an output stream or an update stream in which the most
diff -aprNU5 m4-1.4.17.orig/lib/fopen.c m4-1.4.17/lib/fopen.c
--- m4-1.4.17.orig/lib/fopen.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/fopen.c	2015-07-25 23:29:28 -0502
@@ -19,10 +19,13 @@
 /* If the user's config.h happens to include <stdio.h>, let it include only
    the system's <stdio.h> here, so that orig_fopen doesn't recurse to
    rpl_fopen.  */
 #define __need_FILE
 #include <config.h>
+#ifndef ISSLASH
+# include "dosname.h"
+#endif
 
 /* Get the original definition of fopen.  It might be defined as a macro.  */
 #include <stdio.h>
 #undef __need_FILE
 
@@ -69,11 +72,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.17.orig/lib/open.c m4-1.4.17/lib/open.c
--- m4-1.4.17.orig/lib/open.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/open.c	2015-07-25 23:29:28 -0502
@@ -19,10 +19,13 @@
 /* If the user's config.h happens to include <fcntl.h>, let it include only
    the system's <fcntl.h> here, so that orig_open doesn't recurse to
    rpl_open.  */
 #define __need_system_fcntl_h
 #include <config.h>
+#ifndef ISSLASH
+# include "dosname.h"
+#endif
 
 /* Get the original definition of open.  It might be defined as a macro.  */
 #include <fcntl.h>
 #include <sys/types.h>
 #undef __need_system_fcntl_h
@@ -105,11 +108,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;
         }
     }
@@ -156,11 +159,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 m4-1.4.17.orig/lib/progname.c m4-1.4.17/lib/progname.c
--- m4-1.4.17.orig/lib/progname.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/progname.c	2015-07-25 23:29:28 -0502
@@ -25,10 +25,39 @@
 #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)              \
+  (__gnuc_extension__                          \
+    ({                                         \
+      char *_slash = NULL;                     \
+      if ((filename))                          \
+      {                                        \
+        _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 +83,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 m4-1.4.17.orig/lib/secure_getenv.c m4-1.4.17/lib/secure_getenv.c
--- m4-1.4.17.orig/lib/secure_getenv.c	2013-09-22 06:15:56 -0502
+++ m4-1.4.17/lib/secure_getenv.c	2015-07-25 23:29:28 -0502
@@ -22,11 +22,15 @@
 #if !HAVE___SECURE_GETENV
 # if HAVE_ISSETUGID
 #  include <unistd.h>
 # else
 #  undef issetugid
-#  define issetugid() 1
+#  ifdef __DJGPP__
+#   define issetugid() 0
+#  else
+#   define issetugid() 1
+#  endif
 # endif
 #endif
 
 char *
 secure_getenv (char const *name)
diff -aprNU5 m4-1.4.17.orig/lib/spawn-pipe.c m4-1.4.17/lib/spawn-pipe.c
--- m4-1.4.17.orig/lib/spawn-pipe.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/spawn-pipe.c	2015-07-25 23:29:28 -0502
@@ -39,10 +39,16 @@
 
 /* Native Windows 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>
 
@@ -244,10 +250,135 @@ 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 child;
+  int nulloutfd;
+  int stdinfd;
+  int stdoutfd;
+  int saved_errno;
+
+  /* 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 (djgpp_pipe (ifd, PIPE_STDOUT) < 0)
+      error (EXIT_FAILURE, errno, _("cannot create pipe"));
+  if (pipe_stdin)
+    if (djgpp_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_safer_noinherit (STDIN_FILENO);
+  if (pipe_stdout || prog_stdout != NULL)
+    orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
+  if (null_stderr)
+    orig_stderr = dup_safer_noinherit (STDERR_FILENO);
+  child = -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().  */
+    {
+      child = spawnvpe (P_WAIT, prog_path, prog_argv, environ);
+      if (child < 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;
+	  child = spawnvpe (P_WAIT, prog_argv[0], prog_argv, environ);
+	}
+    }
+  if (child == -1)
+    saved_errno = errno;
+  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 (child == -1)
+    {
+      if (exit_on_error || !null_stderr)
+	error (exit_on_error ? EXIT_FAILURE : 0, errno,
+	       _("%s subprocess failed"), progname);
+      errno = saved_errno;
+      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 child;
+
 #else
 
   /* Unix API.  */
   int ifd[2];
   int ofd[2];
diff -aprNU5 m4-1.4.17.orig/lib/spawni.c m4-1.4.17/lib/spawni.c
--- m4-1.4.17.orig/lib/spawni.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/spawni.c	2015-07-25 23:29:28 -0502
@@ -100,10 +100,23 @@ __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.17.orig/lib/stdio-impl.h m4-1.4.17/lib/stdio-impl.h
--- m4-1.4.17.orig/lib/stdio-impl.h	2013-09-22 06:20:02 -0502
+++ m4-1.4.17/lib/stdio-impl.h	2015-07-25 23:29:28 -0502
@@ -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 m4-1.4.17.orig/lib/tempname.c m4-1.4.17/lib/tempname.c
--- m4-1.4.17.orig/lib/tempname.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/tempname.c	2015-07-25 23:29:28 -0502
@@ -97,10 +97,25 @@
    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_DIFFERENT_TMPDIR    1
+# if HAVE_UNISTD_H
+#  define HAVE_LFN_SUPPORT(name)  ((pathconf((name), _PC_NAME_MAX) > 12) ? true : false)
+# else
+#  define HAVE_LFN_SUPPORT(name)  (false)
+# endif
+# ifdef __DJGPP__
+#  include <libc/unconst.h>
+# endif
+#else
+# define HAVE_DIFFERENT_TMPDIR    0
+# define HAVE_LFN_SUPPORT(name)   (true)
+#endif
+
 #if _LIBC
 /* Return nonzero if DIR is an existent directory.  */
 static int
 direxists (const char *dir)
 {
@@ -136,39 +151,57 @@ __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, ".") != 0 && direxists ("."))
+	dir = "./";
+#else
       else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
         dir = "/tmp";
+#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)
     {
       __set_errno (EINVAL);
       return -1;
     }
 
+  if (!HAVE_LFN_SUPPORT(dir))
+  {
+#ifdef __DJGPP__
+    char *prefix = unconst(pfx, char *);
+    prefix[2] = '\0';
+#endif
+  }
   sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
   return 0;
 }
 #endif /* _LIBC */
 
diff -aprNU5 m4-1.4.17.orig/lib/tmpdir.c m4-1.4.17/lib/tmpdir.c
--- m4-1.4.17.orig/lib/tmpdir.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/tmpdir.c	2015-07-25 23:29:28 -0502
@@ -61,13 +61,24 @@
    ISSLASH(C)           tests whether C is a directory separator character.
  */
 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
   /* Native Windows, Cygwin, OS/2, DOS */
 # define ISSLASH(C) ((C) == '/' || (C) == '\\')
+# define HAVE_DIFFERENT_TMPDIR    1
+# if HAVE_UNISTD_H
+#  define HAVE_LFN_SUPPORT(name)  ((pathconf((name), _PC_NAME_MAX) > 12) ? true : false)
+# else
+#  define HAVE_LFN_SUPPORT(name)  (false)
+# endif
+# ifdef __DJGPP__
+#  include <libc/unconst.h>
+# endif
 #else
   /* Unix */
 # define ISSLASH(C) ((C) == '/')
+# define HAVE_DIFFERENT_TMPDIR    0
+# define HAVE_LFN_SUPPORT(name)   (true)
 #endif
 
 
 /* Return nonzero if DIR is an existent directory.  */
 static bool
@@ -106,10 +117,16 @@ path_search (char *tmpl, size_t tmpl_len
   if (try_tmpdir)
     {
       d = __libc_secure_getenv ("TMPDIR");
       if (d != NULL && direxists (d))
         dir = d;
+#if HAVE_DIFFERENT_TMPDIR
+      else if ((d = __libc_secure_getenv ("TMP")) && direxists (d))
+	dir = d;
+      else if ((d = __libc_secure_getenv ("TEMP")) && direxists (d))
+	dir = d;
+#endif
       else if (dir != NULL && direxists (dir))
         /* nothing */ ;
       else
         dir = NULL;
     }
@@ -128,12 +145,17 @@ path_search (char *tmpl, size_t tmpl_len
         dir = dirbuf;
       else
 #endif
       if (direxists (P_tmpdir))
         dir = P_tmpdir;
+#if HAVE_DIFFERENT_TMPDIR
+      else if (strcmp (P_tmpdir, ".") != 0 && direxists ("."))
+	dir = "./";
+#else
       else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
         dir = "/tmp";
+#endif
       else
         {
           __set_errno (ENOENT);
           return -1;
         }
@@ -151,9 +173,17 @@ path_search (char *tmpl, size_t tmpl_len
     {
       __set_errno (EINVAL);
       return -1;
     }
 
+  if (!HAVE_LFN_SUPPORT(dir))
+  {
+#ifdef __DJGPP__
+    char *prefix = unconst(pfx, char *);
+    prefix[2] = '\0';
+#endif
+  }
   memcpy (tmpl, dir, dlen);
   sprintf (tmpl + dlen, &"/%.*sXXXXXX"[!add_slash], (int) plen, pfx);
+
   return 0;
 }
diff -aprNU5 m4-1.4.17.orig/lib/wait-process.c m4-1.4.17/lib/wait-process.c
--- m4-1.4.17.orig/lib/wait-process.c	2013-09-22 06:15:20 -0502
+++ m4-1.4.17/lib/wait-process.c	2015-07-25 23:29:28 -0502
@@ -46,10 +46,14 @@
 
 /* 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,10 +295,25 @@ 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)
@@ -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.17.orig/src/builtin.c m4-1.4.17/src/builtin.c
--- m4-1.4.17.orig/src/builtin.c	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/src/builtin.c	2015-07-25 23:29:28 -0502
@@ -160,11 +160,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 },
@@ -964,10 +970,17 @@ m4_syscmd (struct obstack *obs M4_GNUC_U
     {
       prog_args[0] = "cmd";
       prog_args[1] = "/c";
     }
 #endif
+#if DOSISH
+  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)
@@ -1007,10 +1020,17 @@ m4_esyscmd (struct obstack *obs, int arg
     {
       prog_args[0] = "cmd";
       prog_args[1] = "/c";
     }
 #endif
+#if DOSISH
+  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.17.orig/src/m4.c m4-1.4.17/src/m4.c
--- m4-1.4.17.orig/src/m4.c	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/src/m4.c	2015-07-25 23:29:28 -0502
@@ -253,15 +253,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);
@@ -377,10 +387,11 @@ main (int argc, char *const *argv)
   const char *frozen_file_to_read = NULL;
   const char *frozen_file_to_write = NULL;
   const char *macro_sequence = "";
 
   set_program_name (argv[0]);
+  STRIP_FULL_PATH_AND_EXTENSION (argv[0]);
   retcode = EXIT_SUCCESS;
   atexit (close_stdin);
 
   include_init ();
   debug_init ();
diff -aprNU5 m4-1.4.17.orig/src/m4.h m4-1.4.17/src/m4.h
--- m4-1.4.17.orig/src/m4.h	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/src/m4.h	2015-07-25 23:29:28 -0502
@@ -69,10 +69,71 @@
 #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
+#  define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+# 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.  */
+
+#ifdef FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+
+# include <libc/unconst.h>
+# undef  IS_SLASH
+# define IS_SLASH(c)             ((c) == '/' || (c) == '\\' || (c) == ':')
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)     (IS_SLASH(c) || (c) == ':')
+# define HAVE_LFN_SUPPORT(name)  ((pathconf((name), _PC_NAME_MAX) > 12) ? true : false)
+
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)     \
+  (__gnuc_extension__                                 \
+    ({                                                \
+       char *_dst, *_src;                             \
+       _dst = _src = unconst((file_name), char *);    \
+       while (*_src++)                                \
+         ;                                            \
+       while ((_src - _dst) && (*--_src != '.'))      \
+         ;                                            \
+       for (*_src = '\0'; (_src - _dst); _src--)      \
+         if (IS_DIR_SEPARATOR(*_src))                 \
+           break;                                     \
+       if (_src - _dst)                               \
+         while ((*_dst++ = *++_src))                  \
+           ;                                          \
+       (file_name);                                   \
+    })                                                \
+  )
+# define CANONICALIZE_PATH(path)                      \
+  (__gnuc_extension__                                 \
+    ({                                                \
+       if ((path))                                    \
+       {                                              \
+         char *_p = unconst((path), char *);          \
+         for (; *_p; _p++)                            \
+           if (*_p == '\\')                           \
+             *_p = '/';                               \
+       }                                              \
+       (path);                                        \
+    })                                                \
+  )
+#else  /* not DOS/Windows like, i.e., Unix */
+# define HAVE_LFN_SUPPORT(name)                    (true)      /* NO OP */
+# define STRIP_FULL_PATH_AND_EXTENSION(filename)   (filename)  /* NO OP */
+# 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.17.orig/src/output.c m4-1.4.17/src/output.c
--- m4-1.4.17.orig/src/output.c	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/src/output.c	2015-07-25 23:29:28 -0502
@@ -188,11 +188,11 @@ m4_tmpname (int divnum)
 {
   static char *buffer;
   static char *tail;
   if (buffer == NULL)
     {
-      tail = xasprintf ("%s/m4-%d", output_temp_dir->dir_name, INT_MAX);
+      tail = xasprintf (HAVE_LFN_SUPPORT(output_temp_dir->dir_name) ? "%s/m4-%d" : "%s/%d.m4", output_temp_dir->dir_name, INT_MAX);
       buffer = (char *) obstack_copy0 (&diversion_storage, tail,
                                        strlen (tail));
       free (tail);
       tail = strrchr (buffer, '-') + 1;
     }
@@ -475,10 +475,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.17.orig/src/path.c m4-1.4.17/src/path.c
--- m4-1.4.17.orig/src/path.c	2013-09-22 05:50:42 -0502
+++ m4-1.4.17/src/path.c	2015-07-25 23:29:28 -0502
@@ -50,10 +50,16 @@ void
 include_env_init (void)
 {
   char *path;
   char *path_end;
   char *env_path;
+  char path_sep = ':';
+#ifdef 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);
