*** empty log message ***
[bpt/emacs.git] / src / fileio.c
index 7727448..945b986 100644 (file)
@@ -1,11 +1,11 @@
 /* File IO for GNU Emacs.
-   Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -17,15 +17,31 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#include "config.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
+
+#ifdef VMS
+#include "vms-pwd.h"
+#else
 #include <pwd.h>
+#endif
+
 #include <ctype.h>
+
+#ifdef VMS
+#include "dir.h"
+#include <perror.h>
+#include <stddef.h>
+#include <string.h>
+#else
 #include <sys/dir.h>
+#endif
+
 #include <errno.h>
 
-#ifndef VMS
+#ifndef vax11c
 extern int errno;
 extern char *sys_errlist[];
 extern int sys_nerr;
@@ -37,34 +53,25 @@ extern int sys_nerr;
 #include <sys/time.h>
 #endif
 
-#ifdef NULL
-#undef NULL
-#endif
-#include "config.h"
 #include "lisp.h"
 #include "buffer.h"
 #include "window.h"
 
 #ifdef VMS
-#include <perror.h>
 #include <file.h>
 #include <rmsdef.h>
 #include <fab.h>
 #include <nam.h>
 #endif
 
-#ifdef NEED_TIME_H
-#include <time.h>
-#else /* not NEED_TIME_H */
-#ifdef HAVE_TIMEVAL
-#include <sys/time.h>
-#endif /* HAVE_TIMEVAL */
-#endif /* not NEED_TIME_H */
+#include "systime.h"
 
 #ifdef HPUX
 #include <netio.h>
+#ifndef HPUX8
 #include <errnet.h>
 #endif
+#endif
 
 #ifndef O_WRONLY
 #define O_WRONLY 1
@@ -110,6 +117,12 @@ report_file_error (string, data)
     Fsignal (Qfile_error,
             Fcons (build_string (string), Fcons (errstring, data)));
 }
+
+close_file_unwind (fd)
+     Lisp_Object fd;
+{
+  close (XFASTINT (fd));
+}
 \f
 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
   1, 1, 0,
@@ -215,7 +228,8 @@ file_name_as_directory (out, in)
          brack = ']';
          strcpy (out, "[.");
        }
-      if (dot = index (p, '.'))
+      dot = index (p, '.');
+      if (dot)
        {
          /* blindly remove any extension */
          size = strlen (out) + (dot - p);
@@ -252,7 +266,7 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
   char *buf;
 
   CHECK_STRING (file, 0);
-  if (NULL (file))
+  if (NILP (file))
     return Qnil;
   buf = (char *) alloca (XSTRING (file)->size + 10);
   return build_string (file_name_as_directory (buf, XSTRING (file)->data));
@@ -346,7 +360,8 @@ directory_file_name (src, dst)
 
       /* If bracket is ']' or '>', bracket - 2 is the corresponding
         opening bracket.  */
-      if (!(ptr = index (src, bracket - 2)))
+      ptr = index (src, bracket - 2);
+      if (ptr == 0)
        { /* no opening bracket */
          strcpy (dst, src);
          return 0;
@@ -396,7 +411,7 @@ directory_file_name (src, dst)
   /* Process as Unix format: just remove any final slash.
      But leave "/" unchanged; do not change it to "".  */
   strcpy (dst, src);
-  if (dst[slen - 1] == '/' && slen > 1)
+  if (slen > 1 && dst[slen - 1] == '/')
     dst[slen - 1] = 0;
   return 1;
 }
@@ -417,7 +432,7 @@ it returns a file name such as \"[X]Y.DIR.1\".")
 
   CHECK_STRING (directory, 0);
 
