]> code.delx.au - gnu-emacs/blobdiff - src/fileio.c
Merge changes from emacs-23 branch
[gnu-emacs] / src / fileio.c
index da19c1e2a215e85dc7d2bb684d10c744611cf32b..881dc92acab521249bf43c2837cfeb561a9a11fb 100644 (file)
@@ -1,7 +1,8 @@
 /* File IO for GNU Emacs.
-   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996,
-                 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997,
+  1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+  2009, 2010  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -20,11 +21,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <limits.h>
-
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#endif
-
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -53,10 +50,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <ctype.h>
 #include <errno.h>
 
-#ifndef vax11c
-#ifndef USE_CRT_DLL
-extern int errno;
-#endif
+#ifdef HAVE_LIBSELINUX
+#include <selinux/selinux.h>
+#include <selinux/context.h>
 #endif
 
 #include "lisp.h"
@@ -72,24 +68,16 @@ extern int errno;
 #ifdef WINDOWSNT
 #define NOMINMAX 1
 #include <windows.h>
-#include <stdlib.h>
 #include <fcntl.h>
 #endif /* not WINDOWSNT */
 
 #ifdef MSDOS
 #include "msdos.h"
 #include <sys/param.h>
-#if __DJGPP__ >= 2
 #include <fcntl.h>
-#include <string.h>
-#endif
 #endif
 
 #ifdef DOS_NT
-#define CORRECT_DIR_SEPS(s) \
-  do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
-       else unixtodos_filename (s); \
-  } while (0)
 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
    redirector allows the six letters between 'Z' and 'a' as well. */
 #ifdef MSDOS
@@ -111,16 +99,6 @@ extern int errno;
 #endif
 
 #include "commands.h"
-extern int use_dialog_box;
-extern int use_file_dialog;
-
-#ifndef O_WRONLY
-#define O_WRONLY 1
-#endif
-
-#ifndef O_RDONLY
-#define O_RDONLY 0
-#endif
 
 #ifndef S_ISLNK
 #  define lstat stat
@@ -197,10 +175,6 @@ Lisp_Object Vauto_save_visited_file_name;
 /* Whether or not to continue auto-saving after a large deletion.  */
 Lisp_Object Vauto_save_include_big_deletions;
 
-/* On NT, specifies the directory separator character, used (eg.) when
-   expanding file names.  This can be bound to / or \. */
-Lisp_Object Vdirectory_sep_char;
-
 #ifdef HAVE_FSYNC
 /* Nonzero means skip the call to fsync in Fwrite-region.  */
 int write_region_inhibit_fsync;
@@ -221,16 +195,10 @@ Lisp_Object Qcopy_directory;
 /* Lisp function for recursively deleting directories.  */
 Lisp_Object Qdelete_directory;
 
-extern Lisp_Object Vuser_login_name;
-
 #ifdef WINDOWSNT
 extern Lisp_Object Vw32_get_true_file_attributes;
 #endif
 
-extern int minibuf_level;
-
-extern int minibuffer_auto_raise;
-
 /* These variables describe handlers that have "already" had a chance
    to handle the current operation.
 
@@ -247,15 +215,13 @@ Lisp_Object Qfile_name_history;
 
 Lisp_Object Qcar_less_than_car;
 
-static int a_write P_ ((int, Lisp_Object, int, int,
-                       Lisp_Object *, struct coding_system *));
-static int e_write P_ ((int, Lisp_Object, int, int, struct coding_system *));
+static int a_write (int, Lisp_Object, int, int,
+                    Lisp_Object *, struct coding_system *);
+static int e_write (int, Lisp_Object, int, int, struct coding_system *);
 
 \f
 void
-report_file_error (string, data)
-     const char *string;
-     Lisp_Object data;
+report_file_error (const char *string, Lisp_Object data)
 {
   Lisp_Object errstring;
   int errorno = errno;
@@ -293,8 +259,7 @@ report_file_error (string, data)
 }
 
 Lisp_Object
-close_file_unwind (fd)
-     Lisp_Object fd;
+close_file_unwind (Lisp_Object fd)
 {
   emacs_close (XFASTINT (fd));
   return Qnil;
@@ -303,8 +268,7 @@ close_file_unwind (fd)
 /* Restore point, having saved it as a marker.  */
 
 Lisp_Object
-restore_point_unwind (location)
-     Lisp_Object location;
+restore_point_unwind (Lisp_Object location)
 {
   Fgoto_char (location);
   Fset_marker (location, Qnil, Qnil);
@@ -339,6 +303,8 @@ Lisp_Object Qfile_accessible_directory_p;
 Lisp_Object Qfile_modes;
 Lisp_Object Qset_file_modes;
 Lisp_Object Qset_file_times;
+Lisp_Object Qfile_selinux_context;
+Lisp_Object Qset_file_selinux_context;
 Lisp_Object Qfile_newer_than_file_p;
 Lisp_Object Qinsert_file_contents;
 Lisp_Object Qwrite_region;
@@ -355,8 +321,7 @@ 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.  */)
-     (filename, operation)
-     Lisp_Object filename, operation;
+  (Lisp_Object filename, Lisp_Object operation)
 {
   /* This function must not munge the match data.  */
   Lisp_Object chain, inhibited_handlers, result;
@@ -412,8 +377,7 @@ DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
 Return nil if FILENAME does not include a directory.
 Otherwise return a directory name.
 Given a Unix syntax file name, returns a string ending in slash.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
 #ifndef DOS_NT
   register const unsigned char *beg;
@@ -434,7 +398,7 @@ Given a Unix syntax file name, returns a string ending in slash.  */)
   filename = FILE_SYSTEM_CASE (filename);
 #ifdef DOS_NT
   beg = (unsigned char *) alloca (SBYTES (filename) + 1);
-  bcopy (SDATA (filename), beg, SBYTES (filename) + 1);
+  memcpy (beg, SDATA (filename), SBYTES (filename) + 1);
 #else
   beg = SDATA (filename);
 #endif
@@ -475,7 +439,7 @@ Given a Unix syntax file name, returns a string ending in slash.  */)
          p = beg + strlen (beg);
        }
     }
-  CORRECT_DIR_SEPS (beg);
+  dostounix_filename (beg);
 #endif /* DOS_NT */
 
   return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename));
@@ -487,8 +451,7 @@ DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
 For example, in a Unix-syntax file name,
 this is everything after the last slash,
 or the entire name if it contains no slash.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   register const unsigned char *beg, *p, *end;
   Lisp_Object handler;
@@ -528,8 +491,7 @@ If FILENAME refers to a file which is not accessible from a local process,
 then this should return nil.
 The `call-process' and `start-process' functions use this function to
 get a current directory to run processes in.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object handler;
 
@@ -544,8 +506,7 @@ get a current directory to run processes in.  */)
 
 \f
 char *
