]> code.delx.au - gnu-emacs/blobdiff - src/fileio.c
Merge from emacs-24; up to 2012-05-07T14:57:18Z!michael.albinus@gmx.de
[gnu-emacs] / src / fileio.c
index 6c3a3b206e8966cf63fb8d9ceb50bf2af76f995c..6c4e34d7312dd4f1bfce437cfdefb0f96a82818d 100644 (file)
@@ -23,14 +23,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <setjmp.h>
 #include <unistd.h>
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
 
-#include <ctype.h>
 #include <errno.h>
 
 #ifdef HAVE_LIBSELINUX
@@ -38,6 +36,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <selinux/context.h>
 #endif
 
+#include <c-ctype.h>
+
 #include "lisp.h"
 #include "intervals.h"
 #include "character.h"
@@ -67,12 +67,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
 #endif
 #ifdef WINDOWSNT
-#define IS_DRIVE(x) isalpha ((unsigned char) (x))
+#define IS_DRIVE(x) c_isalpha (x)
 #endif
 /* Need to lower-case the drive letter, or else expanded
    filenames will sometimes compare unequal, because
    `expand-file-name' doesn't always down-case the drive letter.  */
-#define DRIVE_LETTER(x) (tolower ((unsigned char) (x)))
+#define DRIVE_LETTER(x) c_tolower (x)
 #endif
 
 #include "systime.h"
@@ -84,22 +84,18 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "commands.h"
 
-#ifndef FILE_SYSTEM_CASE
-#define FILE_SYSTEM_CASE(filename)  (filename)
-#endif
-
-/* Nonzero during writing of auto-save files.  */
-static int auto_saving;
+/* True during writing of auto-save files.  */
+static bool auto_saving;
 
 /* Nonzero umask during creation of auto-save directories.  */
-static int auto_saving_dir_umask;
+static mode_t auto_saving_dir_umask;
 
 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
    a new file with the same mode as the original.  */
-static int auto_save_mode_bits;
+static mode_t auto_save_mode_bits;
 
 /* Set by auto_save_1 if an error occurred during the last auto-save.  */
-static int auto_save_error_occurred;
+static bool auto_save_error_occurred;
 
 /* The symbol bound to coding-system-for-read when
    insert-file-contents is called for recovering a file.  This is not
@@ -148,10 +144,10 @@ Lisp_Object Qfile_name_history;
 
 static Lisp_Object Qcar_less_than_car;
 
-static int a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
-                    Lisp_Object *, struct coding_system *);
-static int e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
-                   struct coding_system *);
+static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
+                    Lisp_Object *, struct coding_system *);
+static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
+                    struct coding_system *);
 
 \f
 void
@@ -163,8 +159,7 @@ report_file_error (const char *string, Lisp_Object data)
 
   synchronize_system_messages_locale ();
   str = strerror (errorno);
-  errstring = code_convert_string_norecord (make_unibyte_string (str,
-                                                                strlen (str)),
+  errstring = code_convert_string_norecord (build_unibyte_string (str),
                                            Vlocale_coding_system, 0);
 
   while (1)
@@ -334,9 +329,8 @@ Given a Unix syntax file name, returns a string ending in slash.  */)
       return STRINGP (handled_name) ? handled_name : Qnil;
     }
 
-  filename = FILE_SYSTEM_CASE (filename);
 #ifdef DOS_NT
-  beg = (char *) alloca (SBYTES (filename) + 1);
+  beg = alloca (SBYTES (filename) + 1);
   memcpy (beg, SSDATA (filename), SBYTES (filename) + 1);
 #else
   beg = SSDATA (filename);
@@ -365,12 +359,12 @@ Given a Unix syntax file name, returns a string ending in slash.  */)
 
       if (p == beg + 4 && IS_DIRECTORY_SEP (*beg) && beg[1] == ':')
        {
-         strncpy (res, beg, 2);
+         memcpy (res, beg, 2);
          beg += 2;
          r += 2;
        }
 
-      if (getdefdir (toupper ((unsigned char) *beg) - 'A' + 1, r))
+      if (getdefdir (c_toupper (*beg) - 'A' + 1, r))
        {
          if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
            strcat (res, "/");
@@ -453,32 +447,33 @@ get a current directory to run processes in.  */)
   return Ffile_name_directory (filename);
 }
 
-\f
-static char *
-file_name_as_directory (char *out, const char *in)
-{
-  ptrdiff_t len = strlen (in);
+/* Convert from file name SRC of length SRCLEN to directory name
+   in DST.  On UNIX, just make sure there is a terminating /.
+   Return the length of DST.  */
 
-  if (len == 0)
+static ptrdiff_t
+file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen)
+{
+  if (srclen == 0)
     {
-      out[0] = '.';
-      out[1] = '/';
-      out[2] = 0;
-      return out;
+      dst[0] = '.';
+      dst[1] = '/';
+      dst[2] = '\0';
+      return 2;
     }
 
-  strcpy (out, in);
+  strcpy (dst, src);
 
-  /* For Unix syntax, Append a slash if necessary */
-  if (!IS_DIRECTORY_SEP (out[len - 1]))
+  if (!IS_DIRECTORY_SEP (dst[srclen - 1]))
     {
-      out[len] = DIRECTORY_SEP;
-      out[len + 1] = '\0';
+      dst[srclen] = DIRECTORY_SEP;
+      dst[srclen + 1] = '\0';
+      srclen++;
     }
 #ifdef DOS_NT
-  dostounix_filename (out);
+  dostounix_filename (dst);
 #endif
-  return out;
+  return srclen;
 }
 
 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
@@ -492,6 +487,7 @@ For a Unix-syntax file name, just appends a slash.  */)
   (Lisp_Object file)
 {
   char *buf;
+  ptrdiff_t length;
   Lisp_Object handler;
 
   CHECK_STRING (file);
@@ -510,40 +506,35 @@ For a Unix-syntax file name, just appends a slash.  */)
       error ("Invalid handler in `file-name-handler-alist'");
     }
 
