(g2-UU+5B73): Add `=decomposition@hanyo-denshi'.
[chise/xemacs-chise.git.1] / src / fileio.c
index 49f9262..64adf94 100644 (file)
@@ -53,13 +53,49 @@ Boston, MA 02111-1307, USA.  */
 #endif /* HPUX_PRE_8_0 */
 #endif /* HPUX */
 
+#if defined(WIN32_NATIVE) || defined(CYGWIN)
+#define WIN32_FILENAMES
 #ifdef WIN32_NATIVE
+#include "nt.h"
+#include <aclapi.h>
+#endif /* WIN32_NATIVE */
+#ifdef CYGWIN
+#include <w32api/aclapi.h>
+#endif
+
+
 #define IS_DRIVE(x) isalpha (x)
 /* Need to lower-case the drive letter, or else expanded
    filenames will sometimes compare inequal, because
    `expand-file-name' doesn't always down-case the drive letter.  */
 #define DRIVE_LETTER(x) tolower (x)
-#endif /* WIN32_NATIVE */
+#ifndef CORRECT_DIR_SEPS
+#define CORRECT_DIR_SEPS(s) \
+  normalize_filename(s, DIRECTORY_SEP)
+/* Default implementation that coerces a file to use path_sep. */
+static void
+normalize_filename (Bufbyte *fp, Bufbyte path_sep)
+{
+  /* Always lower-case drive letters a-z, even if the filesystem
+     preserves case in filenames.
+     This is so filenames can be compared by string comparison
+     functions that are case-sensitive.  Even case-preserving filesystems
+     do not distinguish case in drive letters.  */
+  if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z')
+    {
+      *fp += 'a' - 'A';
+      fp += 2;
+    }
+
+  while (*fp)
+    {
+      if (*fp == '/' || *fp == '\\')
+       *fp = path_sep;
+      fp++;
+    }
+}
+#endif /* CORRECT_DIR_SEPS */
+#endif /* WIN32_NATIVE || CYGWIN */
 
 int lisp_to_time (Lisp_Object, time_t *);
 Lisp_Object time_to_lisp (time_t);
@@ -94,6 +130,12 @@ Lisp_Object Vwrite_region_annotations_so_far;
 /* File name in which we write a list of all our auto save files.  */
 Lisp_Object Vauto_save_list_file_name;
 
+/* Prefix used to construct Vauto_save_list_file_name. */
+Lisp_Object Vauto_save_list_file_prefix;
+
+/* When non-nil, it prevents auto-save list file creation. */
+int inhibit_auto_save_session;
+
 int disable_auto_save_when_buffer_shrinks;
 
 Lisp_Object Vdirectory_sep_char;
@@ -328,6 +370,8 @@ If OPERATION equals `inhibit-file-name-operation', then we ignore
 any handlers that are members of `inhibit-file-name-handlers',
 but we still do run any other handlers.  This lets handlers
 use the standard functions without calling themselves recursively.