-file_name_as_directory (out, in)
-     char *out, *in;
+file_name_as_directory (char *out, char *in)
 {
   int size = strlen (in) - 1;
 
@@ -562,12 +523,11 @@ file_name_as_directory (out, in)
   /* For Unix syntax, Append a slash if necessary */
   if (!IS_DIRECTORY_SEP (out[size]))
     {
-      /* Cannot use DIRECTORY_SEP, which could have any value */
-      out[size + 1] = '/';
+      out[size + 1] = DIRECTORY_SEP;
       out[size + 2] = '\0';
     }
 #ifdef DOS_NT
-  CORRECT_DIR_SEPS (out);
+  dostounix_filename (out);
 #endif
   return out;
 }
@@ -580,8 +540,7 @@ a directory is different from its name as a file.
 The result can be used as the value of `default-directory'
 or passed as second argument to `expand-file-name'.
 For a Unix-syntax file name, just appends a slash.  */)
-     (file)
-     Lisp_Object file;
+  (Lisp_Object file)
 {
   char *buf;
   Lisp_Object handler;
@@ -610,8 +569,7 @@ For a Unix-syntax file name, just appends a slash.  */)
  */
 
 int
-directory_file_name (src, dst)
-     char *src, *dst;
+directory_file_name (char *src, char *dst)
 {
   long slen;
 
@@ -628,7 +586,7 @@ directory_file_name (src, dst)
       )
     dst[slen - 1] = 0;
 #ifdef DOS_NT
-  CORRECT_DIR_SEPS (dst);
+  dostounix_filename (dst);
 #endif
   return 1;
 }
@@ -640,8 +598,7 @@ This is the name of the file that holds the data for the directory 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.  */)
-     (directory)
-     Lisp_Object directory;
+  (Lisp_Object directory)
 {
   char *buf;
   Lisp_Object handler;
@@ -694,9 +651,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
    generated.  */
 
 Lisp_Object
-make_temp_name (prefix, base64_p)
-     Lisp_Object prefix;
-     int base64_p;
+make_temp_name (Lisp_Object prefix, int base64_p)
 {
   Lisp_Object val;
   int len, clen;
@@ -739,10 +694,10 @@ make_temp_name (prefix, base64_p)
   if (!STRING_MULTIBYTE (prefix))
     STRING_SET_UNIBYTE (val);
   data = SDATA (val);
-  bcopy(SDATA (prefix), data, len);
+  memcpy (data, SDATA (prefix), len);
   p = data + len;
 
-  bcopy (pidbuf, p, pidlen);
+  memcpy (p, pidbuf, pidlen);
   p += pidlen;
 
   /* Here we try to minimize useless stat'ing when this function is
@@ -815,8 +770,7 @@ probably use `make-temp-file' instead, except in three circumstances:
 * If you are creating the file in the user's home directory.
 * If you are creating a directory rather than an ordinary file.
 * If you are taking special precautions as `make-temp-file' does.  */)
-     (prefix)
-     Lisp_Object prefix;
+  (Lisp_Object prefix)
 {
   return make_temp_name (prefix, 0);
 }
@@ -846,8 +800,7 @@ non-intuitive results for the root directory; for instance,
 \(expand-file-name ".." "/") returns "/..".  For this reason, use
 \(directory-file-name (file-name-directory dirname)) to traverse a
 filesystem tree, not (expand-file-name ".."  dirname).  */)
-     (name, default_directory)
-     Lisp_Object name, default_directory;
+  (Lisp_Object name, Lisp_Object default_directory)
 {
   /* These point to SDATA and need to be careful with string-relocation
      during GC (via DECODE_FILE).  */
@@ -889,8 +842,6 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
 
         To avoid this, we set default_directory to the root of the
         current drive.  */
-      extern char *emacs_root_dir (void);
-
       default_directory = build_string (emacs_root_dir ());
 #else
       default_directory = build_string ("/");
@@ -958,7 +909,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
 
   /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */
   nm = (unsigned char *) alloca (SBYTES (name) + 1);
-  bcopy (SDATA (name), nm, SBYTES (name) + 1);
+  memcpy (nm, SDATA (name), SBYTES (name) + 1);
 
 #ifdef DOS_NT
   /* Note if special escape prefix is present, but remove for now.  */
@@ -1038,10 +989,9 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       if (!lose)
        {
 #ifdef DOS_NT
-         /* Make sure directories are all separated with / or \ as
-            desired, but avoid allocation of a new string when not
-            required. */
-         CORRECT_DIR_SEPS (nm);
+         /* Make sure directories are all separated with /, but
+            avoid allocation of a new string when not required. */
+         dostounix_filename (nm);
 #ifdef WINDOWSNT
          if (IS_DIRECTORY_SEP (nm[1]))
            {
@@ -1113,7 +1063,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          unsigned char *o, *p;
          for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++);
          o = alloca (p - nm + 1);
-         bcopy ((char *) nm, o, p - nm);
+         memcpy (o, nm, p - nm);
          o [p - nm] = 0;
 
          BLOCK_INPUT;
@@ -1264,7 +1214,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          )
        {
          unsigned char *temp = (unsigned char *) alloca (length);
-         bcopy (newdir, temp, length - 1);
+         memcpy (temp, newdir, length - 1);
          temp[length - 1] = 0;
          newdir = temp;
        }
@@ -1387,7 +1337,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
        target[0] = '/';
        target[1] = ':';
       }
-    CORRECT_DIR_SEPS (target);
+    dostounix_filename (target);
 #endif /* DOS_NT */
 
     result = make_specified_string (target, -1, o - target, multibyte);
@@ -1483,11 +1433,11 @@ See also the function `substitute-in-file-name'.")
        /* Get past ~ to user */
        unsigned char *user = nm + 1;
        /* Find end of name. */
-       unsigned char *ptr = (unsigned char *) index (user, '/');
+       unsigned char *ptr = (unsigned char *) strchr (user, '/');
        int len = ptr ? ptr - user : strlen (user);
        /* Copy the user name into temp storage. */
        o = (unsigned char *) alloca (len + 1);
-       bcopy ((char *) user, o, len);
+       memcpy (o, user, len);
        o[len] = 0;
 
        /* Look up the user name. */
@@ -1570,8 +1520,7 @@ See also the function `substitute-in-file-name'.")
 \f
 /* If /~ or // appears, discard everything through first slash.  */
 static int