-  if (NULL (directory))
+  if (NILP (directory))
     return Qnil;
 #ifdef VMS
   /* 20 extra chars is insufficient for VMS, since we might perform a
@@ -449,8 +464,12 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
  (does not start with slash); if DEFAULT is nil or missing,\n\
 the current buffer's value of default-directory is used.\n\
-Filenames containing `.' or `..' as components are simplified;\n\
-initial `~/' expands to your home directory.\n\
+Path components that are `.' are removed, and \n\
+path components followed by `..' are removed, along with the `..' itself;\n\
+note that these simplifications are done without checking the resulting\n\
+paths in the file system.\n\
+An initial `~/' expands to your home directory.\n\
+An initial `~USER/' expands to USER's home directory.\n\
 See also the function `substitute-in-file-name'.")
      (name, defalt)
      Lisp_Object name, defalt;
@@ -602,7 +621,7 @@ See also the function `substitute-in-file-name'.")
 #ifdef VMS
        || nm[1] == ':'
 #endif /* VMS */
-       || nm[1] == 0)/* ~/filename */
+       || nm[1] == 0)/* ~ by itself */
       {
        if (!(newdir = (unsigned char *) egetenv ("HOME")))
          newdir = (unsigned char *) "";
@@ -623,15 +642,18 @@ See also the function `substitute-in-file-name'.")
        o [p - nm] = 0;
 
        pw = (struct passwd *) getpwnam (o + 1);
-       if (!pw)
-         error ("\"%s\" isn't a registered user", o + 1);
-
+       if (pw)
+         {
+           newdir = (unsigned char *) pw -> pw_dir;
 #ifdef VMS
-       nm = p + 1;             /* skip the terminator */
+           nm = p + 1;         /* skip the terminator */
 #else
-       nm = p;
+           nm = p;
 #endif /* VMS */
-       newdir = (unsigned char *) pw -> pw_dir;
+         }
+
+       /* If we don't find a user of that name, leave the name
+          unchanged; don't move nm forward to p.  */
       }
 
   if (nm[0] != '/'
@@ -640,15 +662,30 @@ See also the function `substitute-in-file-name'.")
 #endif /* not VMS */
       && !newdir)
     {
-      if (NULL (defalt))
+      if (NILP (defalt))
        defalt = current_buffer->directory;
       CHECK_STRING (defalt, 1);
       newdir = XSTRING (defalt)->data;
     }
 
-  /* Now concatenate the directory and name to new space in the stack frame */
+  if (newdir != 0)
+    {
+      /* Get rid of any slash at the end of newdir.  */
+      int length = strlen (newdir);
+      if (newdir[length - 1] == '/')
+       {
+         unsigned char *temp = (unsigned char *) alloca (length);
+         bcopy (newdir, temp, length - 1);
+         temp[length - 1] = 0;
+         newdir = temp;
+       }
+      tlen = length + 1;
+    }
+  else
+    tlen = 0;
 
-  tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
+  /* Now concatenate the directory and name to new space in the stack frame */
+  tlen += strlen (nm) + 1;
   target = (unsigned char *) alloca (tlen);
   *target = 0;
 
@@ -760,7 +797,8 @@ See also the function `substitute-in-file-name'.")
   return make_string (target, o - target);
 }
 #if 0
-DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
+/* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'.
+DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
   "Convert FILENAME to absolute, and canonicalize it.\n\
 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
  (does not start with slash); if DEFAULT is nil or missing,\n\
@@ -961,7 +999,7 @@ See also the function `substitute-in-file-name'.")
 #endif /* not VMS */
       && !newdir)
     {
-      if (NULL (defalt))
+      if (NILP (defalt))
        defalt = current_buffer->directory;
       CHECK_STRING (defalt, 1);
       newdir = XSTRING (defalt)->data;
@@ -1321,7 +1359,7 @@ barf_or_query_if_file_exists (absname, querystring, interactive)
       tem = do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
                                     XSTRING (absname)->data, querystring));
       UNGCPRO;
-      if (NULL (tem))
+      if (NILP (tem))
        Fsignal (Qfile_already_exists,
                 Fcons (build_string ("File already exists"),
                        Fcons (absname, Qnil)));
@@ -1330,14 +1368,15 @@ barf_or_query_if_file_exists (absname, querystring, interactive)
 }
 
 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