+
+Otherwise, OPERATION is the name of a funcall'able function.
 */
        (filename, operation))
 {
@@ -393,34 +437,34 @@ call3_check_string (Lisp_Object fn, Lisp_Object arg0,
 
 \f
 DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /*
-Return the directory component in file name NAME.
-Return nil if NAME does not include a directory.
+Return the directory component in file name FILENAME.
+Return nil if FILENAME does not include a directory.
 Otherwise return a directory spec.
 Given a Unix syntax file name, returns a string ending in slash.
 */
-       (file))
+       (filename))
 {
   /* This function can GC.  GC checked 2000-07-28 ben */
   Bufbyte *beg;
   Bufbyte *p;
   Lisp_Object handler;
 
-  CHECK_STRING (file);
+  CHECK_STRING (filename);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (file, Qfile_name_directory);
+  handler = Ffind_file_name_handler (filename, Qfile_name_directory);
   if (!NILP (handler))
-    return call2_check_string_or_nil (handler, Qfile_name_directory, file);
+    return call2_check_string_or_nil (handler, Qfile_name_directory, filename);
 
 #ifdef FILE_SYSTEM_CASE
-  file = FILE_SYSTEM_CASE (file);
+  filename = FILE_SYSTEM_CASE (filename);
 #endif
-  beg = XSTRING_DATA (file);
-  p = beg + XSTRING_LENGTH (file);
+  beg = XSTRING_DATA (filename);
+  p = beg + XSTRING_LENGTH (filename);
 
   while (p != beg && !IS_ANY_SEP (p[-1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
         /* only recognize drive specifier at beginning */
         && !(p[-1] == ':' && p == beg + 2)
 #endif
@@ -452,30 +496,30 @@ Given a Unix syntax file name, returns a string ending in slash.
 }
 
 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /*
-Return file name NAME sans its directory.
+Return file name FILENAME sans its directory.
 For example, in a Unix-syntax file name,
 this is everything after the last slash,
 or the entire name if it contains no slash.
 */
-       (file))
+       (filename))
 {
   /* This function can GC.  GC checked 2000-07-28 ben */
   Bufbyte *beg, *p, *end;
   Lisp_Object handler;
 
-  CHECK_STRING (file);
+  CHECK_STRING (filename);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (file, Qfile_name_nondirectory);
+  handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
   if (!NILP (handler))
-    return call2_check_string (handler, Qfile_name_nondirectory, file);
+    return call2_check_string (handler, Qfile_name_nondirectory, filename);
 
-  beg = XSTRING_DATA (file);
-  end = p = beg + XSTRING_LENGTH (file);
+  beg = XSTRING_DATA (filename);
+  end = p = beg + XSTRING_LENGTH (filename);
 
   while (p != beg && !IS_ANY_SEP (p[-1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
         /* only recognize drive specifier at beginning */
         && !(p[-1] == ':' && p == beg + 2)
 #endif
@@ -493,7 +537,7 @@ If FILENAME is a directly usable file itself, return
 The `call-process' and `start-process' functions use this function to
 get a current directory to run processes in.
 */
-  (filename))
+       (filename))
 {
   /* This function can GC.  GC checked 2000-07-28 ben */
   Lisp_Object handler;
@@ -543,23 +587,23 @@ or passed as second argument to `expand-file-name'.
 For a Unix-syntax file name, just appends a slash,
 except for (file-name-as-directory \"\") => \"./\".
 */
-       (file))
+       (filename))
 {
   /* This function can GC.  GC checked 2000-07-28 ben */
   char *buf;
   Lisp_Object handler;
 
-  CHECK_STRING (file);
+  CHECK_STRING (filename);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
+  handler = Ffind_file_name_handler (filename, Qfile_name_as_directory);
   if (!NILP (handler))
-    return call2_check_string (handler, Qfile_name_as_directory, file);
+    return call2_check_string (handler, Qfile_name_as_directory, filename);
 
-  buf = (char *) alloca (XSTRING_LENGTH (file) + 10);
+  buf = (char *) alloca (XSTRING_LENGTH (filename) + 10);
   return build_string (file_name_as_directory
-                      (buf, (char *) XSTRING_DATA (file)));
+                      (buf, (char *) XSTRING_DATA (filename)));
 }
 \f
 /*
@@ -579,17 +623,17 @@ directory_file_name (const char *src, char *dst)
   strcpy (dst, src);
   if (slen > 1
       && IS_DIRECTORY_SEP (dst[slen - 1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
       && !IS_ANY_SEP (dst[slen - 2])
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
       )
     dst[slen - 1] = 0;
   return 1;
 }
 
 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /*
-Return the file name of the directory named DIR.
-This is the name of the file that holds the data for the directory DIR.
+Return the file name of the directory named DIRECTORY.
+This is the name of the file that holds the data for the directory.
 This operation exists because a directory is also a file, but its name as
 a directory is different from its name as a file.
 In Unix-syntax, this function just removes the final slash.
@@ -731,7 +775,7 @@ DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /*
 Convert filename NAME to absolute, and canonicalize it.
 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
  (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,
-the current buffer's value of default-directory is used.
+the current buffer's value of `default-directory' is used.
 File name components that are `.' are removed, and
 so are file name components followed by `..', along with the `..' itself;
 note that these simplifications are done without checking the resulting
@@ -742,27 +786,28 @@ See also the function `substitute-in-file-name'.
 */
        (name, default_directory))
 {
-  /* This function can GC.  GC-checked 2000-07-11 ben */
+  /* This function can GC.  GC-checked 2000-11-18 */
   Bufbyte *nm;
 
   Bufbyte *newdir, *p, *o;
   int tlen;
   Bufbyte *target;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   int drive = 0;
   int collapse_newdir = 1;
-#else
+#endif
+#ifndef WIN32_NATIVE
   struct passwd *pw;
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
   int length;
-  Lisp_Object handler;
+  Lisp_Object handler = Qnil;
 #ifdef CYGWIN
   char *user;
 #endif
-  struct gcpro gcpro1, gcpro2;
+  struct gcpro gcpro1, gcpro2, gcpro3;
 
   /* both of these get set below */
-  GCPRO2 (name, default_directory);
+  GCPRO3 (name, default_directory, handler);
 
   CHECK_STRING (name);
 
@@ -770,11 +815,8 @@ See also the function `substitute-in-file-name'.
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (name, Qexpand_file_name);
   if (!NILP (handler))
-    {
-      UNGCPRO;
-      return call3_check_string (handler, Qexpand_file_name, name,
-                                default_directory);
-    }
+    RETURN_UNGCPRO (call3_check_string (handler, Qexpand_file_name,
+                                       name, default_directory));
 
   /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted.  */
   if (NILP (default_directory))
@@ -786,10 +828,8 @@ See also the function `substitute-in-file-name'.
     {
       handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
       if (!NILP (handler))
-       {
-         UNGCPRO;
-         return call3 (handler, Qexpand_file_name, name, default_directory);
-       }
+       RETURN_UNGCPRO (call3 (handler, Qexpand_file_name,
+                              name, default_directory));
     }
 
   o = XSTRING_DATA (default_directory);
@@ -808,14 +848,13 @@ See also the function `substitute-in-file-name'.
       /* Save time in some common cases - as long as default_directory
         is not relative, it can be canonicalized with name below (if it
         is needed at all) without requiring it to be expanded now.  */
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
       /* Detect Windows file names with drive specifiers.  */
       && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
       /* Detect Windows file names in UNC format.  */
       && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
-
-#else /* not WIN32_NATIVE */
-
+#endif /* not WIN32_FILENAMES */
+#ifndef WIN32_NATIVE
       /* Detect Unix absolute file names (/... alone is not absolute on
         Windows).  */
       && ! (IS_DIRECTORY_SEP (o[0]))
@@ -832,10 +871,11 @@ See also the function `substitute-in-file-name'.
     into name should be safe during all of this, though. */
   nm = XSTRING_DATA (name);
 
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   /* We will force directory separators to be either all \ or /, so make
      a local copy to modify, even if there ends up being no change. */
-  nm = strcpy ((char *)alloca (strlen ((char *)nm) + 1), (char *)nm);
+  nm = (Bufbyte *) strcpy ((char *) alloca (strlen ((char *) nm) + 1),
+                          (char *) nm);
 
   /* Find and remove drive specifier if present; this makes nm absolute
      even if the rest of the name appears to be relative. */
@@ -843,6 +883,7 @@ See also the function `substitute-in-file-name'.
     Bufbyte *colon = (Bufbyte *) strrchr ((char *)nm, ':');
 
     if (colon)
+      {
       /* Only recognize colon as part of drive specifier if there is a
         single alphabetic character preceding the colon (and if the
         character before the drive letter, if present, is a directory
@@ -863,6 +904,7 @@ See also the function `substitute-in-file-name'.
            if (colon[0] == ':')
              goto look_again;
        }
+      }
   }
 
   /* If we see "c://somedir", we want to strip the first slash after the
@@ -870,7 +912,7 @@ See also the function `substitute-in-file-name'.
      "//somedir".  */
   if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
     nm++;
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
 
   /* If nm is absolute, look for /./ or /../ sequences; if none are
      found, we can probably return right away.  We will avoid allocating
@@ -908,25 +950,30 @@ See also the function `substitute-in-file-name'.
        }
       if (!lose)
        {
-#ifdef WIN32_NATIVE
-         /* Make sure directories are all separated with / or \ as
-            desired, but avoid allocation of a new string when not
-            required. */
-         CORRECT_DIR_SEPS (nm);
-         if (IS_DIRECTORY_SEP (nm[1]))
+#ifdef WIN32_FILENAMES
+         if (drive || IS_DIRECTORY_SEP (nm[1]))
            {
-             if (strcmp (nm, XSTRING_DATA (name)) != 0)
-               name = build_string (nm);
-           }
-         /* drive must be set, so this is okay */
-         else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0)
-           {
-             name = make_string (nm - 2, p - nm + 2);
-             XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
-             XSTRING_DATA (name)[1] = ':';
+             /* Make sure directories are all separated with / or \ as
+                desired, but avoid allocation of a new string when not
+                required. */
+             CORRECT_DIR_SEPS (nm);
+             if (IS_DIRECTORY_SEP (nm[1]))
+               {
+                 if (strcmp ((char *) nm, (char *) XSTRING_DATA (name)) != 0)
+                   name = build_string ((Bufbyte *) nm);
+               }
+             /* drive must be set, so this is okay */
+             else if (strcmp ((char *) nm - 2,
+                              (char *) XSTRING_DATA (name)) != 0)
+               {
+                 name = make_string (nm - 2, p - nm + 2);
+                 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
+                 XSTRING_DATA (name)[1] = ':';
+               }
+             RETURN_UNGCPRO (name);
            }
-         RETURN_UNGCPRO (name);
-#else /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
+#ifndef WIN32_NATIVE
          if (nm == XSTRING_DATA (name))
            RETURN_UNGCPRO (name);
          RETURN_UNGCPRO (build_string ((char *) nm));
@@ -967,7 +1014,7 @@ See also the function `substitute-in-file-name'.
                                Qfile_name);
 
          nm++;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
          collapse_newdir = 0;
 #endif
        }
@@ -979,23 +1026,11 @@ See also the function `substitute-in-file-name'.
          memcpy (o, (char *) nm, p - nm);
          o [p - nm] = 0;
 
-         /* #### marcpa's syncing note: FSF uses getpwnam even on NT,
-            which does not work.  The following works only if ~USER
-            names the user who runs this instance of XEmacs.  While
-            NT is single-user (for the moment) you still can have
-            multiple user profiles users defined, each with its HOME.
-            Therefore, the following should be reworked to handle
-            this case.  */
-#ifdef  WIN32_NATIVE
-         /* Now if the file given is "~foo/file" and HOME="c:/", then
-            we want the file to be named "c:/file" ("~foo" becomes
-            "c:/").  The variable o has "~foo", so we can use the
-            length of that string to offset nm.  August Hill, 31 Aug
-            1998.  */
-         newdir = (Bufbyte *) get_home_directory();
-         dostounix_filename (newdir);
-         nm += strlen(o) + 1;
-#else  /* not WIN32_NATIVE */
+         /* #### While NT is single-user (for the moment) you still
+            can have multiple user profiles users defined, each with
+            its HOME.  So maybe possibly we should think about handling
+            ~user. --ben */
+#ifndef WIN32_NATIVE
 #ifdef CYGWIN
          if ((user = user_login_name (NULL)) != NULL)
            {
@@ -1029,29 +1064,31 @@ See also the function `substitute-in-file-name'.
        }
     }
 
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   /* On DOS and Windows, nm is absolute if a drive name was specified;
      use the drive's current directory as the prefix if needed.  */
   if (!newdir && drive)
     {
+#ifdef WIN32_NATIVE
       /* Get default directory if needed to make nm absolute. */
       if (!IS_DIRECTORY_SEP (nm[0]))
        {
-         newdir = alloca (MAXPATHLEN + 1);
+         newdir = (Bufbyte *) alloca (MAXPATHLEN + 1);
          if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
            newdir = NULL;
        }
+#endif /* WIN32_NATIVE */
       if (!newdir)
        {
          /* Either nm starts with /, or drive isn't mounted. */
-         newdir = alloca (4);
+         newdir = (Bufbyte *) alloca (4);
          newdir[0] = DRIVE_LETTER (drive);
          newdir[1] = ':';
          newdir[2] = '/';
          newdir[3] = 0;
        }
     }
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
 
   /* Finally, if no prefix has been specified and nm is not absolute,
      then it must be expanded relative to default_directory. */
@@ -1060,7 +1097,8 @@ See also the function `substitute-in-file-name'.
 #ifndef WIN32_NATIVE
       /* /... alone is not absolute on DOS and Windows. */
       && !IS_DIRECTORY_SEP (nm[0])
-#else
+#endif
+#ifdef WIN32_FILENAMES
       && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
 #endif
       && !newdir)
@@ -1068,7 +1106,7 @@ See also the function `substitute-in-file-name'.
       newdir = XSTRING_DATA (default_directory);
     }
 
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   if (newdir)
     {
       /* First ensure newdir is an absolute name. */
@@ -1080,6 +1118,10 @@ See also the function `substitute-in-file-name'.
          && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
          /* Detect drive spec by itself */
          && ! (IS_DEVICE_SEP (newdir[1]) && newdir[2] == 0)
+         /* Detect unix format.  */
+#ifndef WIN32_NATIVE
+         && ! (IS_DIRECTORY_SEP (newdir[0]))
+#endif
          )
        {
          /* Effectively, let newdir be (expand-file-name newdir cwd).
@@ -1095,19 +1137,22 @@ See also the function `substitute-in-file-name'.
            }
          if (!IS_DIRECTORY_SEP (nm[0]))
            {
-             char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
-             file_name_as_directory (tmp, newdir);
-             strcat (tmp, nm);
+             Bufbyte *tmp = (Bufbyte *) alloca (strlen ((char *) newdir) +
+                                                strlen ((char *) nm) + 2);
+             file_name_as_directory ((char *) tmp, (char *) newdir);
+             strcat ((char *) tmp, (char *) nm);
              nm = tmp;
            }
-         newdir = alloca (MAXPATHLEN + 1);
+         newdir = (Bufbyte *) alloca (MAXPATHLEN + 1);
          if (drive)
            {
+#ifdef WIN32_NATIVE
              if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
-               newdir = "/";
+#endif
+               newdir = (Bufbyte *) "/";
            }
          else
-           getwd (newdir);
+           getcwd ((char *) newdir, MAXPATHLEN);
        }
 
       /* Strip off drive name from prefix, if present. */
@@ -1119,11 +1164,18 @@ See also the function `substitute-in-file-name'.
 
       /* Keep only a prefix from newdir if nm starts with slash
          (/ /server/share for UNC, nothing otherwise).  */
-      if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
+      if (IS_DIRECTORY_SEP (nm[0]) 
+#ifndef WIN32_NATIVE
+         && IS_DIRECTORY_SEP (nm[1])
+#endif
+         && collapse_newdir)
        {
          if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
            {
-             newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
+             newdir =
+               (Bufbyte *)
+                 strcpy ((char *) alloca (strlen ((char *) newdir) + 1),
+                         (char *) newdir);
              p = newdir + 2;
              while (*p && !IS_DIRECTORY_SEP (*p)) p++;
              p++;
@@ -1131,10 +1183,10 @@ See also the function `substitute-in-file-name'.
              *p = 0;
            }
          else
-           newdir = "";
+           newdir = (Bufbyte *) "";
        }
     }
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
 
   if (newdir)
     {
@@ -1142,7 +1194,7 @@ See also the function `substitute-in-file-name'.
         just // (an incomplete UNC name).  */
       length = strlen ((char *) newdir);
       if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
          && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
 #endif
          )
@@ -1159,14 +1211,14 @@ See also the function `substitute-in-file-name'.
 
   /* Now concatenate the directory and name to new space in the stack frame */
   tlen += strlen ((char *) nm) + 1;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   /* Add reserved space for drive name.  (The Microsoft x86 compiler
      produces incorrect code if the following two lines are combined.)  */
   target = (Bufbyte *) alloca (tlen + 2);
   target += 2;
-#else  /* not WIN32_NATIVE */
+#else  /* not WIN32_FILENAMES */
   target = (Bufbyte *) alloca (tlen);
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
   *target = 0;
 
   if (newdir)
@@ -1215,7 +1267,7 @@ See also the function `substitute-in-file-name'.
            ++o;
          p += 3;
        }
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
       /* if drive is set, we're not dealing with an UNC, so
         multiple dir-seps are redundant (and reportedly cause trouble
         under win95) */
@@ -1228,7 +1280,7 @@ See also the function `substitute-in-file-name'.
        }
     }
 
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
   /* At last, set drive name, except for network file name.  */
   if (drive)
     {
@@ -1236,21 +1288,23 @@ See also the function `substitute-in-file-name'.
       target[0] = DRIVE_LETTER (drive);
       target[1] = ':';
     }
+#ifdef WIN32_NATIVE
   else
     {
       assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]));
     }
+#endif
   CORRECT_DIR_SEPS (target);
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
 
   RETURN_UNGCPRO (make_string (target, o - target));
 }
 
 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /*
-Return the canonical name of the given FILE.
-Second arg DEFAULT is directory to start with if FILE is relative
+Return the canonical name of FILENAME.
+Second arg DEFAULT is directory to start with if FILENAME is relative
  (does not start with slash); if DEFAULT is nil or missing,
- the current buffer's value of default-directory is used.
+ the current buffer's value of `default-directory' is used.
 No component of the resulting pathname will be a symbolic link, as
  in the realpath() function.
 */
@@ -1287,7 +1341,23 @@ No component of the resulting pathname will be a symbolic link, as
     TO_EXTERNAL_FORMAT (LISP_STRING, expanded_name,
                        ALLOCA, (path, elen),
                        Qfile_name);
+
+#if defined(WIN32_FILENAMES) && defined(CYGWIN)
+    /* When using win32 filenames in cygwin we want file-truename to
+       detect that c:/windows == /windows for example. */
+    if ((IS_DIRECTORY_SEP (path[0]) 
+        && (elen == 1 || !IS_DIRECTORY_SEP (path[1])))
+       || (isalpha (path[0])
+           && (elen == 1 || !IS_DEVICE_SEP (path[1])))) {
+      int ltwff2 =
+       cygwin_posix_to_win32_path_list_buf_size (path);
+      p = (Bufbyte *) alloca (ltwff2);
+      cygwin_posix_to_win32_path_list (path, p);
+      path = p;
+    }
+#endif
     p = path;
+
     if (elen > MAXPATHLEN)
       goto toolong;
 
@@ -1316,14 +1386,30 @@ No component of the resulting pathname will be a symbolic link, as
           we just use our own version in realpath.c. */
        for (;;)
          {
-           p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
-           if (p)
-             *p = 0;
+           Extbyte *pos;
+
+#ifdef WIN32_FILENAMES
+           if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1]) 
+               && IS_DIRECTORY_SEP (p[2]))
+             /* don't test c: on windows */
+             p = p+2;
+           else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
+             /* start after // */
+             p = p+1;
+#endif
+           for (pos = p + 1; pos < path + elen; pos++)
+             if (IS_DIRECTORY_SEP (*pos))
+               {
+                 *(p = pos) = 0;
+                 break;
+               }
+           if (p != pos)
+             p = 0;
 
            if (xrealpath ((char *) path, resolved_path))
              {
                if (p)
-                 *p = '/';
+                 *p = DIRECTORY_SEP;
                else
                  break;
 
@@ -1342,13 +1428,13 @@ No component of the resulting pathname will be a symbolic link, as
                  {
                    int plen = elen - (p - path);
 
-                   if (rlen > 1 && resolved_path[rlen - 1] == '/')
+                   if (rlen > 1 && IS_DIRECTORY_SEP (resolved_path[rlen - 1]))
                      rlen = rlen - 1;
 
                    if (plen + rlen + 1 > countof (resolved_path))
                      goto toolong;
 
-                   resolved_path[rlen] = '/';
+                   resolved_path[rlen] = DIRECTORY_SEP;
                    memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1);
                  }
                break;