-file_name_absolute_p (filename)
-     const unsigned char *filename;
+file_name_absolute_p (const unsigned char *filename)
 {
   return
     (IS_DIRECTORY_SEP (*filename) || *filename == '~'
@@ -1583,8 +1532,7 @@ file_name_absolute_p (filename)
 }
 
 static unsigned char *
-search_embedded_absfilename (nm, endp)
-     unsigned char *nm, *endp;
+search_embedded_absfilename (unsigned char *nm, unsigned char *endp)
 {
   unsigned char *p, *s;
 
@@ -1605,7 +1553,7 @@ search_embedded_absfilename (nm, endp)
            {
              unsigned char *o = alloca (s - p + 1);
              struct passwd *pw;
-             bcopy (p, o, s - p);
+             memcpy (o, p, s - p);
              o [s - p] = 0;
 
              /* If we have ~user and `user' exists, discard
@@ -1635,8 +1583,7 @@ the entire variable name in braces.
 If `/~' appears, all of FILENAME through that `/' is discarded.
 If `//' appears, everything up to and including the first of
 those `/' is discarded.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   unsigned char *nm;
 
@@ -1662,10 +1609,10 @@ those `/' is discarded.  */)
      decode of environment variables, causing the original Lisp_String
      data to be relocated.  */
   nm = (unsigned char *) alloca (SBYTES (filename) + 1);
-  bcopy (SDATA (filename), nm, SBYTES (filename) + 1);
+  memcpy (nm, SDATA (filename), SBYTES (filename) + 1);
 
 #ifdef DOS_NT
-  CORRECT_DIR_SEPS (nm);
+  dostounix_filename (nm);
   substituted = (strcmp (nm, SDATA (filename)) != 0);
 #endif
   endp = nm + SBYTES (filename);
@@ -1835,8 +1782,7 @@ those `/' is discarded.  */)
    (directory-file-name (expand-file-name FOO)).  */
 
 Lisp_Object
-expand_and_dir_to_file (filename, defdir)
-     Lisp_Object filename, defdir;
+expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
 {
   register Lisp_Object absname;
 
@@ -1865,12 +1811,7 @@ expand_and_dir_to_file (filename, defdir)
    If QUICK is nonzero, we ask for y or n, not yes or no.  */
 
 void
-barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
-     Lisp_Object absname;
-     unsigned char *querystring;
-     int interactive;
-     struct stat *statptr;
-     int quick;
+barf_or_query_if_file_exists (Lisp_Object absname, const unsigned char *querystring, int interactive, struct stat *statptr, int quick)
 {
   register Lisp_Object tem, encoded_filename;
   struct stat statbuf;
@@ -1889,7 +1830,7 @@ barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
       tem = format2 ("File %s already exists; %s anyway? ",
                     absname, build_string (querystring));
       if (quick)
-       tem = Fy_or_n_p (tem);
+       tem = call1 (intern ("y-or-n-p"), tem);
       else
        tem = do_yes_or_no_p (tem);
       UNGCPRO;
@@ -1907,7 +1848,7 @@ barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
   return;
 }
 
-DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5,
+DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
        "fCopy file: \nGCopy %s to file: \np\nP",
        doc: /* Copy FILE to NEWNAME.  Both args must be strings.
 If NEWNAME names a directory, copy FILE there.
@@ -1929,10 +1870,11 @@ last-modified time as the old one.  (This works on only some systems.)
 A prefix arg makes KEEP-TIME non-nil.
 
 If PRESERVE-UID-GID is non-nil, we try to transfer the
-uid and gid of FILE to NEWNAME.  */)
-  (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid)
-     Lisp_Object file, newname, ok_if_already_exists, keep_time;
-     Lisp_Object preserve_uid_gid;
+uid and gid of FILE to NEWNAME.
+
+If PRESERVE-SELINUX-CONTEXT is non-nil and SELinux is enabled
+on the system, we copy the SELinux context of FILE to NEWNAME.  */)
+  (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, Lisp_Object keep_time, Lisp_Object preserve_uid_gid, Lisp_Object preserve_selinux_context)
 {
   int ifd, ofd, n;
   char buf[16 * 1024];
@@ -1942,6 +1884,10 @@ uid and gid of FILE to NEWNAME.  */)
   int count = SPECPDL_INDEX ();
   int input_file_statable_p;
   Lisp_Object encoded_file, encoded_newname;
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int fail, conlength = 0;
+#endif
 
   encoded_file = encoded_newname = Qnil;
   GCPRO4 (file, newname, encoded_file, encoded_newname);
@@ -1962,8 +1908,9 @@ uid and gid of FILE to NEWNAME.  */)
   if (NILP (handler))
     handler = Ffind_file_name_handler (newname, Qcopy_file);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call6 (handler, Qcopy_file, file, newname,
-                          ok_if_already_exists, keep_time, preserve_uid_gid));
+    RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname,
+                          ok_if_already_exists, keep_time, preserve_uid_gid,
+                          preserve_selinux_context));
 
   encoded_file = ENCODE_FILE (file);
   encoded_newname = ENCODE_FILE (newname);
@@ -2017,7 +1964,15 @@ uid and gid of FILE to NEWNAME.  */)
      copyable by us. */
   input_file_statable_p = (fstat (ifd, &st) >= 0);
 
-#if !defined (MSDOS) || __DJGPP__ > 1
+#if HAVE_LIBSELINUX
+  if (!NILP (preserve_selinux_context) && is_selinux_enabled ())
+    {
+      conlength = fgetfilecon (ifd, &con);
+      if (conlength == -1)
+       report_file_error ("Doing fgetfilecon", Fcons (file, Qnil));
+    }
+#endif
+
   if (out_st.st_mode != 0
       && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
     {
@@ -2025,7 +1980,6 @@ uid and gid of FILE to NEWNAME.  */)
       report_file_error ("Input and output files are the same",
                         Fcons (file, Fcons (newname, Qnil)));
     }
-#endif
 
 #if defined (S_ISREG) && defined (S_ISLNK)
   if (input_file_statable_p)
@@ -2076,6 +2030,18 @@ uid and gid of FILE to NEWNAME.  */)
     }
 #endif /* not MSDOS */
 
+#if HAVE_LIBSELINUX
+  if (conlength > 0)
+    {
+      /* Set the modified context back to the file. */
+      fail = fsetfilecon (ofd, con);
+      if (fail)
+       report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil));
+
+      freecon (con);
+    }
+#endif
+
   /* Closing the output clobbers the file times on some systems.  */
   if (emacs_close (ofd) < 0)
     report_file_error ("I/O error", Fcons (newname, Qnil));
@@ -2096,7 +2062,7 @@ uid and gid of FILE to NEWNAME.  */)
 
   emacs_close (ifd);
 
-#if defined (__DJGPP__) && __DJGPP__ > 1
+#ifdef MSDOS
   if (input_file_statable_p)
     {
       /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
@@ -2106,7 +2072,7 @@ uid and gid of FILE to NEWNAME.  */)
       if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
        chmod (SDATA (encoded_newname), st.st_mode & 07777);
     }
-#endif /* DJGPP version 2 or newer */
+#endif /* MSDOS */
 #endif /* not WINDOWSNT */
 
   /* Discard the unwind protects.  */
@@ -2119,8 +2085,7 @@ uid and gid of FILE to NEWNAME.  */)
 DEFUN ("make-directory-internal", Fmake_directory_internal,
        Smake_directory_internal, 1, 1, 0,
        doc: /* Create a new directory named DIRECTORY.  */)
-     (directory)
-     Lisp_Object directory;
+  (Lisp_Object directory)
 {
   const unsigned char *dir;
   Lisp_Object handler;
@@ -2150,8 +2115,7 @@ DEFUN ("make-directory-internal", Fmake_directory_internal,
 DEFUN ("delete-directory-internal", Fdelete_directory_internal,
        Sdelete_directory_internal, 1, 1, 0,
        doc: /* Delete the directory named DIRECTORY.  Does not follow symlinks.  */)
-     (directory)
-     Lisp_Object directory;
+  (Lisp_Object directory)
 {
   const unsigned char *dir;
   Lisp_Object handler;
@@ -2159,12 +2123,7 @@ DEFUN ("delete-directory-internal", Fdelete_directory_internal,
 
   CHECK_STRING (directory);
   directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
-
-  if (delete_by_moving_to_trash)
-    return call1 (Qmove_file_to_trash, directory);
-
   encoded_dir = ENCODE_FILE (directory);
-
   dir = SDATA (encoded_dir);
 
   if (rmdir (dir) != 0)
@@ -2173,11 +2132,20 @@ DEFUN ("delete-directory-internal", Fdelete_directory_internal,
   return Qnil;
 }
 
-DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
+DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 2,
+       "(list (read-file-name \
+                (if (and delete-by-moving-to-trash (null current-prefix-arg)) \
+                    \"Move file to trash: \" \"Delete file: \") \
+                nil default-directory (confirm-nonexistent-file-or-buffer)) \
+              (null current-prefix-arg))",
        doc: /* Delete file named FILENAME.  If it is a symlink, remove the symlink.
-If file has multiple names, it continues to exist with the other names.  */)
-     (filename)
-     Lisp_Object filename;
+If file has multiple names, it continues to exist with the other names.
+TRASH non-nil means to trash the file instead of deleting, provided
+`delete-by-moving-to-trash' is non-nil.
+
+When called interactively, TRASH is t if no prefix argument is given.
+With a prefix argument, TRASH is nil.  */)
+  (Lisp_Object filename, Lisp_Object trash)
 {
   Lisp_Object handler;
   Lisp_Object encoded_file;
@@ -2194,9 +2162,9 @@ If file has multiple names, it continues to exist with the other names.  */)
 
   handler = Ffind_file_name_handler (filename, Qdelete_file);
   if (!NILP (handler))
-    return call2 (handler, Qdelete_file, filename);
+    return call3 (handler, Qdelete_file, filename, trash);
 
-  if (delete_by_moving_to_trash)
+  if (delete_by_moving_to_trash && !NILP (trash))
     return call1 (Qmove_file_to_trash, filename);
 
   encoded_file = ENCODE_FILE (filename);
@@ -2207,20 +2175,20 @@ If file has multiple names, it continues to exist with the other names.  */)
 }
 
 static Lisp_Object