-  buf = (char *) alloca (SBYTES (file) + 10);
-  file_name_as_directory (buf, SSDATA (file));
-  return make_specified_string (buf, -1, strlen (buf),
-                               STRING_MULTIBYTE (file));
+  buf = alloca (SBYTES (file) + 10);
+  length = file_name_as_directory (buf, SSDATA (file), SBYTES (file));
+  return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file));
 }
 \f
-/*
- * Convert from directory name to filename.
- * On UNIX, it's simple: just make sure there isn't a terminating /
-
- * Value is nonzero if the string output is different from the input.
- */
+/* Convert from directory name SRC of length SRCLEN to
+   file name in DST.  On UNIX, just make sure there isn't
+   a terminating /.  Return the length of DST.  */
 
-static int
-directory_file_name (char *src, char *dst)
+static ptrdiff_t
+directory_file_name (char *dst, char *src, ptrdiff_t srclen)
 {
-  ptrdiff_t slen;
-
-  slen = strlen (src);
-
   /* Process as Unix format: just remove any final slash.
      But leave "/" unchanged; do not change it to "".  */
   strcpy (dst, src);
-  if (slen > 1
-      && IS_DIRECTORY_SEP (dst[slen - 1])
+  if (srclen > 1
+      && IS_DIRECTORY_SEP (dst[srclen - 1])
 #ifdef DOS_NT
-      && !IS_ANY_SEP (dst[slen - 2])
+      && !IS_ANY_SEP (dst[srclen - 2])
 #endif
       )
-    dst[slen - 1] = 0;
+    {
+      dst[srclen - 1] = 0;
+      srclen--;
+    }
 #ifdef DOS_NT
   dostounix_filename (dst);
 #endif
-  return 1;
+  return srclen;
 }
 
 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
@@ -556,6 +547,7 @@ In Unix-syntax, this function just removes the final slash.  */)
   (Lisp_Object directory)
 {
   char *buf;
+  ptrdiff_t length;
   Lisp_Object handler;
 
   CHECK_STRING (directory);
@@ -575,10 +567,9 @@ In Unix-syntax, this function just removes the final slash.  */)
       error ("Invalid handler in `file-name-handler-alist'");
     }
 
-  buf = (char *) alloca (SBYTES (directory) + 20);
-  directory_file_name (SSDATA (directory), buf);
-  return make_specified_string (buf, -1, strlen (buf),
-                               STRING_MULTIBYTE (directory));
+  buf = alloca (SBYTES (directory) + 20);
+  length = directory_file_name (buf, SSDATA (directory), SBYTES (directory));
+  return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory));
 }
 
 static const char make_temp_name_tbl[64] =
@@ -603,7 +594,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
    which has no existing file.  To make this work, PREFIX should be
    an absolute file name.
 
-   BASE64_P non-zero means add the pid as 3 characters in base64
+   BASE64_P means add the pid as 3 characters in base64
    encoding.  In this case, 6 characters will be added to PREFIX to
    form the file name.  Otherwise, if Emacs is running on a system
    with long file names, add the pid as a decimal number.
@@ -612,7 +603,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
    generated.  */
 
 Lisp_Object
-make_temp_name (Lisp_Object prefix, int base64_p)
+make_temp_name (Lisp_Object prefix, bool base64_p)
 {
   Lisp_Object val;
   int len, clen;
@@ -769,12 +760,12 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
   struct passwd *pw;
 #ifdef DOS_NT
   int drive = 0;
-  int collapse_newdir = 1;
-  int is_escaped = 0;
+  bool collapse_newdir = 1;
+  bool is_escaped = 0;
 #endif /* DOS_NT */
   ptrdiff_t length;
   Lisp_Object handler, result, handled_name;
-  int multibyte;
+  bool multibyte;
   Lisp_Object hdir;
 
   CHECK_STRING (name);
@@ -864,7 +855,6 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
        UNGCPRO;
       }
   }
-  name = FILE_SYSTEM_CASE (name);
   multibyte = STRING_MULTIBYTE (name);
   if (multibyte != STRING_MULTIBYTE (default_directory))
     {
@@ -878,7 +868,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
     }
 
   /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below.  */
-  nm = (char *) alloca (SBYTES (name) + 1);
+  nm = alloca (SBYTES (name) + 1);
   memcpy (nm, SSDATA (name), SBYTES (name) + 1);
 
 #ifdef DOS_NT
@@ -929,10 +919,9 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       /* If it turns out that the filename we want to return is just a
         suffix of FILENAME, we don't need to go through and edit
         things; we just need to construct a new string using data
-        starting at the middle of FILENAME.  If we set lose to a
-        non-zero value, that means we've discovered that we can't do
-        that cool trick.  */
-      int lose = 0;
+        starting at the middle of FILENAME.  If we set LOSE, that
+        means we've discovered that we can't do that cool trick.  */
+      bool lose = 0;
       char *p = nm;
 
       while (*p)
@@ -1063,7 +1052,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       if (!IS_DIRECTORY_SEP (nm[0]))
        {
          adir = alloca (MAXPATHLEN + 1);
-         if (!getdefdir (toupper (drive) - 'A' + 1, adir))
+         if (!getdefdir (c_toupper (drive) - 'A' + 1, adir))
            adir = NULL;
        }
       if (!adir)
@@ -1130,15 +1119,16 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
            }
          if (!IS_DIRECTORY_SEP (nm[0]))
            {
-             char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
-             file_name_as_directory (tmp, newdir);
+             ptrdiff_t newlen = strlen (newdir);
+             char *tmp = alloca (newlen + strlen (nm) + 2);
+             file_name_as_directory (tmp, newdir, newlen);
              strcat (tmp, nm);
              nm = tmp;
            }
          adir = alloca (MAXPATHLEN + 1);
          if (drive)
            {
-             if (!getdefdir (toupper (drive) - 'A' + 1, adir))
+             if (!getdefdir (c_toupper (drive) - 'A' + 1, adir))
                newdir = "/";
            }
          else