@@ -1361,12 +1447,12 @@ No component of the resulting pathname will be a symbolic link, as
     {
       Lisp_Object resolved_name;
       int rlen = strlen (resolved_path);
-      if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/'
-          && !(rlen > 0 && resolved_path[rlen - 1] == '/'))
+      if (elen > 0 && IS_DIRECTORY_SEP (XSTRING_BYTE (expanded_name, elen - 1))
+          && !(rlen > 0 && IS_DIRECTORY_SEP (resolved_path[rlen - 1])))
        {
          if (rlen + 1 > countof (resolved_path))
            goto toolong;
-         resolved_path[rlen++] = '/';
+         resolved_path[rlen++] = DIRECTORY_SEP;
          resolved_path[rlen] = '\0';
        }
       TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen),
@@ -1389,12 +1475,11 @@ DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /*
 Substitute environment variables referred to in FILENAME.
 `$FOO' where FOO is an environment variable name means to substitute
 the value of that variable.  The variable name should be terminated
-with a character not a letter, digit or underscore; otherwise, enclose
+with a character, not a letter, digit or underscore; otherwise, enclose
 the entire variable name in braces.
 If `/~' appears, all of FILENAME through that `/' is discarded.
-
 */
-       (string))
+       (filename))
 {
   /* This function can GC.  GC checked 2000-07-28 ben. */
   Bufbyte *nm;
@@ -1406,29 +1491,29 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
   Bufbyte *xnm;
   Lisp_Object handler;
 
-  CHECK_STRING (string);
+  CHECK_STRING (filename);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (string, Qsubstitute_in_file_name);
+  handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
   if (!NILP (handler))
     return call2_check_string_or_nil (handler, Qsubstitute_in_file_name,
-                                     string);
+                                     filename);
 