-internal_delete_file_1 (ignore)
-     Lisp_Object ignore;
+internal_delete_file_1 (Lisp_Object ignore)
 {
   return Qt;
 }
 
-/* Delete file FILENAME, returning 1 if successful and 0 if failed.  */
+/* Delete file FILENAME, returning 1 if successful and 0 if failed.
+   This ignores `delete-by-moving-to-trash'.  */
 
 int
-internal_delete_file (filename)
-     Lisp_Object filename;
+internal_delete_file (Lisp_Object filename)
 {
   Lisp_Object tem;
-  tem = internal_condition_case_1 (Fdelete_file, filename,
+
+  tem = internal_condition_case_2 (Fdelete_file, filename, Qnil,
                                   Qt, internal_delete_file_1);
   return NILP (tem);
 }
@@ -2233,8 +2201,7 @@ 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.
 This is what happens in interactive use with M-x.  */)
-     (file, newname, ok_if_already_exists)
-     Lisp_Object file, newname, ok_if_already_exists;
+  (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists)
 {
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
@@ -2302,7 +2269,7 @@ This is what happens in interactive use with M-x.  */)
               have copy-file prompt again.  */
            Fcopy_file (file, newname,
                        NILP (ok_if_already_exists) ? Qnil : Qt,
-                       Qt, Qt);
+                       Qt, Qt, Qt);
 
          count = SPECPDL_INDEX ();
          specbind (Qdelete_by_moving_to_trash, Qnil);
@@ -2314,7 +2281,7 @@ This is what happens in interactive use with M-x.  */)
              )
            call2 (Qdelete_directory, file, Qt);
          else
-           Fdelete_file (file);
+           Fdelete_file (file, Qnil);
          unbind_to (count, Qnil);
        }
       else
@@ -2331,8 +2298,7 @@ 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.
 This is what happens in interactive use with M-x.  */)
-     (file, newname, ok_if_already_exists)
-     Lisp_Object file, newname, ok_if_already_exists;
+  (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists)
 {
   Lisp_Object handler;
   Lisp_Object encoded_file, encoded_newname;
@@ -2387,8 +2353,7 @@ Signals a `file-already-exists' error if a file LINKNAME already exists
 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
 A number as third arg means request confirmation if LINKNAME already exists.
 This happens for interactive use with M-x.  */)
-     (filename, linkname, ok_if_already_exists)
-     Lisp_Object filename, linkname, ok_if_already_exists;
+  (Lisp_Object filename, Lisp_Object linkname, Lisp_Object ok_if_already_exists)
 {
   Lisp_Object handler;
   Lisp_Object encoded_filename, encoded_linkname;
@@ -2463,8 +2428,7 @@ DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
        1, 1, 0,
        doc: /* Return t if file FILENAME specifies an absolute file name.
 On Unix, this is a name starting with a `/' or a `~'.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   CHECK_STRING (filename);
   return file_name_absolute_p (SDATA (filename)) ? Qt : Qnil;
@@ -2473,8 +2437,7 @@ On Unix, this is a name starting with a `/' or a `~'.  */)
 /* Return nonzero if file FILENAME exists and can be executed.  */
 
 static int
-check_executable (filename)
-     char *filename;
+check_executable (char *filename)
 {
 #ifdef DOS_NT
   int len = strlen (filename);
@@ -2482,16 +2445,7 @@ check_executable (filename)
   struct stat st;
   if (stat (filename, &st) < 0)
     return 0;
-#if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
   return ((st.st_mode & S_IEXEC) != 0);
-#else
-  return (S_ISREG (st.st_mode)
-         && len >= 5
-         && (xstrcasecmp ((suffix = filename + len-4), ".com") == 0
-             || xstrcasecmp (suffix, ".exe") == 0
-             || xstrcasecmp (suffix, ".bat") == 0)
-         || (st.st_mode & S_IFMT) == S_IFDIR);
-#endif /* not WINDOWSNT */
 #else /* not DOS_NT */
 #ifdef HAVE_EUIDACCESS
   return (euidaccess (filename, 1) >= 0);
@@ -2507,8 +2461,7 @@ check_executable (filename)
 /* Return nonzero if file FILENAME exists and can be written.  */
 
 static int
-check_writable (filename)
-     char *filename;
+check_writable (const char *filename)
 {
 #ifdef MSDOS
   struct stat st;
@@ -2534,8 +2487,7 @@ DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
 See also `file-readable-p' and `file-attributes'.
 This returns nil for a symlink to a nonexistent file.
 Use `file-symlink-p' to test for such links.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object absname;
   Lisp_Object handler;
@@ -2558,8 +2510,7 @@ Use `file-symlink-p' to test for such links.  */)
 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
        doc: /* Return t if FILENAME can be executed by you.
 For a directory, this means you can access files in that directory.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object absname;
   Lisp_Object handler;
@@ -2581,8 +2532,7 @@ For a directory, this means you can access files in that directory.  */)
 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
        doc: /* Return t if file FILENAME exists and you can read it.
 See also `file-exists-p' and `file-attributes'.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object absname;
   Lisp_Object handler;
@@ -2631,8 +2581,7 @@ See also `file-exists-p' and `file-attributes'.  */)
    on the RT/PC.  */
 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
        doc: /* Return t if file FILENAME can be written or created by you.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object absname, dir, encoded;
   Lisp_Object handler;
@@ -2676,8 +2625,7 @@ DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
        doc: /* Access file FILENAME, and get an error if that does not work.
 The second argument STRING is used in the error message.
 If there is no error, returns nil.  */)