@@ -1180,21 +1170,25 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       /* Get rid of any slash at the end of newdir, unless newdir is
         just / or // (an incomplete UNC name).  */
       length = strlen (newdir);
+      tlen = length + 1;
       if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
 #ifdef WINDOWSNT
          && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
 #endif
          )
        {
-         char *temp = (char *) alloca (length);
+         char *temp = alloca (length);
          memcpy (temp, newdir, length - 1);
          temp[length - 1] = 0;
+         length--;
          newdir = temp;
        }
-      tlen = length + 1;
     }
   else
-    tlen = 0;
+    {
+      length = 0;
+      tlen = 0;
+    }
 
   /* Now concatenate the directory and name to new space in the stack frame.  */
   tlen += strlen (nm) + 1;
@@ -1202,10 +1196,10 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
   /* Reserve space for drive specifier and escape prefix, since either
      or both may need to be inserted.  (The Microsoft x86 compiler
      produces incorrect code if the following two lines are combined.)  */
-  target = (char *) alloca (tlen + 4);
+  target = alloca (tlen + 4);
   target += 4;
 #else  /* not DOS_NT */
-  target = (char *) alloca (tlen);
+  target = alloca (tlen);
 #endif /* not DOS_NT */
   *target = 0;
 
@@ -1225,7 +1219,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
            strcpy (target, newdir);
        }
       else
-       file_name_as_directory (target, newdir);
+       file_name_as_directory (target, newdir, length);
     }
 
   strcat (target, nm);