-  nm = XSTRING_DATA (string);
-  endp = nm + XSTRING_LENGTH (string);
+  nm = XSTRING_DATA (filename);
+  endp = nm + XSTRING_LENGTH (filename);
 
   /* If /~ or // appears, discard everything through first slash. */
 
   for (p = nm; p != endp; p++)
     {
       if ((p[0] == '~'
-#if defined (WIN32_NATIVE) || defined (CYGWIN)
+#if defined (WIN32_FILENAMES)
           /* // at start of file name is meaningful in WindowsNT systems */
           || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
-#else /* not (WIN32_NATIVE || CYGWIN) */
+#else /* not (WIN32_FILENAMES) */
           || IS_DIRECTORY_SEP (p[0])
-#endif /* not (WIN32_NATIVE || CYGWIN) */
+#endif /* not (WIN32_FILENAMES) */
           )
          && p != nm
          && (IS_DIRECTORY_SEP (p[-1])))
@@ -1436,7 +1521,7 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
          nm = p;
          substituted = 1;
        }
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
       /* see comment in expand-file-name about drive specifiers */
       else if (IS_DRIVE (p[0]) && p[1] == ':'
               && p > nm && IS_DIRECTORY_SEP (p[-1]))
@@ -1444,7 +1529,7 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
          nm = p;
          substituted = 1;
        }
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
     }
 
   /* See if any variables are substituted into the string
@@ -1496,11 +1581,11 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
       }
 
   if (!substituted)
-    return string;
+    return filename;
 
-  /* If substitution required, recopy the string and do it */
+  /* If substitution required, recopy the filename and do it */
   /* Make space in stack frame for the new copy */