-     (filename, string)
-     Lisp_Object filename, string;
+  (Lisp_Object filename, Lisp_Object string)
 {
   Lisp_Object handler, encoded_filename, absname;
   int fd;
@@ -2710,8 +2658,7 @@ Otherwise it returns nil.
 
 This function returns t when given the name of a symlink that
 points to a nonexistent file.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object handler;
 
@@ -2739,7 +2686,7 @@ points to a nonexistent file.  */)
     {
       bufsize *= 2;
       buf = (char *) xrealloc (buf, bufsize);
-      bzero (buf, bufsize);
+      memset (buf, 0, bufsize);
 
       errno = 0;
       valsize = readlink (SDATA (filename), buf, bufsize);
@@ -2760,7 +2707,7 @@ points to a nonexistent file.  */)
   while (valsize >= bufsize);
 
   val = make_string (buf, valsize);
-  if (buf[0] == '/' && index (buf, ':'))
+  if (buf[0] == '/' && strchr (buf, ':'))
     val = concat2 (build_string ("/:"), val);
   xfree (buf);
   val = DECODE_FILE (val);
@@ -2775,8 +2722,7 @@ DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
        doc: /* Return t if FILENAME names an existing directory.
 Symbolic links to directories count as directories.
 See `file-symlink-p' to distinguish symlinks.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   register Lisp_Object absname;
   struct stat st;
@@ -2805,8 +2751,7 @@ directory as a buffer's current directory, this predicate must return true.
 A directory name spec may be given instead; then the value is t
 if the directory so specified exists and really is a readable and
 searchable directory.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object handler;
   int tem;
@@ -2830,8 +2775,7 @@ DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
 This is the sort of file that holds an ordinary stream of data bytes.
 Symbolic links to regular files count as regular files.
 See `file-symlink-p' to distinguish symlinks.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   register Lisp_Object absname;
   struct stat st;
@@ -2868,11 +2812,142 @@ See `file-symlink-p' to distinguish symlinks.  */)
 #endif
 }
 \f
+DEFUN ("file-selinux-context", Ffile_selinux_context,
+       Sfile_selinux_context, 1, 1, 0,
+       doc: /* Return SELinux context of file named FILENAME,
+as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil)
+if file does not exist, is not accessible, or SELinux is disabled */)
+  (Lisp_Object filename)
+{
+  Lisp_Object absname;
+  Lisp_Object values[4];
+  Lisp_Object handler;
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int conlength;
+  context_t context;
+#endif
+
+  absname = expand_and_dir_to_file (filename, current_buffer->directory);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = Ffind_file_name_handler (absname, Qfile_selinux_context);
+  if (!NILP (handler))
+    return call2 (handler, Qfile_selinux_context, absname);
+
+  absname = ENCODE_FILE (absname);
+
+  values[0] = Qnil;
+  values[1] = Qnil;
+  values[2] = Qnil;
+  values[3] = Qnil;
+#if HAVE_LIBSELINUX
+  if (is_selinux_enabled ())
+    {
+      conlength = lgetfilecon (SDATA (absname), &con);
+      if (conlength > 0)
+       {
+         context = context_new (con);
+         if (context_user_get (context))
+           values[0] = build_string (context_user_get (context));
+         if (context_role_get (context))
+           values[1] = build_string (context_role_get (context));
+         if (context_type_get (context))
+           values[2] = build_string (context_type_get (context));
+         if (context_range_get (context))
+           values[3] = build_string (context_range_get (context));
+         context_free (context);
+       }
+      if (con)
+       freecon (con);
+    }
+#endif
+
+  return Flist (sizeof(values) / sizeof(values[0]), values);
+}
+\f
+DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
+       Sset_file_selinux_context, 2, 2, 0,
+       doc: /* Set SELinux context of file named FILENAME to CONTEXT
+as a list ("user", "role", "type", "range"). Has no effect if SELinux
+is disabled. */)
+  (Lisp_Object filename, Lisp_Object context)
+{
+  Lisp_Object absname, encoded_absname;
+  Lisp_Object handler;
+  Lisp_Object user = CAR_SAFE (context);
+  Lisp_Object role = CAR_SAFE (CDR_SAFE (context));
+  Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
+  Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int fail, conlength;
+  context_t parsed_con;
+#endif
+
+  absname = Fexpand_file_name (filename, current_buffer->directory);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = Ffind_file_name_handler (absname, Qset_file_selinux_context);
+  if (!NILP (handler))
+    return call3 (handler, Qset_file_selinux_context, absname, context);
+
+  encoded_absname = ENCODE_FILE (absname);
+
+#if HAVE_LIBSELINUX
+  if (is_selinux_enabled ())
+    {
+      /* Get current file context. */
+      conlength = lgetfilecon (SDATA (encoded_absname), &con);
+      if (conlength > 0)
+       {
+         parsed_con = context_new (con);
+         /* Change the parts defined in the parameter.*/
+         if (STRINGP (user))
+           {
+             if (context_user_set (parsed_con, SDATA (user)))
+               error ("Doing context_user_set");
+           }
+         if (STRINGP (role))
+           {
+             if (context_role_set (parsed_con, SDATA (role)))
+               error ("Doing context_role_set");
+           }
+         if (STRINGP (type))
+           {
+             if (context_type_set (parsed_con, SDATA (type)))
+               error ("Doing context_type_set");
+           }
+         if (STRINGP (range))
+           {
+             if (context_range_set (parsed_con, SDATA (range)))
+               error ("Doing context_range_set");
+           }
+
+         /* Set the modified context back to the file. */
+         fail = lsetfilecon (SDATA (encoded_absname), context_str (parsed_con));
+         if (fail)
+           report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil));
+
+         context_free (parsed_con);
+       }
+      else
+       report_file_error("Doing lgetfilecon", Fcons (absname, Qnil));
+
+      if (con)
+       freecon (con);
+    }
+#endif
+
+  return Qnil;
+}
+\f
 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
        doc: /* Return mode bits of file named FILENAME, as an integer.
 Return nil, if file does not exist or is not accessible.  */)