@@ -1298,7 +1292,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
     if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
 #endif /* WINDOWSNT */
       {
-       if (!drive) abort ();
+       if (!drive) emacs_abort ();
        target -= 2;
        target[0] = DRIVE_LETTER (drive);
        target[1] = ':';
@@ -1364,7 +1358,6 @@ See also the function `substitute-in-file-name'.")
   ptrdiff_t tlen;
   unsigned char *target;
   struct passwd *pw;
-  int lose;
 
   CHECK_STRING (name);
   nm = SDATA (name);
@@ -1373,8 +1366,8 @@ See also the function `substitute-in-file-name'.")
      If no /./ or /../ we can return right away.  */
   if (nm[0] == '/')
     {
+      bool lose = 0;
       p = nm;
-      lose = 0;
       while (*p)
        {
          if (p[0] == '/' && p[1] == '/'
@@ -1415,7 +1408,7 @@ See also the function `substitute-in-file-name'.")
        unsigned char *ptr = (unsigned char *) strchr (user, '/');
        ptrdiff_t len = ptr ? ptr - user : strlen (user);
        /* Copy the user name into temp storage.  */
-       o = (unsigned char *) alloca (len + 1);
+       o = alloca (len + 1);
        memcpy (o, user, len);
        o[len] = 0;
 
@@ -1443,7 +1436,7 @@ See also the function `substitute-in-file-name'.")
   /* Now concatenate the directory and name to new space in the stack frame.  */
 
   tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
-  target = (unsigned char *) alloca (tlen);
+  target = alloca (tlen);
   *target = 0;
 
   if (newdir)
@@ -1498,7 +1491,7 @@ See also the function `substitute-in-file-name'.")
 #endif
 \f
 /* If /~ or // appears, discard everything through first slash.  */
-static int
+static bool
 file_name_absolute_p (const char *filename)
 {
   return
@@ -1564,13 +1557,11 @@ If `//' appears, everything up to and including the first of
 those `/' is discarded.  */)
   (Lisp_Object filename)
 {
-  char *nm;
-
-  register char *s, *p, *o, *x, *endp;
+  char *nm, *s, *p, *o, *x, *endp;
   char *target = NULL;
   int total = 0;
-  int substituted = 0;
-  int multibyte;
+  bool substituted = 0;
+  bool multibyte;
   char *xnm;
   Lisp_Object handler;
 
@@ -1593,7 +1584,7 @@ those `/' is discarded.  */)
   /* Always work on a copy of the string, in case GC happens during
      decode of environment variables, causing the original Lisp_String
      data to be relocated.  */
-  nm = (char *) alloca (SBYTES (filename) + 1);
+  nm = alloca (SBYTES (filename) + 1);
   memcpy (nm, SDATA (filename), SBYTES (filename) + 1);
 
 #ifdef DOS_NT
@@ -1640,13 +1631,13 @@ those `/' is discarded.  */)
        else
          {
            o = p;
-           while (p != endp && (isalnum (*p) || *p == '_')) p++;
+           while (p != endp && (c_isalnum (*p) || *p == '_')) p++;
            s = p;
          }
 
        /* Copy out the variable name.  */
-       target = (char *) alloca (s - o + 1);
-       strncpy (target, o, s - o);
+       target = alloca (s - o + 1);
+       memcpy (target, o, s - o);
        target[s - o] = 0;
 #ifdef DOS_NT
        strupr (target); /* $home == $HOME etc.  */
@@ -1662,7 +1653,7 @@ those `/' is discarded.  */)
               env variables twice should be acceptable. Note that
               decoding may cause a garbage collect.  */
            Lisp_Object orig, decoded;
-           orig = make_unibyte_string (o, strlen (o));
+           orig = build_unibyte_string (o);
            decoded = DECODE_FILE (orig);
            total += SBYTES (decoded);
            substituted = 1;
@@ -1676,7 +1667,7 @@ those `/' is discarded.  */)
 
   /* If substitution required, recopy the string and do it.  */
   /* Make space in stack frame for the new copy.  */
-  xnm = (char *) alloca (SBYTES (filename) + total + 1);
+  xnm = alloca (SBYTES (filename) + total + 1);
   x = xnm;
 
   /* Copy the rest of the name through, replacing $ constructs with values.  */
@@ -1703,13 +1694,13 @@ those `/' is discarded.  */)
        else
          {
            o = p;
-           while (p != endp && (isalnum (*p) || *p == '_')) p++;
+           while (p != endp && (c_isalnum (*p) || *p == '_')) p++;
            s = p;
          }
 
        /* Copy out the variable name.  */
-       target = (char *) alloca (s - o + 1);
-       strncpy (target, o, s - o);
+       target = alloca (s - o + 1);
+       memcpy (target, o, s - o);
        target[s - o] = 0;
 #ifdef DOS_NT
        strupr (target); /* $home == $HOME etc.  */
@@ -1730,13 +1721,13 @@ those `/' is discarded.  */)
            orig = make_unibyte_string (o, orig_length);
            decoded = DECODE_FILE (orig);
            decoded_length = SBYTES (decoded);
-           strncpy (x, SSDATA (decoded), decoded_length);
+           memcpy (x, SDATA (decoded), decoded_length);
            x += decoded_length;
 
            /* If environment variable needed decoding, return value
               needs to be multibyte.  */
            if (decoded_length != orig_length
-               || strncmp (SSDATA (decoded), o, orig_length))
+               || memcmp (SDATA (decoded), o, orig_length))
              multibyte = 1;
          }
       }
@@ -1784,7 +1775,7 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
 }
 \f
 /* Signal an error if the file ABSNAME already exists.
-   If INTERACTIVE is nonzero, ask the user whether to proceed,
+   If INTERACTIVE, ask the user whether to proceed,
    and bypass the error if the user says to go ahead.
    QUERYSTRING is a name for the action that is being considered
    to alter the file.
@@ -1793,13 +1784,14 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
    If the file does not exist, STATPTR->st_mode is set to 0.
    If STATPTR is null, we don't store into it.
 
-   If QUICK is nonzero, we ask for y or n, not yes or no.  */
+   If QUICK, ask for y or n, not yes or no.  */
 
 static void
 barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
-                             int interactive, struct stat *statptr, int quick)
+                             bool interactive, struct stat *statptr,
+                             bool quick)
 {
-  register Lisp_Object tem, encoded_filename;
+  Lisp_Object tem, encoded_filename;
   struct stat statbuf;
   struct gcpro gcpro1;
 
@@ -1873,11 +1865,11 @@ on the system, we copy the SELinux context of FILE to NEWNAME.  */)
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   ptrdiff_t count = SPECPDL_INDEX ();
-  int input_file_statable_p;
+  bool input_file_statable_p;
   Lisp_Object encoded_file, encoded_newname;
 #if HAVE_LIBSELINUX
   security_context_t con;
-  int fail, conlength = 0;
+  int conlength = 0;
 #endif
 
   encoded_file = encoded_newname = Qnil;
@@ -1925,12 +1917,12 @@ on the system, we copy the SELinux context of FILE to NEWNAME.  */)
       DWORD attributes;
       char * filename;
 
-      EMACS_GET_TIME (now);
       filename = SDATA (encoded_newname);
 
       /* Ensure file is writable while its modified time is set.  */
       attributes = GetFileAttributes (filename);
       SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
+      now = current_emacs_time ();
       if (set_file_times (-1, filename, now, now))
        {
          /* Restore original attributes.  */
@@ -1992,7 +1984,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME.  */)
                    S_IREAD | S_IWRITE);
 #else  /* not MSDOS */
   {
-    int new_mask = 0666;
+    mode_t new_mask = 0666;
     if (input_file_statable_p)
       {
        if (!NILP (preserve_uid_gid))
@@ -2022,7 +2014,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME.  */)
      owner and group.  */
   if (input_file_statable_p)
     {
-      int mode_mask = 07777;
+      mode_t mode_mask = 07777;
       if (!NILP (preserve_uid_gid))
        {
          /* Attempt to change owner and group.  If that doesn't work
@@ -2045,7 +2037,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME.  */)
   if (conlength > 0)
     {
       /* Set the modified context back to the file.  */
-      fail = fsetfilecon (ofd, con);
+      bool fail = fsetfilecon (ofd, con) != 0;
       /* See http://debbugs.gnu.org/11245 for ENOTSUP.  */
       if (fail && errno != ENOTSUP)
        report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil));
@@ -2188,17 +2180,14 @@ internal_delete_file_1 (Lisp_Object ignore)
   return Qt;
 }
 
-/* Delete file FILENAME, returning 1 if successful and 0 if failed.
+/* Delete file FILENAME.
    This ignores `delete-by-moving-to-trash'.  */
 
-int
+void
 internal_delete_file (Lisp_Object filename)
 {
-  Lisp_Object tem;
-
-  tem = internal_condition_case_2 (Fdelete_file, filename, Qnil,
-                                  Qt, internal_delete_file_1);
-  return NILP (tem);
+  internal_condition_case_2 (Fdelete_file, filename, Qnil,
+                            Qt, internal_delete_file_1);
 }
 \f
 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
@@ -2434,9 +2423,9 @@ On Unix, this is a name starting with a `/' or a `~'.  */)
   return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil;
 }
 \f
-/* Return nonzero if file FILENAME exists and can be executed.  */
+/* Return true if file FILENAME exists and can be executed.  */
 
-static int
+static bool
 check_executable (char *filename)
 {
 #ifdef DOS_NT
@@ -2456,9 +2445,9 @@ check_executable (char *filename)
 #endif /* not DOS_NT */
 }
 
-/* Return nonzero if file FILENAME exists and can be written.  */
+/* Return true if file FILENAME exists and can be written.  */
 
-static int
+static bool
 check_writable (const char *filename)
 {
 #ifdef MSDOS
@@ -2468,7 +2457,7 @@ check_writable (const char *filename)
   return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode));
 #else /* not MSDOS */
 #ifdef HAVE_EUIDACCESS
-  int res = (euidaccess (filename, 2) >= 0);
+  bool res = (euidaccess (filename, 2) >= 0);
 #ifdef CYGWIN
   /* euidaccess may have returned failure because Cygwin couldn't
      determine the file's UID or GID; if so, we return success. */
@@ -2736,7 +2725,7 @@ searchable directory.  */)
   (Lisp_Object filename)
 {
   Lisp_Object handler;
-  int tem;
+  bool tem;
   struct gcpro gcpro1;
 
   /* If the file name has special constructs in it,
@@ -2844,9 +2833,8 @@ or if SELinux is disabled, or if Emacs lacks SELinux support.  */)
          if (context_range_get (context))
            values[3] = build_string (context_range_get (context));
          context_free (context);
+         freecon (con);
        }