-  xnm = (Bufbyte *) alloca (XSTRING_LENGTH (string) + total + 1);
+  xnm = (Bufbyte *) alloca (XSTRING_LENGTH (filename) + total + 1);
   x = xnm;
 
   /* Copy the rest of the name through, replacing $ constructs with values */
@@ -1554,16 +1639,16 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
 
   for (p = xnm; p != x; p++)
     if ((p[0] == '~'
-#if defined (WIN32_NATIVE)
+#if defined (WIN32_FILENAMES)
         || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
-#else /* not WIN32_NATIVE */
+#else /* not WIN32_FILENAMES */
         || IS_DIRECTORY_SEP (p[0])
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
         )
        /* don't do p[-1] if that would go off the beginning --jwz */
        && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
       xnm = p;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
     else if (IS_DRIVE (p[0]) && p[1] == ':'
             && p > nm && IS_DIRECTORY_SEP (p[-1]))
        xnm = p;
@@ -1572,13 +1657,13 @@ If `/~' appears, all of FILENAME through that `/' is discarded.
   return make_string (xnm, x - xnm);
 
  badsubst:
-  syntax_error ("Bad format environment-variable substitution", string);
+  syntax_error ("Bad format environment-variable substitution", filename);
  missingclose:
   syntax_error ("Missing \"}\" in environment-variable substitution",
-               string);
+               filename);
  badvar:
   syntax_error_2 ("Substituting nonexistent environment variable",
-                 string, build_string (target));
+                 filename, build_string ((char *) target));
 
   /* NOTREACHED */
   return Qnil; /* suppress compiler warning */