-     (filename)
-     Lisp_Object filename;
+  (Lisp_Object filename)
 {
   Lisp_Object absname;
   struct stat st;
@@ -2890,10 +2965,6 @@ Return nil, if file does not exist or is not accessible.  */)
 
   if (stat (SDATA (absname), &st) < 0)
     return Qnil;
-#if defined (MSDOS) && __DJGPP__ < 2
-  if (check_executable (SDATA (absname)))
-    st.st_mode |= S_IEXEC;
-#endif /* MSDOS && __DJGPP__ < 2 */
 
   return make_number (st.st_mode & 07777);
 }
@@ -2906,8 +2977,7 @@ Only the 12 low bits of MODE are used.
 
 Interactively, mode bits are read by `read-file-modes', which accepts
 symbolic notation, like the `chmod' command from GNU Coreutils.  */)
-  (filename, mode)
-     Lisp_Object filename, mode;
+  (Lisp_Object filename, Lisp_Object mode)
 {
   Lisp_Object absname, encoded_absname;
   Lisp_Object handler;
@@ -2933,8 +3003,7 @@ DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_mode
        doc: /* Set the file permission bits for newly created files.
 The argument MODE should be an integer; only the low 9 bits are used.
 This setting is inherited by subprocesses.  */)
-     (mode)
-     Lisp_Object mode;
+  (Lisp_Object mode)
 {
   CHECK_NUMBER (mode);
 
@@ -2946,7 +3015,7 @@ This setting is inherited by subprocesses.  */)
 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
        doc: /* Return the default file protection for created files.
 The value is an integer.  */)
-     ()
+  (void)
 {
   int realmask;
   Lisp_Object value;
@@ -2958,7 +3027,6 @@ The value is an integer.  */)
   return value;
 }
 \f
-extern int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
 
 DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 2, 0,
        doc: /* Set times of file FILENAME to TIME.
@@ -2966,8 +3034,7 @@ Set both access and modification times.
 Return t on success, else nil.
 Use the current time if TIME is nil.  TIME is in the format of
 `current-time'. */)
-  (filename, time)
-     Lisp_Object filename, time;
+  (Lisp_Object filename, Lisp_Object time)
 {
   Lisp_Object absname, encoded_absname;
   Lisp_Object handler;
@@ -3014,7 +3081,7 @@ Use the current time if TIME is nil.  TIME is in the format of
 #ifdef HAVE_SYNC
 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
        doc: /* Tell Unix to finish all pending disk updates.  */)
-     ()
+  (void)
 {
   sync ();
   return Qnil;
@@ -3026,8 +3093,7 @@ DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_
        doc: /* Return t if file FILE1 is newer than file FILE2.
 If FILE1 does not exist, the answer is nil;
 otherwise, if FILE2 does not exist, the answer is t.  */)