-      if (con)
-       freecon (con);
     }
 #endif
 
@@ -2872,7 +2860,8 @@ compiled with SELinux support.  */)
   Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
   Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
   security_context_t con;
-  int fail, conlength;
+  bool fail;
+  int conlength;
   context_t parsed_con;
 #endif
 
@@ -2916,19 +2905,18 @@ compiled with SELinux support.  */)
            }
 
          /* Set the modified context back to the file.  */
-         fail = lsetfilecon (SSDATA (encoded_absname),
-                             context_str (parsed_con));
+         fail = (lsetfilecon (SSDATA (encoded_absname),
+                              context_str (parsed_con))
+                 != 0);
           /* See http://debbugs.gnu.org/11245 for ENOTSUP.  */
          if (fail && errno != ENOTSUP)
            report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil));
 
          context_free (parsed_con);
+         freecon (con);
        }
       else
        report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil));
-
-      if (con)
-       freecon (con);
     }
 #endif
 
@@ -3008,7 +2996,7 @@ DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
 The value is an integer.  */)
   (void)
 {
-  int realmask;
+  mode_t realmask;
   Lisp_Object value;
 
   BLOCK_INPUT;
@@ -3031,7 +3019,7 @@ Use the current time if TIMESTAMP is nil.  TIMESTAMP is in the format of
 {
   Lisp_Object absname, encoded_absname;
   Lisp_Object handler;
-  EMACS_TIME t = lisp_time_argument (timestamp, 0);
+  EMACS_TIME t = lisp_time_argument (timestamp);
 
   absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
 
@@ -3079,8 +3067,7 @@ otherwise, if FILE2 does not exist, the answer is t.  */)
   (Lisp_Object file1, Lisp_Object file2)
 {
   Lisp_Object absname1, absname2;
-  struct stat st;
-  int mtime1;
+  struct stat st1, st2;
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2;
 
@@ -3106,15 +3093,14 @@ otherwise, if FILE2 does not exist, the answer is t.  */)
   absname2 = ENCODE_FILE (absname2);
   UNGCPRO;
 
-  if (stat (SSDATA (absname1), &st) < 0)
+  if (stat (SSDATA (absname1), &st1) < 0)
     return Qnil;
 
-  mtime1 = st.st_mtime;
-
-  if (stat (SSDATA (absname2), &st) < 0)
+  if (stat (SSDATA (absname2), &st2) < 0)
     return Qt;
 
-  return (mtime1 > st.st_mtime) ? Qt : Qnil;
+  return (EMACS_TIME_GT (get_stat_mtime (&st1), get_stat_mtime (&st2))
+         ? Qt : Qnil);
 }
 \f
 #ifndef READ_BUF_SIZE
@@ -3148,16 +3134,15 @@ decide_coding_unwind (Lisp_Object unwind_data)
   undo_list = XCAR (unwind_data);
   buffer = XCDR (unwind_data);
 
-  if (current_buffer != XBUFFER (buffer))
-    set_buffer_internal (XBUFFER (buffer));
+  set_buffer_internal (XBUFFER (buffer));
   adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
   adjust_overlays_for_delete (BEG, Z - BEG);
-  BUF_INTERVALS (current_buffer) = 0;
+  set_buffer_intervals (current_buffer, NULL);
   TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
 
   /* Now we are safe to change the buffer's multibyteness directly.  */
-  BVAR (current_buffer, enable_multibyte_characters) = multibyte;
-  BVAR (current_buffer, undo_list) = undo_list;
+  bset_enable_multibyte_characters (current_buffer, multibyte);
+  bset_undo_list (current_buffer, undo_list);
 
   return Qnil;
 }
@@ -3215,16 +3200,14 @@ emacs_lseek (int fd, EMACS_INT offset, int whence)
   return lseek (fd, offset, whence);
 }
 
-/* Return a special mtime value indicating the error number ERRNUM.  */
+/* Return a special time value indicating the error number ERRNUM.  */
 static EMACS_TIME
-special_mtime (int errnum)
+time_error_value (int errnum)
 {
-  EMACS_TIME t;
-  int ns = (errno == ENOENT || errno == EACCES || errno == ENOTDIR
+  int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR
            ? NONEXISTENT_MODTIME_NSECS
            : UNKNOWN_MODTIME_NSECS);
-  EMACS_SET_SECS_NSECS (t, 0, ns);
-  return t;
+  return make_emacs_time (0, ns);
 }
 
 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