@@ -1662,7 +1747,7 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
 
 DEFUN ("copy-file", Fcopy_file, 2, 4,
        "fCopy file: \nFCopy %s to file: \np\nP", /*
-Copy FILE to NEWNAME.  Both args must be strings.
+Copy FILENAME to NEWNAME.  Both args must be strings.
 Signals a `file-already-exists' error if file NEWNAME already exists,
 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
 A number as third arg means request confirmation if NEWNAME already exists.
@@ -1797,8 +1882,7 @@ A prefix arg makes KEEP-TIME non-nil.
            EMACS_TIME atime, mtime;
            EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
            EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
-           if (set_file_times ((char *) XSTRING_DATA (newname), atime,
-                               mtime))
+           if (set_file_times (newname, atime, mtime))
              report_file_error ("I/O error", list1 (newname));
          }
        chmod ((const char *) XSTRING_DATA (newname),
@@ -1922,8 +2006,8 @@ internal_delete_file (Lisp_Object filename)
 \f
 DEFUN ("rename-file", Frename_file, 2, 3,
        "fRename file: \nFRename %s to file: \np", /*
-Rename FILE as NEWNAME.  Both args strings.
-If file has names other than FILE, it continues to have those names.
+Rename FILENAME as NEWNAME.  Both args must be strings.
+If file has names other than FILENAME, it continues to have those names.
 Signals a `file-already-exists' error if a file NEWNAME already exists
 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
 A number as third arg means request confirmation if NEWNAME already exists.
@@ -2006,7 +2090,7 @@ This is what happens in interactive use with M-x.
 
 DEFUN ("add-name-to-file", Fadd_name_to_file, 2, 3,
        "fAdd name to file: \nFName to add to %s: \np", /*
-Give FILE additional name NEWNAME.  Both args strings.
+Give FILENAME additional name NEWNAME.  Both args must be strings.
 Signals a `file-already-exists' error if a file NEWNAME already exists
 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
 A number as third arg means request confirmation if NEWNAME already exists.
@@ -2161,7 +2245,7 @@ On Unix, this is a name starting with a `/' or a `~'.
   CHECK_STRING (filename);
   ptr = XSTRING_DATA (filename);
   return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
          || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
 #endif
          ) ? Qt : Qnil;
@@ -2189,11 +2273,86 @@ check_executable (char *filename)
 #endif /* not WIN32_NATIVE */
 }
 
+
+
 /* Return nonzero if file FILENAME exists and can be written.  */
 
 static int
 check_writable (const char *filename)
 {
+#if defined(WIN32_NATIVE) || defined(CYGWIN)
+#ifdef CYGWIN
+  char filename_buffer[PATH_MAX];
+#endif
+  // Since this has to work for a directory, we can't just call 'CreateFile'
+  PSECURITY_DESCRIPTOR pDesc; /* Must be freed with LocalFree */
+  /* these need not be freed, they point into pDesc */
+  PSID psidOwner;
+  PSID psidGroup;
+  PACL pDacl;
+  PACL pSacl;
+  /* end of insides of descriptor */
+  DWORD error;
+  DWORD attributes;
+  HANDLE tokenHandle;
+  GENERIC_MAPPING genericMapping;
+  DWORD accessMask;
+  PRIVILEGE_SET PrivilegeSet;
+  DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET );
+  BOOL fAccessGranted = FALSE;
+  DWORD dwAccessAllowed;
+
+#ifdef CYGWIN
+  cygwin_conv_to_full_win32_path(filename, filename_buffer);
+  filename = filename_buffer;
+#endif
+
+  // First check for a normal file with the old-style readonly bit
+  attributes = GetFileAttributes(filename);
+  if (FILE_ATTRIBUTE_READONLY == (attributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY)))
+    return 0;
+
+  /* Win32 prototype lacks const. */
+  error = GetNamedSecurityInfo((LPTSTR)filename, SE_FILE_OBJECT, 
+                               DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION,
+                               &psidOwner, &psidGroup, &pDacl, &pSacl, &pDesc);
+  if (error != ERROR_SUCCESS) { // FAT?
+    attributes = GetFileAttributes(filename);
+    return (attributes & FILE_ATTRIBUTE_DIRECTORY) || (0 == (attributes & FILE_ATTRIBUTE_READONLY));
+  }
+
+  genericMapping.GenericRead = FILE_GENERIC_READ;
+  genericMapping.GenericWrite = FILE_GENERIC_WRITE;
+  genericMapping.GenericExecute = FILE_GENERIC_EXECUTE;
+  genericMapping.GenericAll = FILE_ALL_ACCESS;
+
+  if (!ImpersonateSelf(SecurityDelegation)) {
+    return 0;
+  }
+  if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &tokenHandle)) {
+      return 0;
+  }
+
+  accessMask = GENERIC_WRITE;
+  MapGenericMask(&accessMask, &genericMapping);
+
+  if (!AccessCheck(pDesc, tokenHandle, accessMask, &genericMapping,
+                   &PrivilegeSet,       // receives privileges used in check
+                   &dwPrivSetSize,      // size of PrivilegeSet buffer
+                   &dwAccessAllowed,    // receives mask of allowed access rights
+                   &fAccessGranted)) 
+  {
+    DWORD oops = GetLastError();
+    CloseHandle(tokenHandle);
+    RevertToSelf();
+    LocalFree(pDesc);
+    return 0;
+  }
+  CloseHandle(tokenHandle);
+  RevertToSelf();
+  LocalFree(pDesc);
+  return fAccessGranted == TRUE;
+#else
 #ifdef HAVE_EACCESS
   return (eaccess (filename, W_OK) >= 0);
 #else
@@ -2204,6 +2363,7 @@ check_writable (const char *filename)
      but would lose for directories.  */
   return (access (filename, W_OK) >= 0);
 #endif
+#endif
 }
 
 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /*
@@ -2279,14 +2439,14 @@ See also `file-exists-p' and `file-attributes'.
   if (!NILP (handler))
     RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
 
-#if defined(WIN32_NATIVE) || defined(CYGWIN)
+#if defined(WIN32_FILENAMES)
   /* Under MS-DOS and Windows, open does not work for directories.  */
   UNGCPRO;
   if (access (XSTRING_DATA (abspath), 0) == 0)
     return Qt;
   else
     return Qnil;