-     (file1, file2)
-     Lisp_Object file1, file2;
+  (Lisp_Object file1, Lisp_Object file2)
 {
   Lisp_Object absname1, absname2;
   struct stat st;
@@ -3092,8 +3158,7 @@ Lisp_Object Qfind_buffer_file_type;
        o set back the buffer multibyteness.  */
 
 static Lisp_Object
-decide_coding_unwind (unwind_data)
-     Lisp_Object unwind_data;
+decide_coding_unwind (Lisp_Object unwind_data)
 {
   Lisp_Object multibyte, undo_list, buffer;
 
@@ -3125,12 +3190,12 @@ static EMACS_INT non_regular_nbytes;
 
 
 /* Read from a non-regular file.
-   Read non_regular_trytry bytes max from non_regular_fd.
+   Read non_regular_nbytes bytes max from non_regular_fd.
    Non_regular_inserted specifies where to put the read bytes.
    Value is the number of bytes read.  */
 
 static Lisp_Object
-read_non_regular ()
+read_non_regular (Lisp_Object ignore)
 {
   EMACS_INT nbytes;
 
@@ -3148,7 +3213,7 @@ read_non_regular ()
    in insert-file-contents.  */
 
 static Lisp_Object
-read_non_regular_quit ()
+read_non_regular_quit (Lisp_Object ignore)
 {
   return Qnil;
 }
@@ -3177,8 +3242,7 @@ the number of characters that replace previous buffer contents.
 This function does code conversion according to the value of
 `coding-system-for-read' or `file-coding-system-alist', and sets the
 variable `last-coding-system-used' to the coding system actually used.  */)
-     (filename, visit, beg, end, replace)
-     Lisp_Object filename, visit, beg, end, replace;
+  (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace)
 {
   struct stat st;
   register int fd;
@@ -3714,7 +3778,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
                                  conversion_buffer);
          unprocessed = coding.carryover_bytes;
          if (coding.carryover_bytes > 0)
-           bcopy (coding.carryover, read_buf, unprocessed);
+           memcpy (read_buf, coding.carryover, unprocessed);
        }
       UNGCPRO;
       emacs_close (fd);
@@ -4120,6 +4184,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       if (NILP (handler))
        {
          current_buffer->modtime = st.st_mtime;
+         current_buffer->modtime_size = st.st_size;
          current_buffer->filename = orig_filename;
        }
 
@@ -4301,11 +4366,10 @@ variable `last-coding-system-used' to the coding system actually used.  */)
   RETURN_UNGCPRO (unbind_to (count, val));
 }
 \f
-static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
+static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
 
 static Lisp_Object
-build_annotations_unwind (arg)
-     Lisp_Object arg;
+build_annotations_unwind (Lisp_Object arg)
 {
   Vwrite_region_annotation_buffers = arg;
   return Qnil;
@@ -4314,10 +4378,9 @@ build_annotations_unwind (arg)
 /* Decide the coding-system to encode the data with.  */
 
 static Lisp_Object
-choose_write_coding_system (start, end, filename,
-                           append, visit, lockname, coding)
-     Lisp_Object start, end, filename, append, visit, lockname;
-     struct coding_system *coding;
+choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
+                           Lisp_Object append, Lisp_Object visit, Lisp_Object lockname,
+                           struct coding_system *coding)
 {
   Lisp_Object val;
   Lisp_Object eol_parent = Qnil;
@@ -4458,8 +4521,7 @@ This does code conversion according to the value of
 
 This calls `write-region-annotate-functions' at the start, and
 `write-region-post-annotation-function' at the end.  */)
-     (start, end, filename, append, visit, lockname, mustbenew)
-     Lisp_Object start, end, filename, append, visit, lockname, mustbenew;
+  (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;
@@ -4723,7 +4785,10 @@ This calls `write-region-annotate-functions' at the start, and
      to avoid a "file has changed on disk" warning on
      next attempt to save.  */
   if (visiting)
-    current_buffer->modtime = st.st_mtime;
+    {
+      current_buffer->modtime = st.st_mtime;
+      current_buffer->modtime_size = st.st_size;
+    }
 
   if (failure)
     error ("IO error writing %s: %s", SDATA (filename),
@@ -4757,12 +4822,11 @@ This calls `write-region-annotate-functions' at the start, and
   return Qnil;
 }
 \f
-Lisp_Object merge ();
+Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object);
 
 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
        doc: /* Return t if (car A) is numerically less than (car B).  */)
-     (a, b)
-     Lisp_Object a, b;
+  (Lisp_Object a, Lisp_Object b)
 {
   return Flss (Fcar (a), Fcar (b));
 }
@@ -4776,8 +4840,7 @@ DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
    as save-excursion would do.  */
 
 static Lisp_Object
-build_annotations (start, end)
-     Lisp_Object start, end;
+build_annotations (Lisp_Object start, Lisp_Object end)
 {
   Lisp_Object annotations;
   Lisp_Object p, res;
@@ -4866,13 +4929,7 @@ build_annotations (start, end)
    The return value is negative in case of system call failure.  */
 
 static int
-a_write (desc, string, pos, nchars, annot, coding)
-     int desc;
-     Lisp_Object string;
-     register int nchars;
-     int pos;
-     Lisp_Object *annot;
-     struct coding_system *coding;
+a_write (int desc, Lisp_Object string, int pos, register int nchars, Lisp_Object *annot, struct coding_system *coding)
 {
   Lisp_Object tem;
   int nextpos;
@@ -4916,11 +4973,7 @@ a_write (desc, string, pos, nchars, annot, coding)
    are indexes to the string STRING.  */
 
 static int
-e_write (desc, string, start, end, coding)
-     int desc;
-     Lisp_Object string;
-     int start, end;
-     struct coding_system *coding;
+e_write (int desc, Lisp_Object string, int start, int end, struct coding_system *coding)
 {
   if (STRINGP (string))
     {
@@ -4996,20 +5049,25 @@ e_write (desc, string, start, end, coding)
 }
 \f
 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
-       Sverify_visited_file_modtime, 1, 1, 0,
+       Sverify_visited_file_modtime, 0, 1, 0,
        doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
 This means that the file has not been changed since it was visited or saved.
+If BUF is omitted or nil, it defaults to the current buffer.
 See Info node `(elisp)Modification Time' for more details.  */)
-     (buf)
-     Lisp_Object buf;
+  (Lisp_Object buf)
 {
   struct buffer *b;
   struct stat st;
   Lisp_Object handler;
   Lisp_Object filename;
 
-  CHECK_BUFFER (buf);
-  b = XBUFFER (buf);
+  if (NILP (buf))
+    b = current_buffer;
+  else
+    {
+      CHECK_BUFFER (buf);
+      b = XBUFFER (buf);
+    }
 
   if (!STRINGP (b->filename)) return Qt;
   if (b->modtime == 0) return Qt;
@@ -5032,11 +5090,13 @@ See Info node `(elisp)Modification Time' for more details.  */)
       else
        st.st_mtime = 0;
     }
-  if (st.st_mtime == b->modtime
-      /* If both are positive, accept them if they are off by one second.  */
-      || (st.st_mtime > 0 && b->modtime > 0
-         && (st.st_mtime == b->modtime + 1
-             || st.st_mtime == b->modtime - 1)))
+  if ((st.st_mtime == b->modtime
+       /* If both are positive, accept them if they are off by one second.  */
+       || (st.st_mtime > 0 && b->modtime > 0
+          && (st.st_mtime == b->modtime + 1
+              || st.st_mtime == b->modtime - 1)))
+      && (st.st_size == b->modtime_size
+          || b->modtime_size < 0))
     return Qt;
   return Qnil;
 }
@@ -5045,9 +5105,10 @@ DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
        Sclear_visited_file_modtime, 0, 0, 0,
        doc: /* Clear out records of last mod time of visited file.
 Next attempt to save will certainly not complain of a discrepancy.  */)
-     ()
+  (void)
 {
   current_buffer->modtime = 0;
+  current_buffer->modtime_size = -1;
   return Qnil;
 }
 
@@ -5058,7 +5119,7 @@ The value is a list of the form (HIGH LOW), like the time values
 that `file-attributes' returns.  If the current buffer has no recorded
 file modification time, this function returns 0.
 See Info node `(elisp)Modification Time' for more details.  */)
-     ()
+  (void)
 {
   if (! current_buffer->modtime)
     return make_number (0);
@@ -5073,11 +5134,13 @@ or if the file itself has been changed for some known benign reason.
 An argument specifies the modification time value to use
 \(instead of that of the visited file), in the form of a list
 \(HIGH . LOW) or (HIGH LOW).  */)
-     (time_list)
-     Lisp_Object time_list;
+  (Lisp_Object time_list)
 {
   if (!NILP (time_list))
-    current_buffer->modtime = cons_to_long (time_list);
+    {
+      current_buffer->modtime = cons_to_long (time_list);
+      current_buffer->modtime_size = -1;
+    }
   else
     {
       register Lisp_Object filename;
@@ -5096,15 +5159,17 @@ An argument specifies the modification time value to use
       filename = ENCODE_FILE (filename);
 
       if (stat (SDATA (filename), &st) >= 0)
-       current_buffer->modtime = st.st_mtime;
+        {
+         current_buffer->modtime = st.st_mtime;
+          current_buffer->modtime_size = st.st_size;
+        }
     }
 
   return Qnil;
 }
 \f
 Lisp_Object
-auto_save_error (error)
-     Lisp_Object error;
+auto_save_error (Lisp_Object error)
 {
   Lisp_Object args[3], msg;
   int i, nbytes;
@@ -5123,7 +5188,7 @@ auto_save_error (error)
   GCPRO1 (msg);
   nbytes = SBYTES (msg);
   SAFE_ALLOCA (msgbuf, char *, nbytes);
-  bcopy (SDATA (msg), msgbuf, nbytes);
+  memcpy (msgbuf, SDATA (msg), nbytes);
 
   for (i = 0; i < 3; ++i)
     {
@@ -5140,7 +5205,7 @@ auto_save_error (error)
 }
 
 Lisp_Object
-auto_save_1 ()
+auto_save_1 (void)
 {
   struct stat st;
   Lisp_Object modes;
@@ -5166,8 +5231,8 @@ auto_save_1 ()
 }
 
 static Lisp_Object
-do_auto_save_unwind (arg)  /* used as unwind-protect function */
-     Lisp_Object arg;
+do_auto_save_unwind (Lisp_Object arg)  /* used as unwind-protect function */
+                     
 {
   FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
   auto_saving = 0;
@@ -5181,16 +5246,15 @@ do_auto_save_unwind (arg)  /* used as unwind-protect function */
 }
 
 static Lisp_Object
-do_auto_save_unwind_1 (value)  /* used as unwind-protect function */
-     Lisp_Object value;
+do_auto_save_unwind_1 (Lisp_Object value)  /* used as unwind-protect function */
+                       
 {
   minibuffer_auto_raise = XINT (value);
   return Qnil;
 }
 
 static Lisp_Object
-do_auto_save_make_dir (dir)
-     Lisp_Object dir;
+do_auto_save_make_dir (Lisp_Object dir)
 {
   Lisp_Object mode;
 
@@ -5200,8 +5264,7 @@ do_auto_save_make_dir (dir)
 }
 
 static Lisp_Object
-do_auto_save_eh (ignore)
-     Lisp_Object ignore;
+do_auto_save_eh (Lisp_Object ignore)
 {
   return Qnil;
 }
@@ -5217,8 +5280,7 @@ Normally we run the normal hook `auto-save-hook' before saving.
 
 A non-nil NO-MESSAGE argument means do not print any message if successful.
 A non-nil CURRENT-ONLY argument means save only current buffer.  */)
-     (no_message, current_only)
-     Lisp_Object no_message, current_only;
+  (Lisp_Object no_message, Lisp_Object current_only)
 {
   struct buffer *old = current_buffer, *b;
   Lisp_Object tail, buf;
@@ -5419,7 +5481,7 @@ DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
        Sset_buffer_auto_saved, 0, 0, 0,
        doc: /* Mark current buffer as auto-saved with its current text.
 No auto-save file will be written until the buffer changes again.  */)
-     ()
+  (void)
 {
   /* FIXME: This should not be called in indirect buffers, since
      they're not autosaved.  */
@@ -5432,7 +5494,7 @@ No auto-save file will be written until the buffer changes again.  */)
 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
        Sclear_buffer_auto_save_failure, 0, 0, 0,
        doc: /* Clear any record of a recent auto-save failure in the current buffer.  */)
-     ()
+  (void)
 {
   current_buffer->auto_save_failure_time = -1;
   return Qnil;
@@ -5444,7 +5506,7 @@ DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
 More precisely, if it has been auto-saved since last read from or saved
 in the visited file.  If the buffer has no visited file,
 then any auto-save counts as "recent".  */)
-     ()
+  (void)
 {
   /* FIXME: maybe we should return nil for indirect buffers since
      they're never autosaved.  */
@@ -5458,7 +5520,7 @@ DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p,
        doc: /* Return t if a call to `read-file-name' will use a dialog.
 The return value is only relevant for a call to `read-file-name' that happens
 before any other event (mouse or keypress) is handled.  */)
-  ()
+  (void)
 {
 #if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
   if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
@@ -5471,8 +5533,7 @@ before any other event (mouse or keypress) is handled.  */)
 }
 
 Lisp_Object
-Fread_file_name (prompt, dir, default_filename, mustmatch, initial, predicate)
-     Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate;
+Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object initial, Lisp_Object predicate)
 {
   struct gcpro gcpro1, gcpro2;
   Lisp_Object args[7];
@@ -5490,7 +5551,7 @@ Fread_file_name (prompt, dir, default_filename, mustmatch, initial, predicate)
 
 \f
 void
-syms_of_fileio ()
+syms_of_fileio (void)
 {
   Qoperations = intern_c_string ("operations");
   Qexpand_file_name = intern_c_string ("expand-file-name");
@@ -5520,6 +5581,8 @@ syms_of_fileio ()
   Qfile_modes = intern_c_string ("file-modes");
   Qset_file_modes = intern_c_string ("set-file-modes");
   Qset_file_times = intern_c_string ("set-file-times");
+  Qfile_selinux_context = intern_c_string("file-selinux-context");
+  Qset_file_selinux_context = intern_c_string("set-file-selinux-context");
   Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p");
   Qinsert_file_contents = intern_c_string ("insert-file-contents");
   Qwrite_region = intern_c_string ("write-region");
@@ -5555,6 +5618,8 @@ syms_of_fileio ()
   staticpro (&Qfile_modes);
   staticpro (&Qset_file_modes);
   staticpro (&Qset_file_times);
+  staticpro (&Qfile_selinux_context);
+  staticpro (&Qset_file_selinux_context);
   staticpro (&Qfile_newer_than_file_p);
   staticpro (&Qinsert_file_contents);
   staticpro (&Qwrite_region);
@@ -5621,11 +5686,6 @@ of file names regardless of the current language environment.  */);
   Fput (Qfile_date_error, Qerror_message,
        make_pure_c_string ("Cannot set file date"));
 
-  DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
-              doc: /* Directory separator character for built-in functions that return file names.
-The value is always ?/.  Don't use this variable, just use `/'.  */);
-  XSETFASTINT (Vdirectory_sep_char, '/');
-
   DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
               doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
 If a file name matches REGEXP, then all I/O on that file is done by calling
@@ -5748,8 +5808,10 @@ A non-nil value may result in data loss!  */);
 
   DEFVAR_BOOL ("delete-by-moving-to-trash", &delete_by_moving_to_trash,
                doc: /* Specifies whether to use the system's trash can.
-When non-nil, the function `move-file-to-trash' will be used by
-`delete-file' and `delete-directory'.  */);
+When non-nil, certain file deletion commands use the function
+`move-file-to-trash' instead of deleting files outright.
+This includes interactive calls to `delete-file' and
+`delete-directory' and the Dired deletion commands.  */);
   delete_by_moving_to_trash = 0;
   Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
   Qmove_file_to_trash = intern_c_string ("move-file-to-trash");
@@ -5788,6 +5850,8 @@ When non-nil, the function `move-file-to-trash' will be used by
   defsubr (&Sfile_modes);
   defsubr (&Sset_file_modes);
   defsubr (&Sset_file_times);
+  defsubr (&Sfile_selinux_context);
+  defsubr (&Sset_file_selinux_context);
   defsubr (&Sset_default_file_modes);
   defsubr (&Sdefault_file_modes);
   defsubr (&Sfile_newer_than_file_p);
@@ -5810,5 +5874,3 @@ When non-nil, the function `move-file-to-trash' will be used by
 #endif
 }
 
-/* arch-tag: 64ba3fd7-f844-4fb2-ba4b-427eb928786c
-   (do not change this comment) */