-  "fCopy file: \nFCopy %s to file: \np",
+  "fCopy file: \nFCopy %s to file: \np\nP",
   "Copy FILE to NEWNAME.  Both args must be strings.\n\
 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
 A number as third arg means request confirmation if NEWNAME already exists.\n\
 This is what happens in interactive use with M-x.\n\
-Fourth arg non-nil means give the new file the same last-modified time\n\
-that the old one has.  (This works on only some systems.)")
+Fourth arg KEEP-TIME non-nil means give the new file the same\n\
+last-modified time as the old one.  (This works on only some systems.)\n\
+A prefix arg makes KEEP-TIME non-nil.")
   (filename, newname, ok_if_already_exists, keep_date)
      Lisp_Object filename, newname, ok_if_already_exists, keep_date;
 {
@@ -1345,13 +1384,14 @@ that the old one has.  (This works on only some systems.)")
   char buf[16 * 1024];
   struct stat st;
   struct gcpro gcpro1, gcpro2;
+  int count = specpdl_ptr - specpdl;
 
   GCPRO2 (filename, newname);
   CHECK_STRING (filename, 0);
   CHECK_STRING (newname, 1);
   filename = Fexpand_file_name (filename, Qnil);
   newname = Fexpand_file_name (newname, Qnil);
-  if (NULL (ok_if_already_exists)
+  if (NILP (ok_if_already_exists)
       || XTYPE (ok_if_already_exists) == Lisp_Int)
     barf_or_query_if_file_exists (newname, "copy to it",
                                  XTYPE (ok_if_already_exists) == Lisp_Int);
@@ -1360,6 +1400,8 @@ that the old one has.  (This works on only some systems.)")
   if (ifd < 0)
     report_file_error ("Opening input file", Fcons (filename, Qnil));
 
+  record_unwind_protect (close_file_unwind, make_number (ifd));
+
 #ifdef VMS
   /* Create the copy file with the same record format as the input file */
   ofd = sys_creat (XSTRING (newname)->data, 0666, ifd);
@@ -1367,50 +1409,35 @@ that the old one has.  (This works on only some systems.)")
   ofd = creat (XSTRING (newname)->data, 0666);
 #endif /* VMS */
   if (ofd < 0)
-    {
-      close (ifd);
       report_file_error ("Opening output file", Fcons (newname, Qnil));
-    }
 
+  record_unwind_protect (close_file_unwind, make_number (ofd));
+
+  immediate_quit = 1;
+  QUIT;
   while ((n = read (ifd, buf, sizeof buf)) > 0)
     if (write (ofd, buf, n) != n)
-      {
-       close (ifd);
-       close (ofd);
        report_file_error ("I/O error", Fcons (newname, Qnil));
-      }
+  immediate_quit = 0;
 
   if (fstat (ifd, &st) >= 0)
     {
-#ifdef HAVE_TIMEVAL
-      if (!NULL (keep_date))
+      if (!NILP (keep_date))
        {
-#ifdef USE_UTIME
-/* AIX has utimes() in compatibility package, but it dies.  So use good old
-   utime interface instead. */
-         struct {
-           time_t atime;
-           time_t mtime;
-         } tv;
-         tv.atime = st.st_atime;
-         tv.mtime = st.st_mtime;
-         utime (XSTRING (newname)->data, &tv);
-#else /* not USE_UTIME */
-         struct timeval timevals[2];
-         timevals[0].tv_sec = st.st_atime;
-         timevals[1].tv_sec = st.st_mtime;
-         timevals[0].tv_usec = timevals[1].tv_usec = 0;
-         utimes (XSTRING (newname)->data, timevals);
-#endif /* not USE_UTIME */
+         EMACS_TIME atime, mtime;
+         EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
+         EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
+         EMACS_SET_UTIMES (XSTRING (newname)->data, atime, mtime);
        }
-#endif /* HAVE_TIMEVALS */
-
 #ifdef APOLLO
       if (!egetenv ("USE_DOMAIN_ACLS"))
 #endif
-      chmod (XSTRING (newname)->data, st.st_mode & 07777);
+       chmod (XSTRING (newname)->data, st.st_mode & 07777);
     }
 
+  /* Discard the unwind protects.  */
+  specpdl_ptr = specpdl + count;
+
   close (ifd);
   if (close (ofd) < 0)
     report_file_error ("I/O error", Fcons (newname, Qnil));
@@ -1436,8 +1463,8 @@ DEFUN ("make-directory", Fmake_directory, Smake_directory, 1, 1, "FMake director
     return Qnil;
 }
 
-DEFUN ("remove-directory", Fremove_directory, Sremove_directory, 1, 1, "FRemove directory: ",
-  "Remove a directory.  One argument, a file name string.")
+DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
+  "Delete a directory.  One argument, a file name string.")
   (dirname)
      Lisp_Object dirname;
 {
@@ -1487,7 +1514,7 @@ This is what happens in interactive use with M-x.")
   CHECK_STRING (newname, 1);
   filename = Fexpand_file_name (filename, Qnil);
   newname = Fexpand_file_name (newname, Qnil);
-  if (NULL (ok_if_already_exists)
+  if (NILP (ok_if_already_exists)
       || XTYPE (ok_if_already_exists) == Lisp_Int)
     barf_or_query_if_file_exists (newname, "rename to it",
                                  XTYPE (ok_if_already_exists) == Lisp_Int);
@@ -1538,7 +1565,7 @@ This is what happens in interactive use with M-x.")
   CHECK_STRING (newname, 1);
   filename = Fexpand_file_name (filename, Qnil);
   newname = Fexpand_file_name (newname, Qnil);
-  if (NULL (ok_if_already_exists)
+  if (NILP (ok_if_already_exists)
       || XTYPE (ok_if_already_exists) == Lisp_Int)
     barf_or_query_if_file_exists (newname, "make it a new name",
                                  XTYPE (ok_if_already_exists) == Lisp_Int);
@@ -1566,38 +1593,38 @@ Signals a `file-already-exists' error if a file NEWNAME already exists\n\
 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
 A number as third arg means request confirmation if NEWNAME already exists.\n\
 This happens for interactive use with M-x.")
-  (filename, newname, ok_if_already_exists)
-     Lisp_Object filename, newname, ok_if_already_exists;
+  (filename, linkname, ok_if_already_exists)
+     Lisp_Object filename, linkname, ok_if_already_exists;
 {
 #ifdef NO_ARG_ARRAY
   Lisp_Object args[2];
 #endif
   struct gcpro gcpro1, gcpro2;
 
-  GCPRO2 (filename, newname);
+  GCPRO2 (filename, linkname);
   CHECK_STRING (filename, 0);
-  CHECK_STRING (newname, 1);
+  CHECK_STRING (linkname, 1);
 #if 0 /* This made it impossible to make a link to a relative name.  */
   filename = Fexpand_file_name (filename, Qnil);
 #endif
-  newname = Fexpand_file_name (newname, Qnil);
-  if (NULL (ok_if_already_exists)
+  linkname = Fexpand_file_name (linkname, Qnil);
+  if (NILP (ok_if_already_exists)
       || XTYPE (ok_if_already_exists) == Lisp_Int)
-    barf_or_query_if_file_exists (newname, "make it a link",
+    barf_or_query_if_file_exists (linkname, "make it a link",
                                  XTYPE (ok_if_already_exists) == Lisp_Int);
-  if (0 > symlink (XSTRING (filename)->data, XSTRING (newname)->data))
+  if (0 > symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
     {
       /* If we didn't complain already, silently delete existing file.  */
       if (errno == EEXIST)
        {
          unlink (XSTRING (filename)->data);
-         if (0 <= symlink (XSTRING (filename)->data, XSTRING (newname)->data))
+         if (0 <= symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
            return Qnil;
        }
 
 #ifdef NO_ARG_ARRAY
       args[0] = filename;
-      args[1] = newname;
+      args[1] = linkname;
       report_file_error ("Making symbolic link", Flist (2, args));
 #else
       report_file_error ("Making symbolic link", Flist (2, &filename));
@@ -1619,7 +1646,7 @@ If STRING is nil or a null string, the logical name NAME is deleted.")
      Lisp_Object string;
 {
   CHECK_STRING (varname, 0);
-  if (NULL (string))
+  if (NILP (string))
     delete_logical_name (XSTRING (varname)->data);
   else
     {
@@ -1775,10 +1802,10 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
     return (access (XSTRING (abspath)->data, 2) >= 0) ? Qt : Qnil;
   dir = Ffile_name_directory (abspath);
 #ifdef VMS
-  if (!NULL (dir))
+  if (!NILP (dir))
     dir = Fdirectory_file_name (dir);
 #endif /* VMS */
-  return (access (!NULL (dir) ? (char *) XSTRING (dir)->data : "", 2) >= 0
+  return (access (!NILP (dir) ? (char *) XSTRING (dir)->data : "", 2) >= 0
          ? Qt : Qnil);
 }
 
@@ -1799,6 +1826,23 @@ if the directory so specified exists and really is a directory.")
   return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
 }
 
+DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
+  "Return t if file FILENAME is the name of a directory as a file,\n\
+and files in that directory can be opened by you.  In order to use a\n\
+directory as a buffer's current directory, this predicate must return true.\n\
+A directory name spec may be given instead; then the value is t\n\
+if the directory so specified exists and really is a readable and\n\
+searchable directory.")
+  (filename)
+     Lisp_Object filename;
+{
+  if (NILP (Ffile_directory_p (filename))
+      || NILP (Ffile_executable_p (filename)))
+    return Qnil;
+  else
+    return Qt;
+}
+
 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
   "Return mode bits of FILE, as an integer.")
   (filename)
@@ -1859,6 +1903,49 @@ Only the 12 low bits of MODE are used.")
   return Qnil;
 }
 
+DEFUN ("set-umask", Fset_umask, Sset_umask, 1, 1, 0,
+    "Select which permission bits to disable in newly created files.\n\
+MASK should be an integer; if a permission's bit in MASK is 1,\n\
+subsequently created files will not have that permission enabled.\n\
+Only the low 9 bits are used.\n\
+This setting is inherited by subprocesses.")
+  (mask)
+     Lisp_Object mask;
+{
+  CHECK_NUMBER (mask, 0);
+  
+  umask (XINT (mask) & 0777);
+
+  return Qnil;
+}
+
+DEFUN ("umask", Fumask, Sumask, 0, 0, 0,
+    "Return the current umask value.\n\
+The umask value determines which permissions are enabled in newly\n\
+created files.  If a permission's bit in the umask is 1, subsequently\n\
+created files will not have that permission enabled.")
+  ()
+{
+  Lisp_Object mask;
+
+  XSET (mask, Lisp_Int, umask (0));
+  umask (XINT (mask));
+
+  return mask;
+}
+
+#ifdef unix
+
+DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
+  "Tell Unix to finish all pending disk updates.")
+  ()
+{
+  sync ();
+  return Qnil;
+}
+
+#endif /* unix */
+
 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
   "Return t if file FILE1 is newer than file FILE2.\n\
 If FILE1 does not exist, the answer is nil;\n\
@@ -1888,12 +1975,6 @@ otherwise, if FILE2 does not exist, the answer is t.")
   return (mtime1 > st.st_mtime) ? Qt : Qnil;
 }
 \f
-close_file_unwind (fd)
-     Lisp_Object fd;
-{
-  close (XFASTINT (fd));
-}
-
 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
   1, 2, 0,
   "Insert contents of file FILENAME after point.\n\
@@ -1913,7 +1994,7 @@ before the error is signaled.")
   struct gcpro gcpro1;
   
   GCPRO1 (filename);
-  if (!NULL (current_buffer->read_only))
+  if (!NILP (current_buffer->read_only))
     Fbarf_if_buffer_read_only();
 
   CHECK_STRING (filename, 0);
@@ -1923,14 +2004,14 @@ before the error is signaled.")
 
 #ifndef APOLLO
   if (stat (XSTRING (filename)->data, &st) < 0
-       || (fd = open (XSTRING (filename)->data, 0)) < 0)
+      || (fd = open (XSTRING (filename)->data, 0)) < 0)
 #else
   if ((fd = open (XSTRING (filename)->data, 0)) < 0
       || fstat (fd, &st) < 0)
 #endif /* not APOLLO */
     {
       if (fd >= 0) close (fd);
-      if (NULL (visit))
+      if (NILP (visit))
        report_file_error ("Opening input file", Fcons (filename, Qnil));
       st.st_mtime = -1;
       how_much = 0;
@@ -1939,9 +2020,20 @@ before the error is signaled.")
 
   record_unwind_protect (close_file_unwind, make_number (fd));
 
+#ifdef S_IFSOCK
+  /* This code will need to be changed in order to work on named
+     pipes, and it's probably just not worth it.  So we should at
+     least signal an error.  */
+  if ((st.st_mode & S_IFMT) == S_IFSOCK)
+    Fsignal (Qfile_error,
+            Fcons (build_string ("reading from named pipe"),
+                   Fcons (filename, Qnil)));
+#endif
+
   /* Supposedly happens on VMS.  */
   if (st.st_size < 0)
     error ("File size is negative");
+
   {
     register Lisp_Object temp;
 
@@ -1951,7 +2043,7 @@ before the error is signaled.")
       error ("maximum buffer size exceeded");
   }
 
-  if (NULL (visit))
+  if (NILP (visit))
     prepare_to_modify_buffer (point, point);
 
   move_gap (point);
@@ -1961,7 +2053,13 @@ before the error is signaled.")
   while (1)
     {
       int try = min (st.st_size - inserted, 64 << 10);
-      int this = read (fd, &FETCH_CHAR (point + inserted - 1) + 1, try);
+      int this;
+
+      /* Allow quitting out of the actual I/O.  */
+      immediate_quit = 1;
+      QUIT;
+      this = read (fd, &FETCH_CHAR (point + inserted - 1) + 1, try);
+      immediate_quit = 0;
 
       if (this <= 0)
        {
@@ -1991,7 +2089,7 @@ before the error is signaled.")
 
  notfound:
 
-  if (!NULL (visit))
+  if (!NILP (visit))
     {
       current_buffer->undo_list = Qnil;
 #ifdef APOLLO
@@ -2002,7 +2100,7 @@ before the error is signaled.")
       current_buffer->auto_save_modified = MODIFF;
       XFASTINT (current_buffer->save_length) = Z - BEG;
 #ifdef CLASH_DETECTION
-      if (!NULL (current_buffer->filename))
+      if (!NILP (current_buffer->filename))
        unlock_file (current_buffer->filename);
       unlock_file (filename);
 #endif /* CLASH_DETECTION */
@@ -2014,13 +2112,9 @@ before the error is signaled.")
 
   signal_after_change (point, 0, inserted);
   
-  {
-    Lisp_Object result = Fcons (filename,
-                               Fcons (make_number (inserted),
-                                      Qnil));
-    UNGCPRO;
-    return result;
-  }
+  RETURN_UNGCPRO (Fcons (filename,
+                        Fcons (make_number (inserted),
+                               Qnil)));
 }
 
 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 5,
@@ -2052,7 +2146,7 @@ to the file, instead of any buffer contents, and END is ignored.")
 #endif /* VMS */
 
   /* Special kludge to simplify auto-saving */
-  if (NULL (start))
+  if (NILP (start))
     {
       XFASTINT (start) = BEG;
       XFASTINT (end) = Z;
@@ -2069,7 +2163,7 @@ to the file, instead of any buffer contents, and END is ignored.")
 #endif /* CLASH_DETECTION */
 
   desc = -1;
-  if (!NULL (append))
+  if (!NILP (append))
     desc = open (fn, O_WRONLY);
 
   if (desc < 0)
@@ -2080,15 +2174,15 @@ to the file, instead of any buffer contents, and END is ignored.")
        desc = open (fn, O_RDWR);
        if (desc < 0)
          desc = creat_copy_attrs (XTYPE (current_buffer->filename) == Lisp_String
-                                ? XSTRING (current_buffer->filename)->data : 0,
-                                fn);
+                                  ? XSTRING (current_buffer->filename)->data : 0,
+                                  fn);
       }
     else               /* Write to temporary name and rename if no errors */
       {
        Lisp_Object temp_name;
        temp_name = Ffile_name_directory (filename);
 
-       if (!NULL (temp_name))
+       if (!NILP (temp_name))
          {
            temp_name = Fmake_temp_name (concat2 (temp_name,
                                                  build_string ("$$SAVE$$")));
@@ -2134,7 +2228,7 @@ to the file, instead of any buffer contents, and END is ignored.")
 
   record_unwind_protect (close_file_unwind, make_number (desc));
 
-  if (!NULL (append))
+  if (!NILP (append))
     if (lseek (desc, 0, 2) < 0)
       {
 #ifdef CLASH_DETECTION
@@ -2197,15 +2291,12 @@ to the file, instead of any buffer contents, and END is ignored.")
 #ifndef USG
 #ifndef VMS
 #ifndef BSD4_1
-#ifndef alliant /* trinkle@cs.purdue.edu says fsync can return EBUSY
-                  on alliant, for no visible reason.  */
   /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
      Disk full in NFS may be reported here.  */
   if (fsync (desc) < 0)
     failure = 1, save_errno = errno;
 #endif
 #endif
-#endif
 #endif
 
   /* Spurious "file has changed on disk" warnings have been 
@@ -2267,7 +2358,7 @@ to the file, instead of any buffer contents, and END is ignored.")
       XFASTINT (current_buffer->save_length) = Z - BEG;
       current_buffer->filename = filename;
     }
-  else if (!NULL (visit))
+  else if (!NILP (visit))
     return Qnil;
 
   if (!auto_saving)
@@ -2414,7 +2505,7 @@ Auto-saving writes the buffer into a file\n\
 so that your editing is not lost if the system crashes.\n\
 This file is not the file you visited; that changes only when you save.\n\n\
 Non-nil first argument means do not print any message if successful.\n\
-Non-nil second argumet means save only current buffer.")
+Non-nil second argument means save only current buffer.")
   (nomsg)
      Lisp_Object nomsg;
 {
@@ -2433,7 +2524,7 @@ Non-nil second argumet means save only current buffer.")
 
   /* Vrun_hooks is nil before emacs is dumped, and inc-vers.el will
      eventually call do-auto-save, so don't err here in that case. */
-  if (!NULL (Vrun_hooks))
+  if (!NILP (Vrun_hooks))
     call1 (Vrun_hooks, intern ("auto-save-hook"));
 
   for (tail = Vbuffer_alist; XGCTYPE (tail) == Lisp_Cons;
@@ -2467,7 +2558,7 @@ Non-nil second argumet means save only current buffer.")
              continue;
            }
          set_buffer_internal (b);
-         if (!auto_saved && NULL (nomsg))
+         if (!auto_saved && NILP (nomsg))
            message1 ("Auto-saving...");
          internal_condition_case (auto_save_1, Qt, auto_save_error);
          auto_saved++;
@@ -2480,7 +2571,7 @@ Non-nil second argumet means save only current buffer.")
   if (auto_saved)
     record_auto_save ();
 
-  if (auto_saved && NULL (nomsg))
+  if (auto_saved && NILP (nomsg))
     message1 (omessage ? omessage : "Auto-saving...done");
 
   auto_saving = 0;
@@ -2533,24 +2624,24 @@ DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_inte
       string = Fsubstitute_in_file_name (string);
       name = Ffile_name_nondirectory (string);
       realdir = Ffile_name_directory (string);
-      if (NULL (realdir))
+      if (NILP (realdir))
        realdir = dir;
       else
        realdir = Fexpand_file_name (realdir, dir);
     }
 
-  if (NULL (action))
+  if (NILP (action))
     {
       specdir = Ffile_name_directory (string);
       val = Ffile_name_completion (name, realdir);
       if (XTYPE (val) != Lisp_String)
        {
-         if (NULL (Fstring_equal (string, orig_string)))
+         if (NILP (Fstring_equal (string, orig_string)))
            return string;
          return (val);
        }
 
-      if (!NULL (specdir))
+      if (!NILP (specdir))
        val = concat2 (specdir, val);
 #ifndef VMS
       {
@@ -2611,9 +2702,9 @@ DIR defaults to current buffer's directory default.")
   register char *homedir;
   int count;
 
-  if (NULL (dir))
+  if (NILP (dir))
     dir = current_buffer->directory;
-  if (NULL (defalt))
+  if (NILP (defalt))
     defalt = current_buffer->filename;
 
   /* If dir starts with user's homedir, change that to ~. */
@@ -2631,7 +2722,7 @@ DIR defaults to current buffer's directory default.")
   if (insert_default_directory)
     {
       insdef = dir;
-      if (!NULL (initial))
+      if (!NILP (initial))
        {
          Lisp_Object args[2];
 
@@ -2664,10 +2755,10 @@ DIR defaults to current buffer's directory default.")
 #endif
 
   UNGCPRO;
-  if (NULL (val))
+  if (NILP (val))
     error ("No file name specified");
   tem = Fstring_equal (val, insdef);
-  if (!NULL (tem) && !NULL (defalt))
+  if (!NILP (tem) && !NILP (defalt))
     return defalt;
   return Fsubstitute_in_file_name (val);
 }
@@ -2690,9 +2781,9 @@ DIR defaults to current buffer's directory default.")
   register char *homedir;
   int count;
 
-  if (NULL (dir))
+  if (NILP (dir))
     dir = current_buffer->directory;
-  if (NULL (defalt))
+  if (NILP (defalt))
     defalt = current_buffer->filename;
 
   /* If dir starts with user's homedir, change that to ~. */
@@ -2707,7 +2798,7 @@ DIR defaults to current buffer's directory default.")
       XSTRING (dir)->data[0] = '~';
     }
 
-  if (!NULL (initial))
+  if (!NILP (initial))
     insdef = initial;
   else if (insert_default_directory)
     insdef = dir;
@@ -2729,10 +2820,10 @@ DIR defaults to current buffer's directory default.")
 #endif
 
   UNGCPRO;
-  if (NULL (val))
+  if (NILP (val))
     error ("No file name specified");
   tem = Fstring_equal (val, insdef);
-  if (!NULL (tem) && !NULL (defalt))
+  if (!NILP (tem) && !NILP (defalt))
     return defalt;
   return Fsubstitute_in_file_name (val);
 }
@@ -2774,7 +2865,7 @@ nil means use format `var'.  This variable is meaningful only on VMS.");
   defsubr (&Ssubstitute_in_file_name);
   defsubr (&Scopy_file);
   defsubr (&Smake_directory);
-  defsubr (&Sremove_directory);
+  defsubr (&Sdelete_directory);
   defsubr (&Sdelete_file);
   defsubr (&Srename_file);
   defsubr (&Sadd_name_to_file);
@@ -2794,8 +2885,11 @@ nil means use format `var'.  This variable is meaningful only on VMS.");
   defsubr (&Sfile_writable_p);
   defsubr (&Sfile_symlink_p);
   defsubr (&Sfile_directory_p);
+  defsubr (&Sfile_accessible_directory_p);
   defsubr (&Sfile_modes);
   defsubr (&Sset_file_modes);
+  defsubr (&Sset_umask);
+  defsubr (&Sumask);
   defsubr (&Sfile_newer_than_file_p);
   defsubr (&Sinsert_file_contents);
   defsubr (&Swrite_region);
@@ -2808,4 +2902,6 @@ nil means use format `var'.  This variable is meaningful only on VMS.");
 
   defsubr (&Sread_file_name_internal);
   defsubr (&Sread_file_name);
+
+  defsubr (&Sunix_sync);
 }