2007-02-04  Juan Manuell Guerrero  <juan.guerrero@gmx.de>

	* lib/cloexec.c (set_cloexec_flag): On MSDOS/Windows systems
	always return success.
	* lib/tempname.c (direxists): Use ISSLASH to check for the
	OS dependent directory separator character. 
	* src/m4.c (main): Added GET_PROGRAM_NAME. On DJGPP systems
	it strips the complete path and extension from argv[0]. For
	all other systems it simply copies argv[0] to the variable.
	* src/m4.h: Added O_BINARY. This macro is used to define a
	serie of macros to parametrize OS specific issues like path
	separators, directory separators, drive letters, etc.
	* 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 no-op macro.
	* src/path.c (include_env_init): Use PATH_SEP to check for the
	OS dependent path separator character. 
	(path_search): Use IS_ABSOLUTE to check for the OS dependent
	form of an absolute path.



diff -aprNU5 m4-1.4.8.orig/lib/cloexec.c m4-1.4.8/lib/cloexec.c
--- m4-1.4.8.orig/lib/cloexec.c	2006-09-24 04:28:32 +0000
+++ m4-1.4.8/lib/cloexec.c	2007-02-04 22:58:30 +0000
@@ -34,11 +34,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 alwasy 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.8.orig/lib/tempname.c m4-1.4.8/lib/tempname.c
--- m4-1.4.8.orig/lib/tempname.c	2006-11-20 14:23:08 +0000
+++ m4-1.4.8/lib/tempname.c	2007-02-04 04:37:08 +0000
@@ -107,10 +107,22 @@
    which is better than not having mkstemp at all.  */
 #if !defined UINT64_MAX && !defined uint64_t
 # define uint64_t uintmax_t
 #endif
 
+/* 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 ISSLASH(C) ((C) == '/' || (C) == '\\')
+#else
+  /* Unix */
+# define ISSLASH(C) ((C) == '/')
+#endif
+
+
 #if _LIBC
 /* Return nonzero if DIR is an existent directory.  */
 static int
 direxists (const char *dir)
 {
@@ -165,11 +177,11 @@ __path_search (char *tmpl, size_t tmpl_l
 	  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.8.orig/src/m4.c m4-1.4.8/src/m4.c
--- m4-1.4.8.orig/src/m4.c	2006-11-20 13:55:46 +0000
+++ m4-1.4.8/src/m4.c	2007-02-04 03:07:02 +0000
@@ -316,11 +316,11 @@ main (int argc, char *const *argv, char 
   bool seen_file = false;
   const char *debugfile = NULL;
   const char *frozen_file_to_read = NULL;
   const char *frozen_file_to_write = NULL;
 
-  program_name = argv[0];
+  GET_PROGRAM_NAME(program_name, argv[0]);
   retcode = EXIT_SUCCESS;
   atexit (close_stdout);
 
   include_init ();
   debug_init ();
diff -aprNU5 m4-1.4.8.orig/src/m4.h m4-1.4.8/src/m4.h
--- m4-1.4.8.orig/src/m4.h	2006-11-20 13:55:46 +0000
+++ m4-1.4.8/src/m4.h	2007-02-04 02:39:36 +0000
@@ -63,10 +63,66 @@
 /* Canonicalize OS/2 recognition macro.  */
 #ifdef __EMX__
 # define OS2 1
 #endif
 
+/* MS-DOS and similar non-Posix systems have some peculiarities:
+    - they distinguish between binary and text files;
+    - they use both `/' and `\\' as directory separator in file names;
+    - they can have a drive letter X: prepended to a file name;
+    - they have a separate root directory on each drive;
+    - their filesystems are case-insensitive;
+    - directories in environment variables (like PATH) are separated
+        by `;' rather than `:';
+    - text files can have their lines ended either with \n or with \r\n pairs.
+   These are all parameterized here.  */
+
+#if O_BINARY
+# ifdef __MSDOS__
+#  ifdef __DJGPP__
+#   ifndef HAVE_LC_MESSAGES
+#    define LC_MESSAGES (-1)
+#   endif
+#   define GET_PROGRAM_NAME(progname, name)  \
+    do {                                     \
+      char *p, *my_program_name;             \
+                                             \
+      p = strrchr((name), '/');              \
+      if (p == NULL)                         \
+        p = (name);                          \
+      else                                   \
+        p++;                                 \
+                                             \
+      my_program_name = strdup(p);           \
+      p = strrchr(my_program_name, '.');     \
+      if (p != NULL)                         \
+        *p = '\0';                           \
+                                             \
+      progname = my_program_name;            \
+    } while (0)
+#  endif /* O_BINARY && __DJGPP__ */
+# endif  /* O_BINARY && !__MSDOS__ */
+# ifdef __CYGWIN__
+#  define PATH_SEP                          ':'
+# else  /* O_BINARY && !__CYGWIN__ */
+#  define PATH_SEP                          ';'
+# endif /* O_BINARY && !__CYGWIN__ */
+  /* Back to any O_BINARY system.  */
+# define HAVE_DRIVE(n)                      ((n)[0] && (n)[1] == ':')
+# define IS_SLASH(c)                        ((c) == '/' || (c) == '\\')
+# define IS_ABSOLUTE(n)                     (IS_SLASH((n)[0]) || ((n)[0] && (n)[1] == ':'))
+# ifndef GET_PROGRAM_NAME
+#  define GET_PROGRAM_NAME(progname, name)  do {(progname) = (name);} while (0)
+# endif
+#else  /* not O_BINARY, i.e., Unix */
+# define IS_SLASH(c)                        ((c) == '/')
+# define HAVE_DRIVE(n)                      (0)
+# define IS_ABSOLUTE(n)                     ((n)[0] == '/')
+# define PATH_SEP                           ':'
+# define GET_PROGRAM_NAME(progname, name)   do {(progname) = (name);} while (0)
+#endif /* not O_BINARY */
+
 /* Used for version mismatch, when -R detects a frozen file it can't parse.  */
 #define EXIT_MISMATCH 63
 
 /* Various declarations.  */
 
diff -aprNU5 m4-1.4.8.orig/src/output.c m4-1.4.8/src/output.c
--- m4-1.4.8.orig/src/output.c	2006-11-20 13:55:46 +0000
+++ m4-1.4.8/src/output.c	2007-02-04 20:42:36 +0000
@@ -338,10 +338,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.8.orig/src/path.c m4-1.4.8/src/path.c
--- m4-1.4.8.orig/src/path.c	2006-11-20 13:55:48 +0000
+++ m4-1.4.8/src/path.c	2007-02-04 03:06:40 +0000
@@ -63,11 +63,11 @@ 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';
       add_include_directory (path);
       path = path_end + 1;
     }
@@ -139,11 +139,11 @@ m4_path_search (const char *file, char *
 	*result = xstrdup (file);
       return fp;
     }
 
   /* If file not found, and filename absolute, fail.  */
-  if (*file == '/' || no_gnu_extensions)
+  if (IS_ABSOLUTE(file) || no_gnu_extensions)
     return NULL;
   e = errno;
 
   name = (char *) xmalloc (dir_max_length + 1 + strlen (file) + 1);
 