-#else /* not WIN32_NATIVE */
+#else /* not WIN32_FILENAMES */
   {
     int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0);
     UNGCPRO;
@@ -2295,7 +2455,7 @@ See also `file-exists-p' and `file-attributes'.
     close (desc);
     return Qt;
   }
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
 }
 
 /* Having this before file-symlink-p mysteriously caused it to be forgotten
@@ -2494,7 +2654,7 @@ This is the sort of file that holds an ordinary stream of data bytes.
 }
 \f
 DEFUN ("file-modes", Ffile_modes, 1, 1, 0, /*
-Return mode bits of FILE, as an integer.
+Return mode bits of file named FILENAME, as an integer.
 */
        (filename))
 {
@@ -2531,7 +2691,7 @@ Return mode bits of FILE, as an integer.
 }
 
 DEFUN ("set-file-modes", Fset_file_modes, 2, 2, 0, /*
-Set mode bits of FILE to MODE (an integer).
+Set mode bits of file named FILENAME to MODE (an integer).
 Only the 12 low bits of MODE are used.
 */
        (filename, mode))
@@ -2563,9 +2723,9 @@ Only the 12 low bits of MODE are used.
 
 DEFUN ("set-default-file-modes", Fset_default_file_modes, 1, 1, 0, /*
 Set the file permission bits for newly created files.
-MASK should be an integer; if a permission's bit in MASK is 1,
-subsequently created files will not have that permission enabled.
-Only the low 9 bits are used.
+The argument MODE should be an integer; if a bit in MODE is 1,
+subsequently created files will not have the permission corresponding
+to that bit enabled.  Only the low 9 bits are used.
 This setting is inherited by subprocesses.
 */
        (mode))
@@ -2669,13 +2829,12 @@ it should be a symbol, and the actual coding system that was used for the
 decoding is stored into it.  It will in general be different from CODESYS
 if CODESYS specifies automatic encoding detection or end-of-line detection.
 
-Currently BEG and END refer to byte positions (as opposed to character
+Currently START and END refer to byte positions (as opposed to character
 positions), even in Mule. (Fixing this is very difficult.)
 */
-       (filename, visit, beg, end, replace, codesys, used_codesys))
+       (filename, visit, start, end, replace, codesys, used_codesys))
 {
   /* This function can call lisp */
-  /* #### dmoore - this function hasn't been checked for gc recently */
   struct stat st;
   int fd;
   int saverrno = 0;
@@ -2720,7 +2879,7 @@ positions), even in Mule. (Fixing this is very difficult.)
   if (!NILP (handler))
     {
       val = call6 (handler, Qinsert_file_contents, filename,
-                  visit, beg, end, replace);
+                  visit, start, end, replace);
       goto handled;
     }
 
@@ -2729,7 +2888,7 @@ positions), even in Mule. (Fixing this is very difficult.)
     CHECK_SYMBOL (used_codesys);
 #endif
 
-  if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) )
+  if ( (!NILP (start) || !NILP (end)) && !NILP (visit) )
     error ("Attempt to visit less than an entire file");
 
   fd = -1;
@@ -2746,7 +2905,7 @@ positions), even in Mule. (Fixing this is very difficult.)
 
 #ifdef S_IFREG
   /* Signal an error if we are accessing a non-regular file, with
-     REPLACE, BEG or END being non-nil.  */
+     REPLACE, START or END being non-nil.  */
   if (!S_ISREG (st.st_mode))
     {
       not_regular = 1;
@@ -2754,21 +2913,22 @@ positions), even in Mule. (Fixing this is very difficult.)
       if (!NILP (visit))
        goto notfound;
 
-      if (!NILP (replace) || !NILP (beg) || !NILP (end))
+      if (!NILP (replace) || !NILP (start) || !NILP (end))
        {
          end_multiple_change (buf, mc_count);
 
-         return Fsignal (Qfile_error,
-                         list2 (build_translated_string("not a regular file"),
-                                filename));
+         RETURN_UNGCPRO
+           (Fsignal (Qfile_error,
+                     list2 (build_translated_string("not a regular file"),
+                            filename)));
        }
     }
 #endif /* S_IFREG */
 
-  if (!NILP (beg))
-    CHECK_INT (beg);
+  if (!NILP (start))
+    CHECK_INT (start);
   else
-    beg = Qzero;
+    start = Qzero;
 
   if (!NILP (end))
     CHECK_INT (end);
@@ -2911,7 +3071,7 @@ positions), even in Mule. (Fixing this is very difficult.)
        same_at_end += overlap;
 
       /* Arrange to read only the nonmatching middle part of the file.  */
-      beg = make_int (same_at_start - BUF_BEGV (buf));
+      start = make_int (same_at_start - BUF_BEGV (buf));
       end = make_int (st.st_size - (BUF_ZV (buf) - same_at_end));
 
       buffer_delete_range (buf, same_at_start, same_at_end,
@@ -2923,7 +3083,7 @@ positions), even in Mule. (Fixing this is very difficult.)
 
   if (!not_regular)
     {
-      total = XINT (end) - XINT (beg);
+      total = XINT (end) - XINT (start);
 
       /* Make sure point-max won't overflow after this insertion.  */
       if (total != XINT (make_int (total)))
@@ -2934,7 +3094,7 @@ positions), even in Mule. (Fixing this is very difficult.)
        will make the stream functions read as much as possible.  */
     total = -1;
 