@@ -3255,29 +3238,29 @@ variable `last-coding-system-used' to the coding system actually used.  */)
   struct stat st;
   int file_status;
   EMACS_TIME mtime;
-  register int fd;
+  int fd;
   ptrdiff_t inserted = 0;
-  int nochange = 0;
-  register ptrdiff_t how_much;
+  bool nochange = 0;
+  ptrdiff_t how_much;
   off_t beg_offset, end_offset;
-  register int unprocessed;
+  int unprocessed;
   ptrdiff_t count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   Lisp_Object handler, val, insval, orig_filename, old_undo;
   Lisp_Object p;
   ptrdiff_t total = 0;
-  int not_regular = 0;
+  bool not_regular = 0;
   int save_errno = 0;
   char read_buf[READ_BUF_SIZE];
   struct coding_system coding;
   char buffer[1 << 14];
-  int replace_handled = 0;
-  int set_coding_system = 0;
+  bool replace_handled = 0;
+  bool set_coding_system = 0;
   Lisp_Object coding_system;
-  int read_quit = 0;
+  bool read_quit = 0;
   Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
-  int we_locked_file = 0;
-  int deferred_remove_unwind_protect = 0;
+  bool we_locked_file = 0;
+  bool deferred_remove_unwind_protect = 0;
 
   if (current_buffer->base_buffer && ! NILP (visit))
     error ("Cannot do file visiting in an indirect buffer");
@@ -3338,7 +3321,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       save_errno = errno;
       if (NILP (visit))
        report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
-      mtime = special_mtime (save_errno);
+      mtime = time_error_value (save_errno);
       st.st_size = -1;
       how_much = 0;
       if (!NILP (Vcoding_system_for_read))
@@ -3489,22 +3472,22 @@ variable `last-coding-system-used' to the coding system actually used.  */)
                  Lisp_Object workbuf;
                  struct buffer *buf;
 
-                 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+                 record_unwind_current_buffer ();
 
                  workbuf = Fget_buffer_create (build_string (" *code-converting-work*"));
                  buf = XBUFFER (workbuf);
 
                  delete_all_overlays (buf);
-                 BVAR (buf, directory) = BVAR (current_buffer, directory);
-                 BVAR (buf, read_only) = Qnil;
-                 BVAR (buf, filename) = Qnil;
-                 BVAR (buf, undo_list) = Qt;
+                 bset_directory (buf, BVAR (current_buffer, directory));
+                 bset_read_only (buf, Qnil);
+                 bset_filename (buf, Qnil);
+                 bset_undo_list (buf, Qt);
                  eassert (buf->overlays_before == NULL);
                  eassert (buf->overlays_after == NULL);
 
                  set_buffer_internal (buf);
                  Ferase_buffer ();
-                 BVAR (buf, enable_multibyte_characters) = Qnil;
+                 bset_enable_multibyte_characters (buf, Qnil);
 
                  insert_1_both ((char *) read_buf, nread, nread, 0, 0, 0);
                  TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
@@ -3578,9 +3561,9 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       ptrdiff_t same_at_end = ZV_BYTE;
       ptrdiff_t overlap;
       /* There is still a possibility we will find the need to do code
-        conversion.  If that happens, we set this variable to 1 to
+        conversion.  If that happens, set this variable to
         give up on handling REPLACE in the optimized way.  */