-  if (XINT (beg) != 0
+  if (XINT (start) != 0
 #ifdef FSFMACS_SPEEDY_INSERT
       /* why was this here? asked jwz.  The reason is that the replace-mode
         connivings above will normally put the file pointer other than
@@ -2943,7 +3103,7 @@ positions), even in Mule. (Fixing this is very difficult.)
 #endif /* !FSFMACS_SPEEDY_INSERT */
       )
     {
-      if (lseek (fd, XINT (beg), 0) < 0)
+      if (lseek (fd, XINT (start), 0) < 0)
        report_file_error ("Setting file position", list1 (filename));
     }
 
@@ -2969,7 +3129,7 @@ positions), even in Mule. (Fixing this is very difficult.)
        occurs inside of the filedesc stream. */
     while (1)
       {
-       ssize_t this_len;
+       Lstream_data_count this_len;
        Charcount cc_inserted;
 
        QUIT;
@@ -3027,6 +3187,9 @@ positions), even in Mule. (Fixing this is very difficult.)
             it could be called here.  But that's just silly.
             There's no reason C code can't call out to Lisp
             code, and it's a lot cleaner this way. */
+         /*  Note: compute-buffer-file-truename is called for
+             side-effect!  Its return value is intentionally
+             ignored. */
          if (!NILP (Ffboundp (Qcompute_buffer_file_truename)))
            call1 (Qcompute_buffer_file_truename, make_buffer (buf));
        }
@@ -3118,6 +3281,11 @@ of the CODESYS argument under XEmacs/Mule. (When Mule support is not
 present, both functions are identical and ignore the CODESYS argument.)
 If support for Mule exists in this Emacs, the file is encoded according
 to the value of CODESYS.  If this is nil, no code conversion occurs.
+
+As a special kludge to support auto-saving, when START is nil START and
+END are set to the beginning and end, respectively, of the buffer,
+regardless of any restrictions.  Don't use this feature.  It is documented
+here because write-region handler writers need to be aware of it.
 */
        (start, end, filename, append, visit, lockname, codesys))
 {
@@ -3386,7 +3554,7 @@ to the value of CODESYS.  If this is nil, no code conversion occurs.
         message ("Wrote %s", XSTRING_DATA (visit_file));
       else
        {
-         Lisp_Object fsp;
+         Lisp_Object fsp = Qnil;
          struct gcpro nngcpro1;
 
          NNGCPRO1 (fsp);
@@ -3647,18 +3815,18 @@ Decrypt STRING using KEY.
 
 \f
 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 1, 1, 0, /*
-Return t if last mod time of BUF's visited file matches what BUF records.
+Return t if last mod time of BUFFER's visited file matches what BUFFER records.
 This means that the file has not been changed since it was visited or saved.
 */
-       (buf))
+       (buffer))
 {
   /* This function can call lisp; GC checked 2000-07-11 ben */
   struct buffer *b;
   struct stat st;
   Lisp_Object handler;
 
-  CHECK_BUFFER (buf);
-  b = XBUFFER (buf);
+  CHECK_BUFFER (buffer);
+  b = XBUFFER (buffer);
 
   if (!STRINGP (b->filename)) return Qt;
   if (b->modtime == 0) return Qt;
@@ -3668,7 +3836,7 @@ This means that the file has not been changed since it was visited or saved.
   handler = Ffind_file_name_handler (b->filename,
                                      Qverify_visited_file_modtime);
   if (!NILP (handler))
-    return call2 (handler, Qverify_visited_file_modtime, buf);
+    return call2 (handler, Qverify_visited_file_modtime, buffer);
 
   if (xemacs_stat ((char *) XSTRING_DATA (b->filename), &st) < 0)
     {
@@ -3727,7 +3895,7 @@ An argument specifies the modification time value to use
     }
   else
     {
-      Lisp_Object filename;
+      Lisp_Object filename = Qnil;
       struct stat st;
       Lisp_Object handler;
       struct gcpro gcpro1, gcpro2, gcpro3;
@@ -3795,8 +3963,8 @@ auto_save_1 (Lisp_Object ignored)
   return
     /* !!#### need to deal with this 'escape-quoted everywhere */
     Fwrite_region_internal (Qnil, Qnil, a, Qnil, Qlambda, Qnil,
-#ifdef MULE
-                           Qescape_quoted
+#ifdef FILE_CODING
+                           current_buffer->buffer_file_coding_system
 #else
                            Qnil
 #endif
@@ -3842,7 +4010,7 @@ do_auto_save_unwind_2 (Lisp_Object old_auto_saving)
    and if so, tries to avoid touching lisp objects.
 
    The only time that Fdo_auto_save() is called while GC is in progress
-   is if we're going down, as a result of an abort() or a kill signal.
+   is if we're going down, as a result of an ABORT() or a kill signal.
    It's fairly important that we generate autosave files in that case!
  */
 
@@ -3982,7 +4150,9 @@ Non-nil second argument means save only current buffer.
              /* Open the auto-save list file, if necessary.
                 We only do this now so that the file only exists
                 if we actually auto-saved any files. */
-             if (!auto_saved && STRINGP (listfile) && listdesc < 0)
+             if (!auto_saved && !inhibit_auto_save_session
+                 && !NILP (Vauto_save_list_file_prefix)
+                 && STRINGP (listfile) && listdesc < 0)
                {
                  listdesc = open ((char *) XSTRING_DATA (listfile),
                                   O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
@@ -4298,6 +4468,18 @@ File name in which we write a list of all auto save file names.
 */ );
   Vauto_save_list_file_name = Qnil;
 
+  DEFVAR_LISP ("auto-save-list-file-prefix", &Vauto_save_list_file_prefix /*
+Prefix for generating auto-save-list-file-name.
+Emacs's pid and the system name will be appended to
+this prefix to create a unique file name.
+*/ );
+  Vauto_save_list_file_prefix = build_string ("~/.saves-");
+
+  DEFVAR_BOOL ("inhibit-auto-save-session", &inhibit_auto_save_session /*
+When non-nil, inhibit auto save list file creation.
+*/ );
+  inhibit_auto_save_session = 0;
+
   DEFVAR_BOOL ("disable-auto-save-when-buffer-shrinks",
               &disable_auto_save_when_buffer_shrinks /*
 If non-nil, auto-saving is disabled when a buffer shrinks too much.