-      int giveup_match_end = 0;
+      bool giveup_match_end = 0;
 
       if (beg_offset != 0)
        {
@@ -3768,7 +3751,8 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       ptrdiff_t temp;
       ptrdiff_t this = 0;
       ptrdiff_t this_count = SPECPDL_INDEX ();
-      int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+      bool multibyte
+       = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
       Lisp_Object conversion_buffer;
       struct gcpro gcpro1;
 
@@ -4113,8 +4097,8 @@ variable `last-coding-system-used' to the coding system actually used.  */)
          unwind_data = Fcons (BVAR (current_buffer, enable_multibyte_characters),
                               Fcons (BVAR (current_buffer, undo_list),
                                      Fcurrent_buffer ()));
-         BVAR (current_buffer, enable_multibyte_characters) = Qnil;
-         BVAR (current_buffer, undo_list) = Qt;
+         bset_enable_multibyte_characters (current_buffer, Qnil);
+         bset_undo_list (current_buffer, Qt);
          record_unwind_protect (decide_coding_unwind, unwind_data);
 
          if (inserted > 0 && ! NILP (Vset_auto_coding_function))
@@ -4162,7 +4146,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
          && NILP (replace))
        /* Visiting a file with these coding system makes the buffer
           unibyte. */
-       BVAR (current_buffer, enable_multibyte_characters) = Qnil;
+       bset_enable_multibyte_characters (current_buffer, Qnil);
     }
 
   coding.dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
@@ -4205,13 +4189,13 @@ variable `last-coding-system-used' to the coding system actually used.  */)
   if (!NILP (visit))
     {
       if (!EQ (BVAR (current_buffer, undo_list), Qt) && !nochange)
-       BVAR (current_buffer, undo_list) = Qnil;
+       bset_undo_list (current_buffer, Qnil);
 
       if (NILP (handler))
        {
          current_buffer->modtime = mtime;
          current_buffer->modtime_size = st.st_size;
-         BVAR (current_buffer, filename) = orig_filename;
+         bset_filename (current_buffer, orig_filename);
        }
 
       SAVE_MODIFF = MODIFF;
@@ -4256,7 +4240,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
 
       /* Save old undo list and don't record undo for decoding.  */
       old_undo = BVAR (current_buffer, undo_list);
-      BVAR (current_buffer, undo_list) = Qt;
+      bset_undo_list (current_buffer, Qt);
 
       if (NILP (replace))
        {
@@ -4348,7 +4332,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
 
       if (NILP (visit))
        {
-         BVAR (current_buffer, undo_list) = old_undo;
+         bset_undo_list (current_buffer, old_undo);
          if (CONSP (old_undo) && inserted != old_inserted)
            {
              /* Adjust the last undo record for the size change during
@@ -4363,7 +4347,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       else
        /* If undo_list was Qt before, keep it that way.
           Otherwise start with an empty undo_list.  */
-       BVAR (current_buffer, undo_list) = EQ (old_undo, Qt) ? Qt : Qnil;
+       bset_undo_list (current_buffer, EQ (old_undo, Qt) ? Qt : Qnil);
 
       unbind_to (count1, Qnil);
     }
@@ -4435,8 +4419,8 @@ choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object file
         If it is not set locally, we anyway have to convert EOL
         format if the default value of `buffer-file-coding-system'
         tells that it is not Unix-like (LF only) format.  */
-      int using_default_coding = 0;
-      int force_raw_text = 0;
+      bool using_default_coding = 0;
+      bool force_raw_text = 0;
 
       val = BVAR (current_buffer, buffer_file_coding_system);
       if (NILP (val)
@@ -4545,8 +4529,8 @@ This calls `write-region-annotate-functions' at the start, and
 `write-region-post-annotation-function' at the end.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
 {
-  register int desc;
-  int failure;
+  int desc;
+  bool ok;
   int save_errno = 0;
   const char *fn;
   struct stat st;
@@ -4556,8 +4540,8 @@ This calls `write-region-annotate-functions' at the start, and
   Lisp_Object visit_file;
   Lisp_Object annotations;
   Lisp_Object encoded_filename;
-  int visiting = (EQ (visit, Qt) || STRINGP (visit));
-  int quietly = !NILP (visit);
+  bool visiting = (EQ (visit, Qt) || STRINGP (visit));
+  bool quietly = !NILP (visit);
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   struct buffer *given_buffer;
   struct coding_system coding;
@@ -4603,7 +4587,7 @@ This calls `write-region-annotate-functions' at the start, and
        {
          SAVE_MODIFF = MODIFF;
          XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
-         BVAR (current_buffer, filename) = visit_file;
+         bset_filename (current_buffer, visit_file);
        }
       UNGCPRO;
       return val;
@@ -4721,37 +4705,27 @@ This calls `write-region-annotate-functions' at the start, and
 
   UNGCPRO;
 
-  failure = 0;
   immediate_quit = 1;
 
   if (STRINGP (start))
-    {
-      failure = 0 > a_write (desc, start, 0, SCHARS (start),
-                            &annotations, &coding);
-      save_errno = errno;
-    }
+    ok = a_write (desc, start, 0, SCHARS (start), &annotations, &coding);
   else if (XINT (start) != XINT (end))
-    {
-      failure = 0 > a_write (desc, Qnil,
-                            XINT (start), XINT (end) - XINT (start),
-                            &annotations, &coding);
-      save_errno = errno;
-    }
+    ok = a_write (desc, Qnil, XINT (start), XINT (end) - XINT (start),
+                 &annotations, &coding);
   else
     {
-      /* If file was empty, still need to write the annotations */
+      /* If file was empty, still need to write the annotations */
       coding.mode |= CODING_MODE_LAST_BLOCK;
-      failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
-      save_errno = errno;
+      ok = a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
     }
+  save_errno = errno;
 
-  if (CODING_REQUIRE_FLUSHING (&coding)
-      && !(coding.mode & CODING_MODE_LAST_BLOCK)
-      && ! failure)
+  if (ok && CODING_REQUIRE_FLUSHING (&coding)
+      && !(coding.mode & CODING_MODE_LAST_BLOCK))
     {
       /* We have to flush out a data. */
       coding.mode |= CODING_MODE_LAST_BLOCK;
-      failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
+      ok = e_write (desc, Qnil, 1, 1, &coding);
       save_errno = errno;
     }
 
@@ -4768,13 +4742,13 @@ This calls `write-region-annotate-functions' at the start, and
         ignore EINVAL which happens when fsync is not supported on this
         file.  */
       if (errno != EINTR && errno != EINVAL)
-       failure = 1, save_errno = errno;
+       ok = 0, save_errno = errno;
     }
 #endif
 
   /* NFS can report a write failure now.  */
   if (emacs_close (desc) < 0)
-    failure = 1, save_errno = errno;
+    ok = 0, save_errno = errno;
 
   stat (fn, &st);
 
@@ -4811,7 +4785,7 @@ This calls `write-region-annotate-functions' at the start, and
       current_buffer->modtime_size = st.st_size;
     }
 
-  if (failure)
+  if (! ok)
     error ("IO error writing %s: %s", SDATA (filename),
           emacs_strerror (save_errno));
 
@@ -4819,7 +4793,7 @@ This calls `write-region-annotate-functions' at the start, and
     {
       SAVE_MODIFF = MODIFF;
       XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
-      BVAR (current_buffer, filename) = visit_file;
+      bset_filename (current_buffer, visit_file);
       update_mode_lines++;
     }
   else if (quietly)
@@ -4867,7 +4841,8 @@ build_annotations (Lisp_Object start, Lisp_Object end)
   Lisp_Object p, res;
   struct gcpro gcpro1, gcpro2;
   Lisp_Object original_buffer;
-  int i, used_global = 0;
+  int i;
+  bool used_global = 0;
 
   XSETBUFFER (original_buffer, current_buffer);
 
@@ -4947,11 +4922,11 @@ build_annotations (Lisp_Object start, Lisp_Object end)
 
    We modify *ANNOT by discarding elements as we use them up.
 
-   The return value is negative in case of system call failure.  */
+   Return true if successful.  */
 
-static int
+static bool
 a_write (int desc, Lisp_Object string, ptrdiff_t pos,
-        register ptrdiff_t nchars, Lisp_Object *annot,
+        ptrdiff_t nchars, Lisp_Object *annot,
         struct coding_system *coding)
 {
   Lisp_Object tem;
@@ -4973,29 +4948,29 @@ a_write (int desc, Lisp_Object string, ptrdiff_t pos,
       /* Output buffer text up to the next annotation's position.  */
       if (nextpos > pos)
        {
-         if (0 > e_write (desc, string, pos, nextpos, coding))
-           return -1;
+         if (!e_write (desc, string, pos, nextpos, coding))
+           return 0;
          pos = nextpos;
        }
       /* Output the annotation.  */
       tem = Fcdr (Fcar (*annot));
       if (STRINGP (tem))
        {
-         if (0 > e_write (desc, tem, 0, SCHARS (tem), coding))
-           return -1;
+         if (!e_write (desc, tem, 0, SCHARS (tem), coding))
+           return 0;
        }
       *annot = Fcdr (*annot);
     }
-  return 0;
+  return 1;
 }
 
 
 /* Write text in the range START and END into descriptor DESC,
    encoding them with coding system CODING.  If STRING is nil, START
    and END are character positions of the current buffer, else they
-   are indexes to the string STRING.  */
+   are indexes to the string STRING.  Return true if successful.  */
 
-static int
+static bool
 e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
         struct coding_system *coding)
 {
@@ -5064,12 +5039,12 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
                         coding->produced);
 
          if (coding->produced)
-           return -1;
+           return 0;
        }
       start += coding->consumed_char;
     }
 
-  return 0;
+  return 1;
 }
 \f
 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
@@ -5084,7 +5059,7 @@ See Info node `(elisp)Modification Time' for more details.  */)
   struct stat st;
   Lisp_Object handler;
   Lisp_Object filename;
-  EMACS_TIME mtime, diff, one_second;
+  EMACS_TIME mtime, diff;
 
   if (NILP (buf))
     b = current_buffer;
@@ -5108,15 +5083,14 @@ See Info node `(elisp)Modification Time' for more details.  */)
 
   mtime = (stat (SSDATA (filename), &st) == 0
           ? get_stat_mtime (&st)
-          : special_mtime (errno));
+          : time_error_value (errno));
   if ((EMACS_TIME_EQ (mtime, b->modtime)
        /* If both exist, accept them if they are off by one second.  */
        || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
-          && ((EMACS_TIME_LT (mtime, b->modtime)
-               ? EMACS_SUB_TIME (diff, b->modtime, mtime)
-               : EMACS_SUB_TIME (diff, mtime, b->modtime)),
-              EMACS_SET_SECS_NSECS (one_second, 1, 0),
-              EMACS_TIME_LE (diff, one_second))))
+          && ((diff = (EMACS_TIME_LT (mtime, b->modtime)
+                       ? sub_emacs_time (b->modtime, mtime)
+                       : sub_emacs_time (mtime, b->modtime))),
+              EMACS_TIME_LE (diff, make_emacs_time (1, 0)))))
       && (st.st_size == b->modtime_size
           || b->modtime_size < 0))
     return Qt;
@@ -5129,7 +5103,7 @@ DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
 Next attempt to save will certainly not complain of a discrepancy.  */)
   (void)
 {
-  EMACS_SET_SECS_NSECS (current_buffer->modtime, 0, UNKNOWN_MODTIME_NSECS);
+  current_buffer->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
   current_buffer->modtime_size = -1;
   return Qnil;
 }
@@ -5161,7 +5135,7 @@ An argument specifies the modification time value to use
 {
   if (!NILP (time_list))
     {
-      current_buffer->modtime = lisp_time_argument (time_list, 0);
+      current_buffer->modtime = lisp_time_argument (time_list);
       current_buffer->modtime_size = -1;
     }
   else
@@ -5210,7 +5184,7 @@ auto_save_error (Lisp_Object error_val)
   msg = Fformat (3, args);
   GCPRO1 (msg);
   nbytes = SBYTES (msg);
-  SAFE_ALLOCA (msgbuf, char *, nbytes);
+  msgbuf = SAFE_ALLOCA (nbytes);
   memcpy (msgbuf, SDATA (msg), nbytes);
 
   for (i = 0; i < 3; ++i)
@@ -5309,13 +5283,13 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
 {
   struct buffer *old = current_buffer, *b;
   Lisp_Object tail, buf, hook;
-  int auto_saved = 0;
+  bool auto_saved = 0;
   int do_handled_files;
   Lisp_Object oquit;
   FILE *stream = NULL;
   ptrdiff_t count = SPECPDL_INDEX ();
-  int orig_minibuffer_auto_raise = minibuffer_auto_raise;
-  int old_message_p = 0;
+  bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
+  bool old_message_p = 0;
   struct gcpro gcpro1, gcpro2;
 
   if (max_specpdl_size < specpdl_size + 40)
@@ -5428,9 +5402,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
                || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name),
                                                  Qwrite_region))))
          {
-           EMACS_TIME before_time, after_time;
-
-           EMACS_GET_TIME (before_time);
+           EMACS_TIME before_time = current_emacs_time ();
+           EMACS_TIME after_time;
 
            /* If we had a failure, don't try again for 20 minutes.  */
            if (b->auto_save_failure_time > 0
@@ -5462,12 +5435,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
            if (!auto_saved && NILP (no_message))
              message1 ("Auto-saving...");
            internal_condition_case (auto_save_1, Qt, auto_save_error);
-           auto_saved++;
+           auto_saved = 1;
            BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b);
            XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
            set_buffer_internal (old);
 
-           EMACS_GET_TIME (after_time);
+           after_time = current_emacs_time ();
 
            /* If auto-save took more than 60 seconds,
               assume it was an NFS failure that got a timeout.  */
@@ -5647,17 +5620,17 @@ of file names regardless of the current language environment.  */);
   Fput (Qfile_error, Qerror_conditions,
        Fpurecopy (list2 (Qfile_error, Qerror)));
   Fput (Qfile_error, Qerror_message,
-       make_pure_c_string ("File error"));
+       build_pure_c_string ("File error"));
 
   Fput (Qfile_already_exists, Qerror_conditions,
        Fpurecopy (list3 (Qfile_already_exists, Qfile_error, Qerror)));
   Fput (Qfile_already_exists, Qerror_message,
-       make_pure_c_string ("File already exists"));
+       build_pure_c_string ("File already exists"));
 
   Fput (Qfile_date_error, Qerror_conditions,
        Fpurecopy (list3 (Qfile_date_error, Qfile_error, Qerror)));
   Fput (Qfile_date_error, Qerror_message,
-       make_pure_c_string ("Cannot set file date"));
+       build_pure_c_string ("Cannot set file date"));
 
   DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist,
               doc: /* Alist of elements (REGEXP . HANDLER) for file names handled specially.